From ffbdaaac2b56506dd563fed8d52b4680151a64a1 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Mon, 20 Jan 2020 17:30:17 +0100 Subject: [PATCH] TLS/OpenSSL fix: If ssl_verify_server_cert or MYSQL_OPT_SSL_VERIFY_SERVER_CERT option was set without setting a local ca file, the server certificate will be checked using the system ca store. This might lead to an error, in case the server certificate was self signed. In this case, the preferred way is to specify a local CA. --- libmariadb/secure/openssl.c | 5 +++-- unittest/libmariadb/ssl.c.in | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/libmariadb/secure/openssl.c b/libmariadb/secure/openssl.c index ac982698..95c23bcb 100644 --- a/libmariadb/secure/openssl.c +++ b/libmariadb/secure/openssl.c @@ -530,8 +530,9 @@ static int ma_tls_set_certs(MYSQL *mysql, SSL *ssl) X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } } - SSL_CTX_set_verify(ctx, (mysql->options.ssl_ca || mysql->options.ssl_capath)? - SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); + SSL_CTX_set_verify(ctx, (mysql->options.ssl_ca || mysql->options.ssl_capath) || + (mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) ? + SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); return 0; error: diff --git a/unittest/libmariadb/ssl.c.in b/unittest/libmariadb/ssl.c.in index 7344bb1b..4124c366 100644 --- a/unittest/libmariadb/ssl.c.in +++ b/unittest/libmariadb/ssl.c.in @@ -1329,8 +1329,41 @@ static int test_conc386(MYSQL *mysql) return OK; } +#ifdef HAVE_OPENSSL +static int test_ssl_verify(MYSQL *my __attribute__((unused))) +{ + MYSQL *mysql; + my_bool verify= 1, enforce= 1; + + if (check_skip_ssl()) + return SKIP; + + /* verify, using system ca should fail with self signed certificate */ + mysql= mysql_init(NULL); + mysql_options(mysql, MYSQL_OPT_SSL_ENFORCE, &enforce); + mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &verify); + FAIL_IF(mysql_real_connect(mysql, hostname, username, password, schema, + port, socketname, 0), "Error expected"); + diag("error expected: %s\n", mysql_error(mysql)); + mysql_close(mysql); + + /* verify against local ca, this should pass */ + mysql= mysql_init(NULL); + mysql_ssl_set(mysql,0, 0, sslca, 0, 0); + mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &verify); + FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema, + port, socketname, 0), mysql_error(mysql)); + mysql_close(mysql); + + return OK; +} +#endif + struct my_tests_st my_tests[] = { {"test_ssl", test_ssl, TEST_CONNECTION_NEW, 0, NULL, NULL}, +#ifdef HAVE_OPENSSL + {"test_ssl_verify", test_ssl_verify, TEST_CONNECTION_NEW, 0, NULL, NULL}, +#endif {"test_mdev14101", test_mdev14101, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_mdev14027", test_mdev14027, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_conc286", test_conc286, TEST_CONNECTION_NEW, 0, NULL, NULL},