@@ -92,6 +92,12 @@ static void SSLerrfree(char *buf);
9292
9393static bool pq_init_ssl_lib = true;
9494static bool pq_init_crypto_lib = true;
95+
96+ /*
97+ * SSL_context is currently shared between threads and therefore we need to be
98+ * careful to lock around any usage of it when providing thread safety.
99+ * ssl_config_mutex is the mutex that we use to protect it.
100+ */
95101static SSL_CTX * SSL_context = NULL ;
96102
97103#ifdef ENABLE_THREAD_SAFETY
@@ -253,6 +259,10 @@ pqsecure_open_client(PGconn *conn)
253259/* We cannot use MSG_NOSIGNAL to block SIGPIPE when using SSL */
254260conn -> sigpipe_flag = false;
255261
262+ #ifdef ENABLE_THREAD_SAFETY
263+ if (pthread_mutex_lock (& ssl_config_mutex ))
264+ return -1 ;
265+ #endif
256266/* Create a connection-specific SSL object */
257267if (!(conn -> ssl = SSL_new (SSL_context ))||
258268!SSL_set_app_data (conn -> ssl ,conn )||
@@ -265,9 +275,14 @@ pqsecure_open_client(PGconn *conn)
265275err );
266276SSLerrfree (err );
267277close_SSL (conn );
278+ #ifdef ENABLE_THREAD_SAFETY
279+ pthread_mutex_unlock (& ssl_config_mutex );
280+ #endif
268281return PGRES_POLLING_FAILED ;
269282}
270-
283+ #ifdef ENABLE_THREAD_SAFETY
284+ pthread_mutex_unlock (& ssl_config_mutex );
285+ #endif
271286/*
272287 * Load client certificate, private key, and trusted CA certs.
273288 */
@@ -999,8 +1014,9 @@ destroy_ssl_system(void)
9991014CRYPTO_set_id_callback (NULL );
10001015
10011016/*
1002- * We don't free the lock array. If we get another connection in this
1003- * process, we will just re-use it with the existing mutexes.
1017+ * We don't free the lock array or the SSL_context. If we get another
1018+ * connection in this process, we will just re-use them with the
1019+ * existing mutexes.
10041020 *
10051021 * This means we leak a little memory on repeated load/unload of the
10061022 * library.
@@ -1089,7 +1105,15 @@ initialize_SSL(PGconn *conn)
10891105 * understands which subject cert to present, in case different
10901106 * sslcert settings are used for different connections in the same
10911107 * process.
1108+ *
1109+ * NOTE: This function may also modify our SSL_context and therefore
1110+ * we have to lock around this call and any places where we use the
1111+ * SSL_context struct.
10921112 */
1113+ #ifdef ENABLE_THREAD_SAFETY
1114+ if (pthread_mutex_lock (& ssl_config_mutex ))
1115+ return -1 ;
1116+ #endif
10931117if (SSL_CTX_use_certificate_chain_file (SSL_context ,fnbuf )!= 1 )
10941118{
10951119char * err = SSLerrmessage ();
@@ -1098,8 +1122,13 @@ initialize_SSL(PGconn *conn)
10981122libpq_gettext ("could not read certificate file \"%s\": %s\n" ),
10991123fnbuf ,err );
11001124SSLerrfree (err );
1125+
1126+ #ifdef ENABLE_THREAD_SAFETY
1127+ pthread_mutex_unlock (& ssl_config_mutex );
1128+ #endif
11011129return -1 ;
11021130}
1131+
11031132if (SSL_use_certificate_file (conn -> ssl ,fnbuf ,SSL_FILETYPE_PEM )!= 1 )
11041133{
11051134char * err = SSLerrmessage ();
@@ -1108,10 +1137,18 @@ initialize_SSL(PGconn *conn)
11081137libpq_gettext ("could not read certificate file \"%s\": %s\n" ),
11091138fnbuf ,err );
11101139SSLerrfree (err );
1140+ #ifdef ENABLE_THREAD_SAFETY
1141+ pthread_mutex_unlock (& ssl_config_mutex );
1142+ #endif
11111143return -1 ;
11121144}
1145+
11131146/* need to load the associated private key, too */
11141147have_cert = true;
1148+
1149+ #ifdef ENABLE_THREAD_SAFETY
1150+ pthread_mutex_unlock (& ssl_config_mutex );
1151+ #endif
11151152}
11161153
11171154/*
@@ -1287,6 +1324,10 @@ initialize_SSL(PGconn *conn)
12871324{
12881325X509_STORE * cvstore ;
12891326
1327+ #ifdef ENABLE_THREAD_SAFETY
1328+ if (pthread_mutex_lock (& ssl_config_mutex ))
1329+ return -1 ;
1330+ #endif
12901331if (SSL_CTX_load_verify_locations (SSL_context ,fnbuf ,NULL )!= 1 )
12911332{
12921333char * err = SSLerrmessage ();
@@ -1295,6 +1336,9 @@ initialize_SSL(PGconn *conn)
12951336libpq_gettext ("could not read root certificate file \"%s\": %s\n" ),
12961337fnbuf ,err );
12971338SSLerrfree (err );
1339+ #ifdef ENABLE_THREAD_SAFETY
1340+ pthread_mutex_unlock (& ssl_config_mutex );
1341+ #endif
12981342return -1 ;
12991343}
13001344
@@ -1322,11 +1366,17 @@ initialize_SSL(PGconn *conn)
13221366libpq_gettext ("SSL library does not support CRL certificates (file \"%s\")\n" ),
13231367fnbuf );
13241368SSLerrfree (err );
1369+ #ifdef ENABLE_THREAD_SAFETY
1370+ pthread_mutex_unlock (& ssl_config_mutex );
1371+ #endif
13251372return -1 ;
13261373#endif
13271374}
13281375/* if not found, silently ignore; we do not require CRL */
13291376}
1377+ #ifdef ENABLE_THREAD_SAFETY
1378+ pthread_mutex_unlock (& ssl_config_mutex );
1379+ #endif
13301380
13311381SSL_set_verify (conn -> ssl ,SSL_VERIFY_PEER ,verify_cb );
13321382}