void *ma_ssl_init(MYSQL *mysql) { gnutls_session_t ssl= NULL; int ssl_error= 0; const char *err; pthread_mutex_lock(&LOCK_gnutls_config); if ((ssl_error= ma_ssl_set_certs(mysql)) < 0) goto error; if ((ssl_error = gnutls_init(&ssl, GNUTLS_CLIENT & GNUTLS_NONBLOCK)) < 0) goto error; gnutls_session_set_ptr(ssl, (void *)mysql); ssl_error= gnutls_priority_set_direct(ssl, "NORMAL:-DHE-RSA", &err); if (ssl_error < 0) goto error; if ((ssl_error= gnutls_credentials_set(ssl, GNUTLS_CRD_CERTIFICATE, GNUTLS_xcred)) < 0) goto error; pthread_mutex_unlock(&LOCK_gnutls_config); return (void *)ssl; error: ma_ssl_set_error(mysql, ssl_error); if (ssl) gnutls_deinit(ssl); pthread_mutex_unlock(&LOCK_gnutls_config); return NULL; }
my_bool ma_ssl_connect(MARIADB_SSL *cssl) { SSL *ssl = (SSL *)cssl->ssl; my_bool blocking; MYSQL *mysql; MARIADB_PVIO *pvio; int rc; mysql= (MYSQL *)SSL_get_app_data(ssl); pvio= mysql->net.pvio; /* Set socket to blocking if not already set */ if (!(blocking= pvio->methods->is_blocking(pvio))) pvio->methods->blocking(pvio, TRUE, 0); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), mysql->options.connect_timeout); SSL_set_fd(ssl, mysql_get_socket(mysql)); if (SSL_connect(ssl) != 1) { ma_ssl_set_error(mysql); /* restore blocking mode */ if (!blocking) pvio->methods->blocking(pvio, FALSE, 0); return 1; } if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT)) { 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) pvio->methods->blocking(pvio, FALSE, 0); return 1; } } pvio->cssl->ssl= cssl->ssl= (void *)ssl; return 0; }
my_bool ma_ssl_connect(MARIADB_SSL *cssl) { gnutls_session_t ssl = (gnutls_session_t)cssl->ssl; my_bool blocking; MYSQL *mysql; MARIADB_PVIO *pvio; int ret; mysql= (MYSQL *)gnutls_session_get_ptr(ssl); if (!mysql) return 1; pvio= mysql->net.pvio; /* Set socket to blocking if not already set */ if (!(blocking= pvio->methods->is_blocking(pvio))) pvio->methods->blocking(pvio, TRUE, 0); /* we don't use GnuTLS read/write functions */ gnutls_transport_set_ptr(ssl, pvio); gnutls_transport_set_push_function(ssl, ma_ssl_push); gnutls_transport_set_pull_function(ssl, ma_ssl_pull); gnutls_transport_set_pull_timeout_function(ssl, ma_ssl_pull_timeout); gnutls_handshake_set_timeout(ssl, pvio->timeout[PVIO_CONNECT_TIMEOUT]); do { ret = gnutls_handshake(ssl); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { ma_ssl_set_error(mysql, ret); /* restore blocking mode */ if (!blocking) pvio->methods->blocking(pvio, FALSE, 0); return 1; } cssl->ssl= (void *)ssl; return 0; }
static int ma_ssl_set_certs(MYSQL *mysql) { char *certfile= mysql->options.ssl_cert, *keyfile= mysql->options.ssl_key; /* 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; /* If the private key file is encrypted, we need to register a callback function * for providing password. */ if (OPT_HAS_EXT_VAL(mysql, ssl_pw)) { SSL_CTX_set_default_passwd_cb_userdata(SSL_context, (void *)mysql->options.extension->ssl_pw); SSL_CTX_set_default_passwd_cb(SSL_context, ma_ssl_get_password); } if (keyfile && keyfile[0]) { if (SSL_CTX_use_PrivateKey_file(SSL_context, keyfile, SSL_FILETYPE_PEM) != 1) goto error; } if (OPT_HAS_EXT_VAL(mysql, ssl_pw)) { SSL_CTX_set_default_passwd_cb_userdata(SSL_context, NULL); SSL_CTX_set_default_passwd_cb(SSL_context, NULL); } /* 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; } } return 0; error: ma_ssl_set_error(mysql); return 1; }