Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 6fea59e

Browse files
committed
Move EnsureOpenSslInitialized shim from coreclr to corefx
The implementation was simplified in the process by removing the dynamic loading. Whereas libcoreclr could not statically depend on libcrypto, System.Security.Cryptography.Native can and already does.
1 parent 327b90a commit 6fea59e

File tree

10 files changed

+201
-80
lines changed

10 files changed

+201
-80
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Runtime.InteropServices;
6+
using System.Security.Cryptography;
7+
8+
internal static partial class Interop
9+
{
10+
// Initialization of libcrypto threading support is done in a static constructor.
11+
// This enables a project simply to include this file, and any usage of any of
12+
// the libcrypto or System.Security.Cryptography.Native functions will trigger
13+
// initialization of the threading support.
14+
15+
// Note that we can collapse everything into Interop.Crypto once we no longer
16+
// have a mix of P/Invokes to libcrypto and System.Security.Crytpography.Native.
17+
// In the meantime, a third Interop.CryptoInitializer class is used to prevent
18+
// a circular initialization dependency between the two.
19+
20+
internal static partial class libcrypto
21+
{
22+
static libcrypto()
23+
{
24+
CryptoInitializer.Initialize();
25+
}
26+
}
27+
28+
internal static partial class Crypto
29+
{
30+
static Crypto()
31+
{
32+
CryptoInitializer.Initialize();
33+
}
34+
}
35+
36+
internal static class CryptoInitializer
37+
{
38+
static CryptoInitializer()
39+
{
40+
if (EnsureOpenSslInitialized() != 0)
41+
{
42+
// Ideally this would be a CryptographicException, but we use
43+
// OpenSSL in libraries lower than System.Security.Cryptography.
44+
// It's not a big deal, though: this will already be wrapped in a
45+
// TypeLoadException, and this failing means something is very
46+
// wrong with the system's configuration and any code using
47+
// these libraries will be unable to operate correctly.
48+
throw new InvalidOperationException();
49+
}
50+
51+
// Load the SHA-2 hash algorithms, and anything else not in the default
52+
// support set.
53+
OPENSSL_add_all_algorithms_conf();
54+
55+
// Ensure that the error message table is loaded.
56+
ERR_load_crypto_strings();
57+
}
58+
59+
internal static void Initialize()
60+
{
61+
// No-op that exists to provide a hook for other static constructors
62+
// to trigger initialization. Once we stop having direct P/Invokes
63+
// to libcrypto and everything is collapsed in to the static constructor
64+
// of Interop.Crypto, this function can be removed.
65+
}
66+
67+
[DllImport(Libraries.CryptoNative)]
68+
private static extern int EnsureOpenSslInitialized();
69+
70+
[DllImport(Libraries.LibCrypto)]
71+
private static extern void ERR_load_crypto_strings();
72+
73+
[DllImport(Libraries.LibCrypto)]
74+
private static extern void OPENSSL_add_all_algorithms_conf();
75+
}
76+
}

