From 8260fe53e6ce964bcaf4f9acdd1dcfce0cf15902 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Mon, 25 Jul 2022 13:52:43 +0200 Subject: [PATCH 1/5] Backport of CONC-503: OpenSSL 3.0 support for Connector/C 3.1. Backported from 3.3 --- plugins/auth/caching_sha2_pw.c | 40 ++++++++++++++++++++++++++-------- plugins/auth/sha256_pw.c | 34 ++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/plugins/auth/caching_sha2_pw.c b/plugins/auth/caching_sha2_pw.c index 4bd45e84..4e1af7d7 100644 --- a/plugins/auth/caching_sha2_pw.c +++ b/plugins/auth/caching_sha2_pw.c @@ -241,10 +241,11 @@ static int auth_caching_sha2_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) int rc= CR_ERROR; #if !defined(HAVE_GNUTLS) char passwd[MAX_PW_LEN]; - unsigned char rsa_enc_pw[MAX_PW_LEN]; #ifdef HAVE_OPENSSL - int rsa_size; + unsigned char *rsa_enc_pw= NULL; + size_t rsa_size; #else + unsigned char rsa_enc_pw[MAX_PW_LEN]; ULONG rsa_size; #endif unsigned int pwlen, i; @@ -253,8 +254,10 @@ static int auth_caching_sha2_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) unsigned char buf[MA_SHA256_HASH_SIZE]; #if defined(HAVE_OPENSSL) - RSA *pubkey= NULL; + EVP_PKEY *pubkey= NULL; + EVP_PKEY_CTX *ctx= NULL; BIO *bio; + size_t outlen; #elif defined(HAVE_WINCRYPT) BCRYPT_KEY_HANDLE pubkey= 0; BCRYPT_OAEP_PADDING_INFO paddingInfo; @@ -337,10 +340,19 @@ static int auth_caching_sha2_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) #if defined(HAVE_OPENSSL) bio= BIO_new_mem_buf(filebuffer ? (unsigned char *)filebuffer : packet, packet_length); - if ((pubkey= PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL))) - rsa_size= RSA_size(pubkey); - BIO_free(bio); - ERR_clear_error(); + if ((pubkey= PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL))) + { + if (!(ctx= EVP_PKEY_CTX_new(pubkey, NULL))) + goto error; + if (EVP_PKEY_encrypt_init(ctx) <= 0) + goto error; + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) + goto error; + rsa_size= EVP_PKEY_size(pubkey); + } + BIO_free(bio); + bio= NULL; + ERR_clear_error(); #elif defined(HAVE_WINCRYPT) der_buffer_len= packet_length; /* Load pem and convert it to binary object. New length will be returned @@ -377,7 +389,11 @@ static int auth_caching_sha2_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) /* encrypt scrambled password */ #if defined(HAVE_OPENSSL) - if (RSA_public_encrypt(pwlen, (unsigned char *)passwd, rsa_enc_pw, pubkey, RSA_PKCS1_OAEP_PADDING) < 0) + if (EVP_PKEY_encrypt(ctx, NULL, &outlen, (unsigned char *)passwd, pwlen) <= 0) + goto error; + if (!(rsa_enc_pw= malloc(outlen))) + goto error; + if (EVP_PKEY_encrypt(ctx, rsa_enc_pw, &outlen, (unsigned char *)passwd, pwlen) <= 0) goto error; #elif defined(HAVE_WINCRYPT) ZeroMemory(&paddingInfo, sizeof(paddingInfo)); @@ -403,7 +419,13 @@ static int auth_caching_sha2_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) error: #if defined(HAVE_OPENSSL) if (pubkey) - RSA_free(pubkey); + EVP_PKEY_free(pubkey); + if (rsa_enc_pw) + free(rsa_enc_pw); + if (bio) + BIO_free(bio); + if (ctx) + EVP_PKEY_CTX_free(ctx); #elif defined(HAVE_WINCRYPT) if (pubkey) BCryptDestroyKey(pubkey); diff --git a/plugins/auth/sha256_pw.c b/plugins/auth/sha256_pw.c index 3e22fb5c..fbe5a2bd 100644 --- a/plugins/auth/sha256_pw.c +++ b/plugins/auth/sha256_pw.c @@ -164,14 +164,17 @@ static int auth_sha256_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) int packet_length; int rc= CR_ERROR; char passwd[MAX_PW_LEN]; - unsigned char rsa_enc_pw[MAX_PW_LEN]; unsigned int rsa_size; unsigned int pwlen, i; #if defined(HAVE_OPENSSL) - RSA *pubkey= NULL; + EVP_PKEY *pubkey= NULL; + EVP_PKEY_CTX *ctx= NULL; + size_t outlen= 0; + unsigned char *rsa_enc_pw= NULL; BIO *bio; #elif defined(HAVE_WINCRYPT) + unsigned char rsa_enc_pw[MAX_PW_LEN]; HCRYPTKEY pubkey= 0; HCRYPTPROV hProv= 0; LPBYTE der_buffer= NULL; @@ -229,9 +232,18 @@ static int auth_sha256_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) #if defined(HAVE_OPENSSL) bio= BIO_new_mem_buf(filebuffer ? (unsigned char *)filebuffer : packet, packet_length); - if ((pubkey= PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL))) - rsa_size= RSA_size(pubkey); + if ((pubkey= PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL))) + { + if (!(ctx= EVP_PKEY_CTX_new(pubkey, NULL))) + goto error; + if (EVP_PKEY_encrypt_init(ctx) <= 0) + goto error; + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) + goto error; + rsa_size= EVP_PKEY_size(pubkey); + } BIO_free(bio); + bio= NULL; ERR_clear_error(); #elif defined(HAVE_WINCRYPT) der_buffer_len= packet_length; @@ -273,7 +285,11 @@ static int auth_sha256_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) /* encrypt scrambled password */ #if defined(HAVE_OPENSSL) - if (RSA_public_encrypt(pwlen, (unsigned char *)passwd, rsa_enc_pw, pubkey, RSA_PKCS1_OAEP_PADDING) < 0) + if (EVP_PKEY_encrypt(ctx, NULL, &outlen, (unsigned char *)passwd, pwlen) <= 0) + goto error; + if (!(rsa_enc_pw= malloc(outlen))) + goto error; + if (EVP_PKEY_encrypt(ctx, rsa_enc_pw, &outlen, (unsigned char *)passwd, pwlen) <= 0) goto error; #elif defined(HAVE_WINCRYPT) if (!CryptEncrypt(pubkey, 0, TRUE, CRYPT_OAEP, (BYTE *)passwd, (DWORD *)&pwlen, MAX_PW_LEN)) @@ -293,7 +309,13 @@ static int auth_sha256_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) error: #if defined(HAVE_OPENSSL) if (pubkey) - RSA_free(pubkey); + EVP_PKEY_free(pubkey); + if (bio) + BIO_free(bio); + if (ctx) + EVP_PKEY_CTX_free(ctx); + if (rsa_enc_pw) + free(rsa_enc_pw); #elif defined(HAVE_WINCRYPT) CryptReleaseContext(hProv, 0); if (publicKeyInfo) From 788535f217993e022ca55a05f9526855e0072bdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 25 Jul 2022 15:45:36 +0300 Subject: [PATCH 2/5] Fix GCC -Og -Wmaybe-uninitialized --- plugins/auth/caching_sha2_pw.c | 4 ++-- plugins/auth/sha256_pw.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/auth/caching_sha2_pw.c b/plugins/auth/caching_sha2_pw.c index 4e1af7d7..651943eb 100644 --- a/plugins/auth/caching_sha2_pw.c +++ b/plugins/auth/caching_sha2_pw.c @@ -1,5 +1,5 @@ /************************************************************************************ - Copyright (C) 2017 MariaDB Corporation AB + Copyright (C) 2017, 2022, MariaDB Corporation AB This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -243,7 +243,7 @@ static int auth_caching_sha2_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) char passwd[MAX_PW_LEN]; #ifdef HAVE_OPENSSL unsigned char *rsa_enc_pw= NULL; - size_t rsa_size; + size_t rsa_size= 0; #else unsigned char rsa_enc_pw[MAX_PW_LEN]; ULONG rsa_size; diff --git a/plugins/auth/sha256_pw.c b/plugins/auth/sha256_pw.c index fbe5a2bd..79a59753 100644 --- a/plugins/auth/sha256_pw.c +++ b/plugins/auth/sha256_pw.c @@ -1,5 +1,5 @@ /************************************************************************************ - Copyright (C) 2017 MariaDB Corporation AB + Copyright (C) 2017, 2022, MariaDB Corporation AB This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -164,7 +164,7 @@ static int auth_sha256_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) int packet_length; int rc= CR_ERROR; char passwd[MAX_PW_LEN]; - unsigned int rsa_size; + unsigned int rsa_size= 0; unsigned int pwlen, i; #if defined(HAVE_OPENSSL) From b9811b7c6d48cf57b64bb5bc0d34522f3730037e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 26 Jul 2022 08:16:53 +0300 Subject: [PATCH 3/5] Fix clang -Wunused-but-set-variable --- unittest/libmariadb/cursor.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/unittest/libmariadb/cursor.c b/unittest/libmariadb/cursor.c index 332202dc..be908ad8 100644 --- a/unittest/libmariadb/cursor.c +++ b/unittest/libmariadb/cursor.c @@ -421,11 +421,9 @@ static int test_bug10736(MYSQL *mysql) for (i= 0; i < 3; i++) { - int row_no= 0; rc= mysql_stmt_execute(stmt); check_stmt_rc(rc, stmt); - while ((rc= mysql_stmt_fetch(stmt)) == 0) - ++row_no; + while ((rc= mysql_stmt_fetch(stmt)) == 0); FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA"); } rc= mysql_stmt_close(stmt); From 12722e3131c1d2ee381ed024e752ab6db0e766eb Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 27 Jul 2022 14:52:20 +0200 Subject: [PATCH 4/5] Error message fix: Since TLS errors might happen not only when connecting and SSL protocol is not longer used, errormessage for CR_SSL_CONNECTION_ERROR was replaced by TLS/SSL error. --- libmariadb/ma_errmsg.c | 2 +- libmariadb/secure/gnutls.c | 2 +- libmariadb/secure/ma_schannel.c | 5 ++--- libmariadb/secure/schannel.c | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/libmariadb/ma_errmsg.c b/libmariadb/ma_errmsg.c index fe8eea9e..3c6d6ec3 100644 --- a/libmariadb/ma_errmsg.c +++ b/libmariadb/ma_errmsg.c @@ -108,7 +108,7 @@ const char *client_errors[]= /* 2023 */ "", /* 2024 */ "", /* 2025 */ "", -/* 2026 */ "SSL connection error: %-.100s", +/* 2026 */ "TLS/SSL error1: %-.100s", /* 2027 */ "received malformed packet", /* 2028 */ "", /* 2029 */ "", diff --git a/libmariadb/secure/gnutls.c b/libmariadb/secure/gnutls.c index dd462752..6e32366c 100644 --- a/libmariadb/secure/gnutls.c +++ b/libmariadb/secure/gnutls.c @@ -889,7 +889,7 @@ static void ma_tls_set_error(MYSQL *mysql, void *ssl, int ssl_errno) alert_name= gnutls_alert_get_name(alert_desc); snprintf(ssl_error, MAX_SSL_ERR_LEN, "fatal alert received: %s", alert_name); - pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ssl_error); + pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, ssl_error); return; } diff --git a/libmariadb/secure/ma_schannel.c b/libmariadb/secure/ma_schannel.c index e3d395d1..be4148c7 100644 --- a/libmariadb/secure/ma_schannel.c +++ b/libmariadb/secure/ma_schannel.c @@ -52,7 +52,7 @@ void ma_schannel_set_sec_error(MARIADB_PVIO* pvio, DWORD ErrorNo) void ma_schannel_set_win_error(MARIADB_PVIO *pvio, DWORD ErrorNo) { char buffer[256]; - ma_format_win32_error(buffer, sizeof(buffer), ErrorNo, "SSL connection error: "); + ma_format_win32_error(buffer, sizeof(buffer), ErrorNo, "TLS/SSL error: "); pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, buffer); return; } @@ -526,8 +526,7 @@ my_bool ma_schannel_verify_certs(MARIADB_TLS *ctls, BOOL verify_server_name) end: if (!ret) { - pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, - "SSL connection error: %s", errmsg); + pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, errmsg); } if (pServerCert) CertFreeCertificateContext(pServerCert); diff --git a/libmariadb/secure/schannel.c b/libmariadb/secure/schannel.c index acd7394e..4b168129 100644 --- a/libmariadb/secure/schannel.c +++ b/libmariadb/secure/schannel.c @@ -225,7 +225,7 @@ static int ma_tls_set_client_certs(MARIADB_TLS *ctls,const CERT_CONTEXT **cert_c *cert_ctx = schannel_create_cert_context(certfile, keyfile, errmsg, sizeof(errmsg)); if (!*cert_ctx) { - pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: %s", errmsg); + pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, errmsg); return 1; } From 9db7314acd7f3860f3013659b31ae2cb06167b67 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 27 Jul 2022 15:00:46 +0200 Subject: [PATCH 5/5] Fixed typo in ma_errmsg.h --- libmariadb/ma_errmsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb/ma_errmsg.c b/libmariadb/ma_errmsg.c index 3c6d6ec3..1dc4633f 100644 --- a/libmariadb/ma_errmsg.c +++ b/libmariadb/ma_errmsg.c @@ -108,7 +108,7 @@ const char *client_errors[]= /* 2023 */ "", /* 2024 */ "", /* 2025 */ "", -/* 2026 */ "TLS/SSL error1: %-.100s", +/* 2026 */ "TLS/SSL error: %-.100s", /* 2027 */ "received malformed packet", /* 2028 */ "", /* 2029 */ "",