@@ -102,7 +102,7 @@ static void git_openssl_free(void *mem)
102102# endif /* !GIT_OPENSSL_LEGACY && !GIT_OPENSSL_DYNAMIC */
103103#endif /* VALGRIND */
104104
105- int git_openssl_stream_global_init (void )
105+ static int openssl_init (void )
106106{
107107 long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 ;
108108 const char * ciphers = git_libgit2__ssl_ciphers ();
@@ -115,11 +115,6 @@ int git_openssl_stream_global_init(void)
115115 ssl_opts |= SSL_OP_NO_COMPRESSION ;
116116#endif
117117
118- #ifdef GIT_OPENSSL_DYNAMIC
119- if (git_openssl_stream_dynamic_init () < 0 )
120- return -1 ;
121- #endif
122-
123118#ifdef VALGRIND
124119 /*
125120 * Swap in our own allocator functions that initialize
@@ -171,6 +166,49 @@ int git_openssl_stream_global_init(void)
171166 return -1 ;
172167}
173168
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+
174212#if !defined(GIT_OPENSSL_LEGACY ) && !defined(GIT_OPENSSL_DYNAMIC )
175213int git_openssl_set_locking (void )
176214{
@@ -644,6 +682,9 @@ static int openssl_stream_wrap(
644682
645683int git_openssl_stream_wrap (git_stream * * out , git_stream * in , const char * host )
646684{
685+ if (openssl_ensure_initialized () < 0 )
686+ return -1 ;
687+
647688 return openssl_stream_wrap (out , in , host , 0 );
648689}
649690
@@ -656,6 +697,9 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
656697 GIT_ASSERT_ARG (host );
657698 GIT_ASSERT_ARG (port );
658699
700+ if (openssl_ensure_initialized () < 0 )
701+ return -1 ;
702+
659703 if ((error = git_socket_stream_new (& stream , host , port )) < 0 )
660704 return error ;
661705
@@ -669,6 +713,9 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
669713
670714int git_openssl__set_cert_location (const char * file , const char * path )
671715{
716+ if (openssl_ensure_initialized () < 0 )
717+ return -1 ;
718+
672719 if (SSL_CTX_load_verify_locations (git__ssl_ctx , file , path ) == 0 ) {
673720 char errmsg [256 ];
674721
0 commit comments