/* establish SSL connection between client and server SYNOPSIS my_ssl_connect ssl ssl object RETURN VALUES 0 success 1 error */ int my_ssl_connect(SSL *ssl) { my_bool blocking; MYSQL *mysql; DBUG_ENTER("my_ssl_connect"); DBUG_ASSERT(ssl != NULL); mysql= (MYSQL *)SSL_get_app_data(ssl); CLEAR_CLIENT_ERROR(mysql); /* Set socket to blocking if not already set */ if (!(blocking= vio_is_blocking(mysql->net.vio))) vio_blocking(mysql->net.vio, TRUE); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), mysql->options.connect_timeout); SSL_set_fd(ssl, mysql->net.vio->sd); if (SSL_connect(ssl) != 1) { my_SSL_error(mysql); /* restore blocking mode */ if (!blocking) vio_blocking(mysql->net.vio, FALSE); DBUG_RETURN(1); } vio_reset(mysql->net.vio, VIO_TYPE_SSL, mysql->net.vio->sd, 0, 0); mysql->net.vio->ssl= ssl; DBUG_RETURN(0); }
/* Initializes SSL and allocate global context SSL_context SYNOPSIS my_ssl_start mysql connection handle RETURN VALUES 0 success 1 error */ int my_ssl_start(MYSQL *mysql) { int rc= 0; DBUG_ENTER("my_ssl_start"); /* lock mutex to prevent multiple initialization */ pthread_mutex_lock(&LOCK_ssl_config); if (!my_ssl_initialized) { if (ssl_crypto_init()) goto end; SSL_library_init(); #if SSLEAY_VERSION_NUMBER >= 0x00907000L OPENSSL_config(NULL); #endif /* load errors */ SSL_load_error_strings(); /* digests and ciphers */ OpenSSL_add_all_algorithms(); if (!(SSL_context= SSL_CTX_new(TLSv1_client_method()))) { my_SSL_error(mysql); rc= 1; goto end; } my_ssl_initialized= TRUE; } end: pthread_mutex_unlock(&LOCK_ssl_config); DBUG_RETURN(rc); }
/* establish SSL connection between client and server SYNOPSIS my_ssl_connect ssl ssl object RETURN VALUES 0 success 1 error */ int my_ssl_connect(SSL *ssl) { my_bool blocking; MYSQL *mysql; long rc; my_bool try_connect= 1; DBUG_ENTER("my_ssl_connect"); DBUG_ASSERT(ssl != NULL); mysql= (MYSQL *)SSL_get_app_data(ssl); CLEAR_CLIENT_ERROR(mysql); /* Set socket to non blocking */ if (!(blocking= vio_is_blocking(mysql->net.vio))) vio_blocking(mysql->net.vio, FALSE, 0); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), mysql->options.connect_timeout); SSL_set_fd(ssl, mysql->net.vio->sd); while (try_connect && (rc= SSL_connect(ssl)) == -1) { switch(SSL_get_error(ssl, rc)) { case SSL_ERROR_WANT_READ: if (vio_wait_or_timeout(mysql->net.vio, TRUE, mysql->options.connect_timeout) < 1) try_connect= 0; break; case SSL_ERROR_WANT_WRITE: if (vio_wait_or_timeout(mysql->net.vio, TRUE, mysql->options.connect_timeout) < 1) try_connect= 0; break; default: try_connect= 0; } } if (rc != 1) { my_SSL_error(mysql); DBUG_RETURN(1); } rc= SSL_get_verify_result(ssl); if (rc != X509_V_OK) { my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(rc)); /* restore blocking mode */ if (!blocking) vio_blocking(mysql->net.vio, FALSE, 0); DBUG_RETURN(1); } vio_reset(mysql->net.vio, VIO_TYPE_SSL, mysql->net.vio->sd, 0, 0); mysql->net.vio->ssl= ssl; DBUG_RETURN(0); }
/* Initializes SSL and allocate global context SSL_context SYNOPSIS my_ssl_start mysql connection handle RETURN VALUES 0 success 1 error */ int my_ssl_start(MYSQL *mysql) { int rc= 0; DBUG_ENTER("my_ssl_start"); /* lock mutex to prevent multiple initialization */ pthread_mutex_lock(&LOCK_ssl_config); if (!my_ssl_initialized) { if (!(LOCK_crypto= (pthread_mutex_t *)my_malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks(), MYF(0)))) { rc= 1; goto end; } else { int i; for (i=0; i < CRYPTO_num_locks(); i++) pthread_mutex_init(&LOCK_crypto[i], NULL); CRYPTO_set_id_callback(my_cb_threadid); CRYPTO_set_locking_callback(my_cb_locking); } #if SSLEAY_VERSION_NUMBER >= 0x00907000L OPENSSL_config(NULL); #endif /* always returns 1, so we can discard return code */ SSL_library_init(); /* load errors */ SSL_load_error_strings(); /* digests and ciphers */ OpenSSL_add_all_algorithms(); if (!(SSL_context= SSL_CTX_new(TLSv1_client_method()))) { my_SSL_error(mysql); rc= 1; goto end; } my_ssl_initialized= TRUE; } end: pthread_mutex_unlock(&LOCK_ssl_config); DBUG_RETURN(rc); }
/* establish SSL connection between client and server SYNOPSIS my_ssl_connect ssl ssl object RETURN VALUES 0 success 1 error */ int my_ssl_connect(SSL *ssl) { my_bool blocking; MYSQL *mysql; long rc; DBUG_ENTER("my_ssl_connect"); DBUG_ASSERT(ssl != NULL); mysql= (MYSQL *)SSL_get_app_data(ssl); CLEAR_CLIENT_ERROR(mysql); /* Set socket to blocking if not already set */ if (!(blocking= vio_is_blocking(mysql->net.vio))) vio_blocking(mysql->net.vio, TRUE, 0); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), mysql->options.connect_timeout); SSL_set_fd(ssl, mysql->net.vio->sd); if (SSL_connect(ssl) != 1) { my_SSL_error(mysql); /* restore blocking mode */ if (!blocking) vio_blocking(mysql->net.vio, FALSE, 0); DBUG_RETURN(1); } rc= SSL_get_verify_result(ssl); if (rc != X509_V_OK) { my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(rc)); /* restore blocking mode */ if (!blocking) vio_blocking(mysql->net.vio, FALSE, 0); DBUG_RETURN(1); } vio_reset(mysql->net.vio, VIO_TYPE_SSL, mysql->net.vio->sd, 0, 0); mysql->net.vio->ssl= ssl; DBUG_RETURN(0); }
/* Set certification stuff. */ static int my_ssl_set_certs(SSL *ssl) { int have_cert= 0; MYSQL *mysql; DBUG_ENTER("my_ssl_set_certs"); /* Make sure that ssl was allocated and ssl_system was initialized */ DBUG_ASSERT(ssl != NULL); DBUG_ASSERT(my_ssl_initialized == TRUE); /* get connection for current ssl */ mysql= (MYSQL *)SSL_get_app_data(ssl); /* add cipher */ if ((mysql->options.ssl_cipher && mysql->options.ssl_cipher[0] != 0) && SSL_set_cipher_list(ssl, mysql->options.ssl_cipher) == 0) goto error; /* set cert */ if (mysql->options.ssl_cert && mysql->options.ssl_cert[0] != 0) { if (SSL_CTX_use_certificate_chain_file(SSL_context, mysql->options.ssl_cert) <= 0) goto error; have_cert= 1; } /* set key */ if (mysql->options.ssl_key && mysql->options.ssl_key[0]) { if (SSL_CTX_use_PrivateKey_file(SSL_context, mysql->options.ssl_key, SSL_FILETYPE_PEM) <= 0) goto error; /* verify key */ if (have_cert && SSL_CTX_check_private_key(SSL_context) != 1) goto error; } /* ca_file and ca_path */ if (SSL_CTX_load_verify_locations(SSL_context, mysql->options.ssl_ca, mysql->options.ssl_capath) == 0) { if (mysql->options.ssl_ca || mysql->options.ssl_capath) goto error; if (SSL_CTX_set_default_verify_paths(SSL_context) == 0) goto error; } if (mysql->options.extension && (mysql->options.extension->ssl_crl || mysql->options.extension->ssl_crlpath)) { X509_STORE *certstore; if ((certstore= SSL_CTX_get_cert_store(SSL_context))) { if (X509_STORE_load_locations(certstore, mysql->options.ssl_ca, mysql->options.ssl_capath) == 0 || X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL) == 0) goto error; } } DBUG_RETURN(0); error: my_SSL_error(mysql); DBUG_RETURN(1); }
/* Set certification stuff. */ static int my_ssl_set_certs(MYSQL *mysql) { char *certfile= mysql->options.ssl_cert, *keyfile= mysql->options.ssl_key; DBUG_ENTER("my_ssl_set_certs"); /* Make sure that ssl was allocated and ssl_system was initialized */ DBUG_ASSERT(my_ssl_initialized == TRUE); /* add cipher */ if ((mysql->options.ssl_cipher && mysql->options.ssl_cipher[0] != 0) && SSL_CTX_set_cipher_list(SSL_context, mysql->options.ssl_cipher) == 0) goto error; /* ca_file and ca_path */ if (SSL_CTX_load_verify_locations(SSL_context, mysql->options.ssl_ca, mysql->options.ssl_capath) == 0) { if (mysql->options.ssl_ca || mysql->options.ssl_capath) goto error; if (SSL_CTX_set_default_verify_paths(SSL_context) == 0) goto error; } if (keyfile && !certfile) certfile= keyfile; if (certfile && !keyfile) keyfile= certfile; /* set cert */ if (certfile && certfile[0] != 0) if (SSL_CTX_use_certificate_file(SSL_context, certfile, SSL_FILETYPE_PEM) != 1) goto error; /* set key */ if (keyfile && keyfile[0]) { if (SSL_CTX_use_PrivateKey_file(SSL_context, keyfile, SSL_FILETYPE_PEM) != 1) goto error; } /* verify key */ if (certfile && !SSL_CTX_check_private_key(SSL_context)) goto error; if (mysql->options.extension && (mysql->options.extension->ssl_crl || mysql->options.extension->ssl_crlpath)) { X509_STORE *certstore; if ((certstore= SSL_CTX_get_cert_store(SSL_context))) { if (X509_STORE_load_locations(certstore, mysql->options.extension->ssl_crl, mysql->options.extension->ssl_crlpath) == 0 || X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL) == 0) goto error; } } DBUG_RETURN(0); error: my_SSL_error(mysql); DBUG_RETURN(1); }