src/Common/src/Interop/Unix/libcoreclr/Interop.EnsureOpenSslInitialized.cs

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/Common/src/Interop/Unix/libcrypto/Interop.ERR.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ internal static partial class Interop
1010
{
1111
internal static partial class libcrypto
1212
{
13-
[DllImport(Libraries.LibCrypto)]
14-
private static extern void ERR_load_crypto_strings();
15-
1613
[DllImport(Libraries.LibCrypto)]
1714
private static extern uint ERR_get_error();
1815

src/Common/src/Interop/Unix/libcrypto/Interop.Initialization.cs

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/Native/System.Security.Cryptography.Native/openssl.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
44
//
55

6+
#include <assert.h>
7+
#include <pthread.h>
8+
#include <stdlib.h>
69
#include <string.h>
710
#include <time.h>
11+
#include <unistd.h>
812
#include <openssl/asn1.h>
913
#include <openssl/bio.h>
1014
#include <openssl/evp.h>
@@ -913,3 +917,114 @@ UpRefEvpPkey(
913917

914918
return CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
915919
}
920+
921+
// Lock used to make sure EnsureopenSslInitialized itself is thread safe
922+
static pthread_mutex_t g_initLock = PTHREAD_MUTEX_INITIALIZER;
923+
924+
// Set of locks initialized for OpenSSL
925+
static pthread_mutex_t* g_locks = NULL;
926+
927+
/*
928+
Function:
929+
LockingCallback
930+
931+
Called back by OpenSSL to lock or unlock.
932+
*/
933+
static
934+
void
935+
LockingCallback(int mode, int n, const char* file, int line)
936+
{
937+
int result;
938+
if (mode & CRYPTO_LOCK)
939+
{
940+
result = pthread_mutex_lock(&g_locks[n]);
941+
}
942+
else
943+
{
944+
result = pthread_mutex_unlock(&g_locks[n]);
945+
}
946+
947+
if (result != 0)
948+
{
949+
assert(!"LockingCallback failed.");
950+
}
951+
}
952+
953+
/*
954+
Function:
955+
EnsureOpenSslInitialized
956+
957+
Initializes OpenSSL with a locking callback to ensure thread safety.
958+
959+
Return values:
960+
0 on success
961+
non-zero on failure
962+
*/
963+
int
964+
EnsureOpenSslInitialized()
965+
{
966+
int ret = 0;
967+
int numLocks = 0;
968+
int locksInitialized = 0;
969+
970+
pthread_mutex_lock(&g_initLock);
971+
972+
if (g_locks != NULL)
973+
{
974+
// Already initialized; nothing more to do.
975+
goto done;
976+
}
977+
978+
// Determine how many locks are needed
979+
numLocks = CRYPTO_num_locks();
980+
if (numLocks <= 0)
981+
{
982+
assert(!"CRYPTO_num_locks returned invalid value.");
983+
ret = 1;
984+
goto done;
985+
}
986+
987+
// Create the locks array
988+
g_locks = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t) * numLocks);
989+
if (g_locks == NULL)
990+
{
991+
assert(!"malloc failed.");
992+
ret = 2;
993+
goto done;
994+
}
995+
996+
// Initialize each of the locks
997+
for (locksInitialized = 0; locksInitialized < numLocks; locksInitialized++)
998+
{
999+
if (pthread_mutex_init(&g_locks[locksInitialized], NULL) != 0)
1000+
{
1001+
assert(!"pthread_mutex_init failed.");
1002+
ret = 3;
1003+
goto done;
1004+
}
1005+
}
1006+
1007+
// Initialize the callback
1008+
CRYPTO_set_locking_callback(LockingCallback);
1009+
1010+
done:
1011+
if (ret != 0)
1012+
{
1013+
// Cleanup on failure
1014+
if (g_locks != NULL)
1015+
{
1016+
for (int i = locksInitialized - 1; i >= 0; i--)
1017+
{
1018+
if (pthread_mutex_destroy(&g_locks[i]) != 0)
1019+
{
1020+
assert(!"Unable to pthread_mutex_destroy while cleaning up.");
1021+
}
1022+
}
1023+
free(g_locks);
1024+
g_locks = NULL;
1025+
}
1026+
}
1027+
1028+
pthread_mutex_unlock(&g_initLock);
1029+
return ret;
1030+
}

src/System.Runtime.Extensions/src/System.Runtime.Extensions.CoreCLR.csproj

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,17 +118,11 @@
118118
<Compile Include="$(CommonPath)\Interop\Unix\libc\Interop.gnu_get_libc_version.cs">
119119
<Link>Common\Interop\Unix\libc\Interop.gnu_get_libc_version.cs</Link>
120120
</Compile>
121-
<Compile Include="$(CommonPath)\Interop\Unix\libcoreclr\Interop.EnsureOpenSslInitialized.cs">
122-
<Link>Common\Interop\Unix\libcoreclr\Interop.EnsureOpenSslInitialized.cs</Link>
123-
</Compile>
124121
<Compile Include="$(CommonPath)\Interop\Unix\libcoreclr\Interop.QueryPerformanceCounter.cs">
125122
<Link>Common\Interop\Unix\libcoreclr\Interop.QueryPerformanceCounter.cs</Link>
126123
</Compile>
127-
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.ERR.cs">
128-
<Link>Common\Interop\Unix\libcrypto\Interop.ERR.cs</Link>
129-
</Compile>
130-
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.Initialization.cs">
131-
<Link>Common\Interop\Unix\libcrypto\Interop.Initialization.cs</Link>
124+
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs">
125+
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs</Link>
132126
</Compile>
133127
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.RAND.cs">
134128
<Link>Common\Interop\Unix\libcrypto\Interop.RAND.cs</Link>

