@@ -32,9 +32,9 @@ static SSL_CTX *SSL_context= NULL;
3232#define MAX_SSL_ERR_LEN 100
3333
3434extern pthread_mutex_t LOCK_ssl_config ;
35- static pthread_mutex_t * LOCK_crypto ;
35+ static pthread_mutex_t * LOCK_crypto = NULL ;
3636
37- /*
37+ /*
3838 SSL error handling
3939*/
4040static void my_SSL_error (MYSQL * mysql )
@@ -70,21 +70,41 @@ static void my_SSL_error(MYSQL *mysql)
7070 Crypto call back functions will be
7171 set during ssl_initialization
7272 */
73- static unsigned long my_cb_threadid (void )
73+ static void my_cb_threadid (CRYPTO_THREADID * id )
7474{
75- /* cast pthread_t to unsigned long */
76- return (unsigned long ) pthread_self ();
75+ CRYPTO_THREADID_set_numeric (id , (unsigned long )pthread_self ());
7776}
7877
79- static void
80- my_cb_locking (int mode , int n , const char * file , int line )
78+ static void my_cb_locking (int mode , int n , const char * file , int line )
8179{
82- if (mode & CRYPTO_LOCK )
83- pthread_mutex_lock (& LOCK_crypto [n ]);
84- else
85- pthread_mutex_unlock (& LOCK_crypto [n ]);
80+ if (mode & CRYPTO_LOCK )
81+ pthread_mutex_lock (& LOCK_crypto [n ]);
82+ else
83+ pthread_mutex_unlock (& LOCK_crypto [n ]);
84+ }
85+
86+
87+ static int ssl_thread_init ()
88+ {
89+ int i , max = CRYPTO_num_locks ();
90+
91+ if (LOCK_crypto == NULL )
92+ {
93+ if (!(LOCK_crypto =
94+ (pthread_mutex_t * )my_malloc (sizeof (pthread_mutex_t ) * max , MYF (0 ))))
95+ return 1 ;
96+
97+ for (i = 0 ; i < max ; i ++ )
98+ pthread_mutex_init (& LOCK_crypto [i ], NULL );
99+ }
100+
101+ CRYPTO_THREADID_set_callback (my_cb_threadid );
102+ CRYPTO_set_locking_callback (my_cb_locking );
103+
104+ return 0 ;
86105}
87106
107+
88108/*
89109 Initializes SSL and allocate global
90110 context SSL_context
@@ -103,30 +123,15 @@ int my_ssl_start(MYSQL *mysql)
103123 DBUG_ENTER ("my_ssl_start" );
104124 /* lock mutex to prevent multiple initialization */
105125 pthread_mutex_lock (& LOCK_ssl_config );
106-
107126 if (!my_ssl_initialized )
108127 {
109- if (!(LOCK_crypto =
110- (pthread_mutex_t * )my_malloc (sizeof (pthread_mutex_t ) *
111- CRYPTO_num_locks (), MYF (0 ))))
112- {
113- rc = 1 ;
128+ if (ssl_thread_init ())
114129 goto end ;
115- } else
116- {
117- int i ;
130+ SSL_library_init ();
118131
119- for (i = 0 ; i < CRYPTO_num_locks (); i ++ )
120- pthread_mutex_init (& LOCK_crypto [i ], NULL );
121- CRYPTO_set_id_callback (my_cb_threadid );
122- CRYPTO_set_locking_callback (my_cb_locking );
123- }
124132#if SSLEAY_VERSION_NUMBER >= 0x00907000L
125133 OPENSSL_config (NULL );
126134#endif
127-
128- /* always returns 1, so we can discard return code */
129- SSL_library_init ();
130135 /* load errors */
131136 SSL_load_error_strings ();
132137 /* digests and ciphers */
@@ -165,12 +170,14 @@ void my_ssl_end()
165170 {
166171 int i ;
167172 CRYPTO_set_locking_callback (NULL );
168- CRYPTO_set_id_callback (NULL );
173+ CRYPTO_set_id_callback (NULL );
169174
170175 for (i = 0 ; i < CRYPTO_num_locks (); i ++ )
171176 pthread_mutex_destroy (& LOCK_crypto [i ]);
172177
173178 my_free ((gptr )LOCK_crypto , MYF (0 ));
179+ LOCK_crypto = NULL ;
180+
174181 if (SSL_context )
175182 {
176183 SSL_CTX_free (SSL_context );
@@ -196,7 +203,9 @@ void my_ssl_end()
196203*/
197204static int my_ssl_set_certs (MYSQL * mysql )
198205{
199- char * key_file = mysql -> options .ssl_key ? mysql -> options .ssl_key : mysql -> options .ssl_cert ;
206+ char * certfile = mysql -> options .ssl_cert ,
207+ * keyfile = mysql -> options .ssl_key ;
208+
200209 DBUG_ENTER ("my_ssl_set_certs" );
201210
202211 /* Make sure that ssl was allocated and
@@ -220,21 +229,26 @@ static int my_ssl_set_certs(MYSQL *mysql)
220229 goto error ;
221230 }
222231
232+ if (keyfile && !certfile )
233+ certfile = keyfile ;
234+ if (certfile && !keyfile )
235+ keyfile = certfile ;
236+
223237 /* set cert */
224- if (mysql -> options . ssl_cert && mysql -> options . ssl_cert [0 ] != 0 )
225- if (SSL_CTX_use_certificate_chain_file (SSL_context , mysql -> options . ssl_cert ) <= 0 )
238+ if (certfile && certfile [0 ] != 0 )
239+ if (SSL_CTX_use_certificate_file (SSL_context , certfile , SSL_FILETYPE_PEM ) != 1 )
226240 goto error ;
227241
228- /* set key */
229- if (key_file )
242+ /* set key */
243+ if (keyfile && keyfile [ 0 ] )
230244 {
231- if (SSL_CTX_use_PrivateKey_file (SSL_context , key_file , SSL_FILETYPE_PEM ) <= 0 )
232- goto error ;
233-
234- /* verify key */
235- if (!SSL_CTX_check_private_key (SSL_context ))
245+ if (SSL_CTX_use_PrivateKey_file (SSL_context , keyfile , SSL_FILETYPE_PEM ) != 1 )
236246 goto error ;
237247 }
248+ /* verify key */
249+ if (certfile && !SSL_CTX_check_private_key (SSL_context ))
250+ goto error ;
251+
238252 if (mysql -> options .extension &&
239253 (mysql -> options .extension -> ssl_crl || mysql -> options .extension -> ssl_crlpath ))
240254 {
@@ -318,6 +332,7 @@ SSL *my_ssl_init(MYSQL *mysql)
318332 if (!my_ssl_initialized )
319333 my_ssl_start (mysql );
320334
335+ pthread_mutex_lock (& LOCK_ssl_config );
321336 if (my_ssl_set_certs (mysql ))
322337 goto error ;
323338
@@ -333,8 +348,10 @@ SSL *my_ssl_init(MYSQL *mysql)
333348 SSL_CTX_set_verify (SSL_context , verify , my_verify_callback );
334349 SSL_CTX_set_verify_depth (SSL_context , 1 );
335350
351+ pthread_mutex_unlock (& LOCK_ssl_config );
336352 DBUG_RETURN (ssl );
337353error :
354+ pthread_mutex_unlock (& LOCK_ssl_config );
338355 if (ssl )
339356 SSL_free (ssl );
340357 DBUG_RETURN (NULL );
@@ -503,7 +520,10 @@ int my_ssl_close(Vio *vio)
503520 int i , rc ;
504521 DBUG_ENTER ("my_ssl_close" );
505522
506-
523+ if (!vio || !vio -> ssl )
524+ DBUG_RETURN (1 );
525+
526+ SSL_set_quiet_shutdown (vio -> ssl , 1 );
507527 /* 2 x pending + 2 * data = 4 */
508528 for (i = 0 ; i < 4 ; i ++ )
509529 if ((rc = SSL_shutdown (vio -> ssl )))
0 commit comments