@@ -102,7 +102,7 @@ static void git_openssl_free(void *mem)
102
102
# endif /* !GIT_OPENSSL_LEGACY && !GIT_OPENSSL_DYNAMIC */
103
103
#endif /* VALGRIND */
104
104
105
- int git_openssl_stream_global_init (void )
105
+ static int openssl_init (void )
106
106
{
107
107
long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 ;
108
108
const char * ciphers = git_libgit2__ssl_ciphers ();
@@ -115,11 +115,6 @@ int git_openssl_stream_global_init(void)
115
115
ssl_opts |= SSL_OP_NO_COMPRESSION ;
116
116
#endif
117
117
118
- #ifdef GIT_OPENSSL_DYNAMIC
119
- if (git_openssl_stream_dynamic_init () < 0 )
120
- return -1 ;
121
- #endif
122
-
123
118
#ifdef VALGRIND
124
119
/*
125
120
* Swap in our own allocator functions that initialize
@@ -171,6 +166,49 @@ int git_openssl_stream_global_init(void)
171
166
return -1 ;
172
167
}
173
168
169
+ /*
170
+ * When we use dynamic loading, we defer OpenSSL initialization until
171
+ * it's first used. `openssl_ensure_initialized` will do the work
172
+ * under a mutex.
173
+ */
174
+ git_mutex openssl_mutex ;
175
+ bool openssl_initialized ;
176
+
177
+ int git_openssl_stream_global_init (void )
178
+ {
179
+ #ifndef GIT_OPENSSL_DYNAMIC
180
+ return openssl_init ();
181
+ #else
182
+ if (git_mutex_init (& openssl_mutex ) != 0 )
183
+ return -1 ;
184
+
185
+ return 0 ;
186
+ #endif
187
+ }
188
+
189
+ static int openssl_ensure_initialized (void )
190
+ {
191
+ #ifdef GIT_OPENSSL_DYNAMIC
192
+ int error = 0 ;
193
+
194
+ if (git_mutex_lock (& openssl_mutex ) != 0 )
195
+ return -1 ;
196
+
197
+ if (!openssl_initialized ) {
198
+ if ((error = git_openssl_stream_dynamic_init ()) == 0 )
199
+ error = openssl_init ();
200
+
201
+ openssl_initialized = true;
202
+ }
203
+
204
+ error |= git_mutex_unlock (& openssl_mutex );
205
+ return error ;
206
+
207
+ #else
208
+ return 0 ;
209
+ #endif
210
+ }
211
+
174
212
#if !defined(GIT_OPENSSL_LEGACY ) && !defined(GIT_OPENSSL_DYNAMIC )
175
213
int git_openssl_set_locking (void )
176
214
{
@@ -644,6 +682,9 @@ static int openssl_stream_wrap(
644
682
645
683
int git_openssl_stream_wrap (git_stream * * out , git_stream * in , const char * host )
646
684
{
685
+ if (openssl_ensure_initialized () < 0 )
686
+ return -1 ;
687
+
647
688
return openssl_stream_wrap (out , in , host , 0 );
648
689
}
649
690
@@ -656,6 +697,9 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
656
697
GIT_ASSERT_ARG (host );
657
698
GIT_ASSERT_ARG (port );
658
699
700
+ if (openssl_ensure_initialized () < 0 )
701
+ return -1 ;
702
+
659
703
if ((error = git_socket_stream_new (& stream , host , port )) < 0 )
660
704
return error ;
661
705
@@ -669,6 +713,9 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
669
713
670
714
int git_openssl__set_cert_location (const char * file , const char * path )
671
715
{
716
+ if (openssl_ensure_initialized () < 0 )
717
+ return -1 ;
718
+
672
719
if (SSL_CTX_load_verify_locations (git__ssl_ctx , file , path ) == 0 ) {
673
720
char errmsg [256 ];
674
721
0 commit comments