src/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,6 @@
125125
<Compile Include="$(CommonPath)\Interop\Unix\Interop.Libraries.cs">
126126
<Link>Common\Interop\Unix\Interop.Libraries.cs</Link>
127127
</Compile>
128-
<Compile Include="$(CommonPath)\Interop\Unix\libcoreclr\Interop.EnsureOpenSslInitialized.cs">
129-
<Link>Common\Interop\Unix\libcoreclr\Interop.EnsureOpenSslInitialized.cs</Link>
130-
</Compile>
131128
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.ERR.cs">
132129
<Link>Common\Interop\Unix\libcrypto\Interop.ERR.cs</Link>
133130
</Compile>
@@ -137,8 +134,8 @@
137134
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.EVP.Cipher.cs">
138135
<Link>Common\Interop\Unix\libcrypto\Interop.EVP.Cipher.cs</Link>
139136
</Compile>
140-
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.Initialization.cs">
141-
<Link>Common\Interop\Unix\libcrypto\Interop.Initialization.cs</Link>
137+
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs">
138+
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs</Link>
142139
</Compile>
143140
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.RAND.cs">
144141
<Link>Common\Interop\Unix\libcrypto\Interop.RAND.cs</Link>

src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@
5656
<Compile Include="$(CommonPath)\Interop\Unix\Interop.Libraries.cs">
5757
<Link>Common\Interop\Unix\Interop.Libraries.cs</Link>
5858
</Compile>
59-
<Compile Include="$(CommonPath)\Interop\Unix\libcoreclr\Interop.EnsureOpenSslInitialized.cs">
60-
<Link>Common\Interop\Unix\libcoreclr\Interop.EnsureOpenSslInitialized.cs</Link>
61-
</Compile>
6259
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.ASN1.cs">
6360
<Link>Common\Interop\Unix\libcrypto\Interop.ASN1.cs</Link>
6461
</Compile>
@@ -68,8 +65,8 @@
6865
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.ERR.cs">
6966
<Link>Common\Interop\Unix\libcrypto\Interop.ERR.cs</Link>
7067
</Compile>
71-
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.Initialization.cs">
72-
<Link>Common\Interop\Unix\libcrypto\Interop.Initialization.cs</Link>
68+
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs">
69+
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs</Link>
7370
</Compile>
7471
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.X509Ext.cs">
7572
<Link>Common\Interop\Unix\libcrypto\Interop.X509Ext.cs</Link>

src/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.ASN1.cs">
4040
<Link>Common\Interop\Unix\libcrypto\Interop.ASN1.cs</Link>
4141
</Compile>
42-
<Compile Include="$(CommonPath)\Interop\Unix\libcoreclr\Interop.EnsureOpenSslInitialized.cs">
43-
<Link>Common\Interop\Unix\libcoreclr\Interop.EnsureOpenSslInitialized.cs</Link>
42+
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs">
43+
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs"</Link>
4444
</Compile>
4545
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.ERR.cs">
4646
<Link>Common\Interop\Unix\libcrypto\Interop.ERR.cs</Link>

src/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,6 @@
156156
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.d2i.cs">
157157
<Link>Common\Interop\Unix\libcrypto\Interop.d2i.cs</Link>
158158
</Compile>
159-
<Compile Include="$(CommonPath)\Interop\Unix\libcoreclr\Interop.EnsureOpenSslInitialized.cs">
160-
<Link>Common\Interop\Unix\libcoreclr\Interop.EnsureOpenSslInitialized.cs</Link>
161-
</Compile>
162159
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.ERR.cs">
163160
<Link>Common\Interop\Unix\libcrypto\Interop.ERR.cs</Link>
164161
</Compile>
@@ -168,8 +165,8 @@
168165
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.EvpPkey.Rsa.cs">
169166
<Link>Common\Interop\Unix\libcrypto\Interop.EvpPkey.Rsa.cs</Link>
170167
</Compile>
171-
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.Initialization.cs">
172-
<Link>Common\Interop\Unix\libcrypto\Interop.Initialization.cs</Link>
168+
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs">
169+
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs</Link>
173170
</Compile>
174171
<Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.Pkcs12.cs">
175172
<Link>Common\Interop\Unix\libcrypto\Interop.Pkcs12.cs</Link>

0 commit comments

Comments
 (0)