@@ -93,6 +93,12 @@ static void SSLerrfree(char *buf);
9393
9494static bool pq_init_ssl_lib = true;
9595static bool pq_init_crypto_lib = true;
96+
97+ /*
98+ * SSL_context is currently shared between threads and therefore we need to be
99+ * careful to lock around any usage of it when providing thread safety.
100+ * ssl_config_mutex is the mutex that we use to protect it.
101+ */
96102static SSL_CTX * SSL_context = NULL ;
97103
98104#ifdef ENABLE_THREAD_SAFETY
@@ -254,6 +260,10 @@ pqsecure_open_client(PGconn *conn)
254260/* We cannot use MSG_NOSIGNAL to block SIGPIPE when using SSL */
255261conn -> sigpipe_flag = false;
256262
263+ #ifdef ENABLE_THREAD_SAFETY
264+ if (pthread_mutex_lock (& ssl_config_mutex ))
265+ return -1 ;
266+ #endif
257267/* Create a connection-specific SSL object */
258268if (!(conn -> ssl = SSL_new (SSL_context ))||
259269!SSL_set_app_data (conn -> ssl ,conn )||
@@ -266,9 +276,14 @@ pqsecure_open_client(PGconn *conn)
266276err );
267277SSLerrfree (err );
268278close_SSL (conn );
279+ #ifdef ENABLE_THREAD_SAFETY
280+ pthread_mutex_unlock (& ssl_config_mutex );
281+ #endif
269282return PGRES_POLLING_FAILED ;
270283}
271-
284+ #ifdef ENABLE_THREAD_SAFETY
285+ pthread_mutex_unlock (& ssl_config_mutex );
286+ #endif
272287/*
273288 * Load client certificate, private key, and trusted CA certs.
274289 */
@@ -1000,8 +1015,9 @@ destroy_ssl_system(void)
10001015CRYPTO_set_id_callback (NULL );
10011016
10021017/*
1003- * We don't free the lock array. If we get another connection in this
1004- * process, we will just re-use it with the existing mutexes.
1018+ * We don't free the lock array or the SSL_context. If we get another
1019+ * connection in this process, we will just re-use them with the
1020+ * existing mutexes.
10051021 *
10061022 * This means we leak a little memory on repeated load/unload of the
10071023 * library.
@@ -1090,7 +1106,15 @@ initialize_SSL(PGconn *conn)
10901106 * understands which subject cert to present, in case different
10911107 * sslcert settings are used for different connections in the same
10921108 * process.
1109+ *
1110+ * NOTE: This function may also modify our SSL_context and therefore
1111+ * we have to lock around this call and any places where we use the
1112+ * SSL_context struct.
10931113 */
1114+ #ifdef ENABLE_THREAD_SAFETY
1115+ if (pthread_mutex_lock (& ssl_config_mutex ))
1116+ return -1 ;
1117+ #endif
10941118if (SSL_CTX_use_certificate_chain_file (SSL_context ,fnbuf )!= 1 )
10951119{
10961120char * err = SSLerrmessage ();
@@ -1099,8 +1123,13 @@ initialize_SSL(PGconn *conn)
10991123libpq_gettext ("could not read certificate file \"%s\": %s\n" ),
11001124fnbuf ,err );
11011125SSLerrfree (err );
1126+
1127+ #ifdef ENABLE_THREAD_SAFETY
1128+ pthread_mutex_unlock (& ssl_config_mutex );
1129+ #endif
11021130return -1 ;
11031131}
1132+
11041133if (SSL_use_certificate_file (conn -> ssl ,fnbuf ,SSL_FILETYPE_PEM )!= 1 )
11051134{
11061135char * err = SSLerrmessage ();
@@ -1109,10 +1138,18 @@ initialize_SSL(PGconn *conn)
11091138libpq_gettext ("could not read certificate file \"%s\": %s\n" ),
11101139fnbuf ,err );
11111140SSLerrfree (err );
1141+ #ifdef ENABLE_THREAD_SAFETY
1142+ pthread_mutex_unlock (& ssl_config_mutex );
1143+ #endif
11121144return -1 ;
11131145}
1146+
11141147/* need to load the associated private key, too */
11151148have_cert = true;
1149+
1150+ #ifdef ENABLE_THREAD_SAFETY
1151+ pthread_mutex_unlock (& ssl_config_mutex );
1152+ #endif
11161153}
11171154
11181155/*
@@ -1288,6 +1325,10 @@ initialize_SSL(PGconn *conn)
12881325{
12891326X509_STORE * cvstore ;
12901327
1328+ #ifdef ENABLE_THREAD_SAFETY
1329+ if (pthread_mutex_lock (& ssl_config_mutex ))
1330+ return -1 ;
1331+ #endif
12911332if (SSL_CTX_load_verify_locations (SSL_context ,fnbuf ,NULL )!= 1 )
12921333{
12931334char * err = SSLerrmessage ();
@@ -1296,6 +1337,9 @@ initialize_SSL(PGconn *conn)
12961337libpq_gettext ("could not read root certificate file \"%s\": %s\n" ),
12971338fnbuf ,err );
12981339SSLerrfree (err );
1340+ #ifdef ENABLE_THREAD_SAFETY
1341+ pthread_mutex_unlock (& ssl_config_mutex );
1342+ #endif
12991343return -1 ;
13001344}
13011345
@@ -1323,11 +1367,17 @@ initialize_SSL(PGconn *conn)
13231367libpq_gettext ("SSL library does not support CRL certificates (file \"%s\")\n" ),
13241368fnbuf );
13251369SSLerrfree (err );
1370+ #ifdef ENABLE_THREAD_SAFETY
1371+ pthread_mutex_unlock (& ssl_config_mutex );
1372+ #endif
13261373return -1 ;
13271374#endif
13281375}
13291376/* if not found, silently ignore; we do not require CRL */
13301377}
1378+ #ifdef ENABLE_THREAD_SAFETY
1379+ pthread_mutex_unlock (& ssl_config_mutex );
1380+ #endif
13311381
13321382SSL_set_verify (conn -> ssl ,SSL_VERIFY_PEER ,verify_cb );
13331383}