diff --git a/extra/mariadb/0001-openssl-1-1-0.patch b/extra/mariadb/0001-openssl-1-1-0.patch new file mode 100644 index 000000000..8575ef127 --- /dev/null +++ b/extra/mariadb/0001-openssl-1-1-0.patch @@ -0,0 +1,2129 @@ +From fb57acd98f96b3d2684cd29c126b4904db81f84c Mon Sep 17 00:00:00 2001 +From: Georg Richter <georg@mariadb.com> +Date: Wed, 8 Mar 2017 17:39:47 +0100 +Subject: [PATCH 1/2] MDEV-10332 support for OpenSSL 1.1 and LibreSSL + +Initial support + +tested against OpenSSL 1.0.1, 1.0.2, 1.1.0, Yassl and LibreSSL +not working on Windows with native SChannel support, due to wrong cipher +mapping: Latter one requires push of CONC-241 fixes. +Please note that OpenSSL 0.9.8 and OpenSSL 1.1.0 will not work: Even if +the build succeeds, test cases will fail with various errors, especially +when using different tls libraries or versions for client and server. + +Upstream commit: f8866f8f665ac26beb31842fef48ecee5feb346e +--- + extra/yassl/src/handshake.cpp | 10 +++ + include/my_crypt.h | 15 ++++ + include/violite.h | 9 +- + mysql-test/include/require_openssl_client.inc | 5 ++ + mysql-test/mysql-test-run.pl | 5 ++ + mysql-test/r/openssl_1.result | 2 +- + mysql-test/r/openssl_6975,tlsv10.result | 18 ++-- + mysql-test/r/openssl_6975,tlsv12.result | 14 ++-- + mysql-test/t/openssl_1.test | 4 +- + mysql-test/t/openssl_6975.test | 19 +++-- + mysql-test/t/ssl_7937.test | 1 + + mysql-test/t/ssl_8k_key.test | 1 + + mysys_ssl/my_crypt.cc | 115 ++++++++++++++++++-------- + mysys_ssl/my_md5.cc | 39 ++++++--- + mysys_ssl/yassl.cc | 15 ++++ + sql-common/client.c | 6 +- + sql/mysqld.cc | 14 +++- + sql/slave.cc | 13 +++ + vio/viosslfactories.c | 54 ++++++++---- + 19 files changed, 263 insertions(+), 96 deletions(-) + create mode 100644 mysql-test/include/require_openssl_client.inc + +diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp +index 407e4092ccc..6e181a997bd 100644 +--- a/extra/yassl/src/handshake.cpp ++++ b/extra/yassl/src/handshake.cpp +@@ -788,6 +788,16 @@ int DoProcessReply(SSL& ssl) + needHdr = true; + else { + buffer >> hdr; ++ /* ++ According to RFC 4346 (see "7.4.1.3. Server Hello"), the Server Hello ++ packet needs to specify the highest supported TLS version, but not ++ higher than what client requests. YaSSL highest supported version is ++ TLSv1.1 (=3.2) - if the client requests a higher version, downgrade it ++ here to 3.2. ++ See also Appendix E of RFC 5246 (TLS 1.2) ++ */ ++ if (hdr.version_.major_ == 3 && hdr.version_.minor_ > 2) ++ hdr.version_.minor_ = 2; + ssl.verifyState(hdr); + } + +diff --git a/include/my_crypt.h b/include/my_crypt.h +index 719e349bfb9..e7dd9d80100 100644 +--- a/include/my_crypt.h ++++ b/include/my_crypt.h +@@ -21,4 +21,19 @@ + #include <my_config.h> /* HAVE_EncryptAes128{Ctr,Gcm} */ + #include <mysql/service_my_crypt.h> + ++/* OpenSSL version specific definitions */ ++#if !defined(HAVE_YASSL) && defined(OPENSSL_VERSION_NUMBER) ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) ++#define ERR_remove_state(X) ++#else ++#define EVP_CIPHER_CTX_reset(X) EVP_CIPHER_CTX_cleanup(X) ++#define RAND_OpenSSL() RAND_SSLeay(); ++#if defined(HAVE_ERR_remove_thread_state) ++#define ERR_remove_state(X) ERR_remove_thread_state(NULL) ++#endif ++#endif ++#elif defined(HAVE_YASSL) ++#define EVP_CIPHER_CTX_reset(X) EVP_CIPHER_CTX_cleanup(X) ++#endif /* !defined(HAVE_YASSL) */ ++ + #endif /* MY_CRYPT_INCLUDED */ +diff --git a/include/violite.h b/include/violite.h +index a7165ca91a9..23800696e5a 100644 +--- a/include/violite.h ++++ b/include/violite.h +@@ -146,14 +146,15 @@ typedef my_socket YASSL_SOCKET_T; + #include <openssl/ssl.h> + #include <openssl/err.h> + +-#ifdef HAVE_ERR_remove_thread_state ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) ++#define ERR_remove_state(X) ++#elif defined(HAVE_ERR_remove_thread_state) + #define ERR_remove_state(X) ERR_remove_thread_state(NULL) + #endif +- + enum enum_ssl_init_error + { +- SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY, +- SSL_INITERR_NOMATCH, SSL_INITERR_BAD_PATHS, SSL_INITERR_CIPHERS, ++ SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY, ++ SSL_INITERR_NOMATCH, SSL_INITERR_BAD_PATHS, SSL_INITERR_CIPHERS, + SSL_INITERR_MEMFAIL, SSL_INITERR_DH, SSL_INITERR_LASTERR + }; + const char* sslGetErrString(enum enum_ssl_init_error err); +diff --git a/mysql-test/include/require_openssl_client.inc b/mysql-test/include/require_openssl_client.inc +new file mode 100644 +index 00000000000..9b19960041b +--- /dev/null ++++ b/mysql-test/include/require_openssl_client.inc +@@ -0,0 +1,5 @@ ++if ($CLIENT_TLS_LIBRARY != "OpenSSL") { ++ if ($CLIENT_TLS_LIBRARY != "LibreSSL") { ++ skip "Test requires Connector/C with OpenSSL library"; ++ } ++} +diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl +index ef054fb2d3e..7241d2f2ea9 100755 +--- a/mysql-test/mysql-test-run.pl ++++ b/mysql-test/mysql-test-run.pl +@@ -2304,6 +2304,11 @@ sub environment_setup { + $ENV{'MYSQL_PLUGIN'}= $exe_mysql_plugin; + $ENV{'MYSQL_EMBEDDED'}= $exe_mysql_embedded; + ++ my $client_config_exe= ++ native_path("$bindir/libmariadb/mariadb_config$opt_vs_config/mariadb_config"); ++ my $tls_info= `$client_config_exe --tlsinfo`; ++ ($ENV{CLIENT_TLS_LIBRARY},$ENV{CLIENT_TLS_LIBRARY_VERSION})= ++ split(/ /, $tls_info, 2); + my $exe_mysqld= find_mysqld($basedir); + $ENV{'MYSQLD'}= $exe_mysqld; + my $extra_opts= join (" ", @opt_extra_mysqld_opt); +diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result +index 294ddaf7884..9a9bc619377 100644 +--- a/mysql-test/r/openssl_1.result ++++ b/mysql-test/r/openssl_1.result +@@ -198,7 +198,7 @@ DROP TABLE t1; + Variable_name Value + Ssl_cipher DHE-RSA-AES256-SHA + Variable_name Value +-Ssl_cipher EDH-RSA-DES-CBC3-SHA ++Ssl_cipher AES128-SHA + select 'is still running; no cipher request crashed the server' as result from dual; + result + is still running; no cipher request crashed the server +diff --git a/mysql-test/r/openssl_6975,tlsv10.result b/mysql-test/r/openssl_6975,tlsv10.result +index 6285faa0143..202e7f4268e 100644 +--- a/mysql-test/r/openssl_6975,tlsv10.result ++++ b/mysql-test/r/openssl_6975,tlsv10.result +@@ -1,24 +1,24 @@ + create user ssl_sslv3@localhost; +-grant select on test.* to ssl_sslv3@localhost require cipher "RC4-SHA"; ++grant select on test.* to ssl_sslv3@localhost require cipher "AES128-SHA"; + create user ssl_tls12@localhost; + grant select on test.* to ssl_tls12@localhost require cipher "AES128-SHA256"; + TLS1.2 ciphers: user is ok with any cipher +-ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure +-ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure +-TLS1.2 ciphers: user requires SSLv3 cipher RC4-SHA +-ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure +-ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure ++ERROR 2026 (HY000): SSL connection error: sslv3 alert handshake failure ++ERROR 2026 (HY000): SSL connection error: sslv3 alert handshake failure ++TLS1.2 ciphers: user requires SSLv3 cipher AES128-SHA ++ERROR 2026 (HY000): SSL connection error: sslv3 alert handshake failure ++ERROR 2026 (HY000): SSL connection error: sslv3 alert handshake failure + TLS1.2 ciphers: user requires TLSv1.2 cipher AES128-SHA256 + ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure + ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure + SSLv3 ciphers: user is ok with any cipher + Variable_name Value +-Ssl_cipher RC4-SHA ++Ssl_cipher AES256-SHA + Variable_name Value + Ssl_cipher DHE-RSA-AES256-SHA +-SSLv3 ciphers: user requires SSLv3 cipher RC4-SHA ++SSLv3 ciphers: user requires SSLv3 cipher AES128-SHA + Variable_name Value +-Ssl_cipher RC4-SHA ++Ssl_cipher AES128-SHA + ERROR 1045 (28000): Access denied for user 'ssl_sslv3'@'localhost' (using password: NO) + SSLv3 ciphers: user requires TLSv1.2 cipher AES128-SHA256 + ERROR 1045 (28000): Access denied for user 'ssl_tls12'@'localhost' (using password: NO) +diff --git a/mysql-test/r/openssl_6975,tlsv12.result b/mysql-test/r/openssl_6975,tlsv12.result +index 31d2658c829..e2cc28cca70 100644 +--- a/mysql-test/r/openssl_6975,tlsv12.result ++++ b/mysql-test/r/openssl_6975,tlsv12.result +@@ -1,5 +1,5 @@ + create user ssl_sslv3@localhost; +-grant select on test.* to ssl_sslv3@localhost require cipher "RC4-SHA"; ++grant select on test.* to ssl_sslv3@localhost require cipher "AES128-SHA"; + create user ssl_tls12@localhost; + grant select on test.* to ssl_tls12@localhost require cipher "AES128-SHA256"; + TLS1.2 ciphers: user is ok with any cipher +@@ -7,7 +7,7 @@ Variable_name Value + Ssl_cipher AES128-SHA256 + Variable_name Value + Ssl_cipher DHE-RSA-AES256-GCM-SHA384 +-TLS1.2 ciphers: user requires SSLv3 cipher RC4-SHA ++TLS1.2 ciphers: user requires SSLv3 cipher AES128-SHA + ERROR 1045 (28000): Access denied for user 'ssl_sslv3'@'localhost' (using password: NO) + ERROR 1045 (28000): Access denied for user 'ssl_sslv3'@'localhost' (using password: NO) + TLS1.2 ciphers: user requires TLSv1.2 cipher AES128-SHA256 +@@ -15,11 +15,11 @@ Variable_name Value + Ssl_cipher AES128-SHA256 + ERROR 1045 (28000): Access denied for user 'ssl_tls12'@'localhost' (using password: NO) + SSLv3 ciphers: user is ok with any cipher +-ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure +-ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure +-SSLv3 ciphers: user requires SSLv3 cipher RC4-SHA +-ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure +-ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure ++ERROR 2026 (HY000): SSL connection error: sslv3 alert handshake failure ++ERROR 2026 (HY000): SSL connection error: sslv3 alert handshake failure ++SSLv3 ciphers: user requires SSLv3 cipher AES128-SHA ++ERROR 2026 (HY000): SSL connection error: sslv3 alert handshake failure ++ERROR 2026 (HY000): SSL connection error: sslv3 alert handshake failure + SSLv3 ciphers: user requires TLSv1.2 cipher AES128-SHA256 + ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure + ERROR 2026 (HY000): SSL connection error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure +diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test +index eea74b5b012..28f666263d2 100644 +--- a/mysql-test/t/openssl_1.test ++++ b/mysql-test/t/openssl_1.test +@@ -221,8 +221,8 @@ DROP TABLE t1; + # + + # Common ciphers to openssl and yassl +---exec $MYSQL --host=localhost -e "SHOW STATUS LIKE 'Ssl_cipher';" --ssl-cipher=DHE-RSA-AES256-SHA +---exec $MYSQL --host=localhost -e "SHOW STATUS LIKE 'Ssl_cipher';" --ssl-cipher=EDH-RSA-DES-CBC3-SHA ++--exec $MYSQL --host=localhost -e "SHOW STATUS LIKE 'Ssl_cipher';" --ssl-cipher=AES256-SHA ++--exec $MYSQL --host=localhost -e "SHOW STATUS LIKE 'Ssl_cipher';" --ssl-cipher=AES128-SHA + --disable_query_log + --disable_result_log + +diff --git a/mysql-test/t/openssl_6975.test b/mysql-test/t/openssl_6975.test +index 6e8e03a0a89..6cf5d82cf54 100644 +--- a/mysql-test/t/openssl_6975.test ++++ b/mysql-test/t/openssl_6975.test +@@ -4,11 +4,13 @@ + # test SSLv3 and TLSv1.2 ciphers when OpenSSL is restricted to SSLv3 or TLSv1.2 + # + source include/have_ssl_communication.inc; ++source include/require_openssl_client.inc; + + # this is OpenSSL test. + + create user ssl_sslv3@localhost; +-grant select on test.* to ssl_sslv3@localhost require cipher "RC4-SHA"; ++# grant select on test.* to ssl_sslv3@localhost require cipher "AES128-SHA"; ++grant select on test.* to ssl_sslv3@localhost require cipher "AES128-SHA"; + create user ssl_tls12@localhost; + grant select on test.* to ssl_tls12@localhost require cipher "AES128-SHA256"; + +@@ -18,8 +20,9 @@ disable_abort_on_error; + echo TLS1.2 ciphers: user is ok with any cipher; + exec $mysql --ssl-cipher=AES128-SHA256; + --replace_result DHE-RSA-CHACHA20-POLY1305 DHE-RSA-AES256-GCM-SHA384 +-exec $mysql --ssl-cipher=TLSv1.2; +-echo TLS1.2 ciphers: user requires SSLv3 cipher RC4-SHA; ++--replace_result ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ++exec $mysql --ssl-cipher=TLSv1.2 ++echo TLS1.2 ciphers: user requires SSLv3 cipher AES128-SHA; + exec $mysql --user ssl_sslv3 --ssl-cipher=AES128-SHA256; + exec $mysql --user ssl_sslv3 --ssl-cipher=TLSv1.2; + echo TLS1.2 ciphers: user requires TLSv1.2 cipher AES128-SHA256; +@@ -27,13 +30,13 @@ exec $mysql --user ssl_tls12 --ssl-cipher=AES128-SHA256; + exec $mysql --user ssl_tls12 --ssl-cipher=TLSv1.2; + + echo SSLv3 ciphers: user is ok with any cipher; +-exec $mysql --ssl-cipher=RC4-SHA; +-exec $mysql --ssl-cipher=SSLv3; +-echo SSLv3 ciphers: user requires SSLv3 cipher RC4-SHA; +-exec $mysql --user ssl_sslv3 --ssl-cipher=RC4-SHA; ++exec $mysql --ssl-cipher=AES256-SHA; ++exec $mysql --ssl-cipher=DHE-RSA-AES256-SHA ++echo SSLv3 ciphers: user requires SSLv3 cipher AES128-SHA; ++exec $mysql --user ssl_sslv3 --ssl-cipher=AES128-SHA; + exec $mysql --user ssl_sslv3 --ssl-cipher=SSLv3; + echo SSLv3 ciphers: user requires TLSv1.2 cipher AES128-SHA256; +-exec $mysql --user ssl_tls12 --ssl-cipher=RC4-SHA; ++exec $mysql --user ssl_tls12 --ssl-cipher=AES128-SHA; + exec $mysql --user ssl_tls12 --ssl-cipher=SSLv3; + + drop user ssl_sslv3@localhost; +diff --git a/mysql-test/t/ssl_7937.test b/mysql-test/t/ssl_7937.test +index d593b9d936d..a76457906ec 100644 +--- a/mysql-test/t/ssl_7937.test ++++ b/mysql-test/t/ssl_7937.test +@@ -26,6 +26,7 @@ create procedure have_ssl() + # we fake the test result for yassl + let yassl=`select variable_value='Unknown' from information_schema.session_status where variable_name='Ssl_session_cache_mode'`; + if (!$yassl) { ++ --replace_result "self signed certificate in certificate chain" "Failed to verify the server certificate" "Error in the certificate." "Failed to verify the server certificate" + --exec $MYSQL --ssl --ssl-verify-server-cert -e "call test.have_ssl()" 2>&1 + } + if ($yassl) { +diff --git a/mysql-test/t/ssl_8k_key.test b/mysql-test/t/ssl_8k_key.test +index 27cffdce1f2..470d577edb8 100644 +--- a/mysql-test/t/ssl_8k_key.test ++++ b/mysql-test/t/ssl_8k_key.test +@@ -1,4 +1,5 @@ + # This test should work in embedded server after we fix mysqltest ++-- source include/require_openssl_client.inc + -- source include/not_embedded.inc + + -- source include/have_ssl_communication.inc +diff --git a/mysys_ssl/my_crypt.cc b/mysys_ssl/my_crypt.cc +index a0937a83e17..0ff49a2c427 100644 +--- a/mysys_ssl/my_crypt.cc ++++ b/mysys_ssl/my_crypt.cc +@@ -17,7 +17,6 @@ + + #include <my_global.h> + #include <string.h> +-#include <my_crypt.h> + + #ifdef HAVE_YASSL + #include "yassl.cc" +@@ -26,43 +25,51 @@ + #include <openssl/evp.h> + #include <openssl/aes.h> + #include <openssl/err.h> ++#include <openssl/rand.h> + +-#ifdef HAVE_ERR_remove_thread_state +-#define ERR_remove_state(X) ERR_remove_thread_state(NULL) + #endif ++#include <my_crypt.h> + +-#endif ++#define MY_CIPHER_CTX_SIZE 384 + + class MyCTX + { + public: +- EVP_CIPHER_CTX ctx; +- MyCTX() { EVP_CIPHER_CTX_init(&ctx); } +- virtual ~MyCTX() { EVP_CIPHER_CTX_cleanup(&ctx); ERR_remove_state(0); } ++ EVP_CIPHER_CTX *ctx; ++ const uchar *key; ++ unsigned int klen; ++ MyCTX() { ++ ctx= EVP_CIPHER_CTX_new(); ++ } ++ virtual ~MyCTX() { ++ EVP_CIPHER_CTX_free(ctx); ++ ERR_remove_state(0); ++ } + + virtual int init(const EVP_CIPHER *cipher, int encrypt, const uchar *key, + uint klen, const uchar *iv, uint ivlen) + { ++ compile_time_assert(MY_AES_CTX_SIZE >= sizeof(MyCTX)); + if (unlikely(!cipher)) + return MY_AES_BAD_KEYSIZE; + +- if (!EVP_CipherInit_ex(&ctx, cipher, NULL, key, iv, encrypt)) ++ if (!EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, encrypt)) + return MY_AES_OPENSSL_ERROR; + +- DBUG_ASSERT(EVP_CIPHER_CTX_key_length(&ctx) == (int)klen); +- DBUG_ASSERT(EVP_CIPHER_CTX_iv_length(&ctx) <= (int)ivlen); ++ DBUG_ASSERT(EVP_CIPHER_CTX_key_length(ctx) == (int)klen); ++ DBUG_ASSERT(EVP_CIPHER_CTX_iv_length(ctx) <= (int)ivlen); + + return MY_AES_OK; + } + virtual int update(const uchar *src, uint slen, uchar *dst, uint *dlen) + { +- if (!EVP_CipherUpdate(&ctx, dst, (int*)dlen, src, slen)) ++ if (!EVP_CipherUpdate(ctx, dst, (int*)dlen, src, slen)) + return MY_AES_OPENSSL_ERROR; + return MY_AES_OK; + } + virtual int finish(uchar *dst, uint *dlen) + { +- if (!EVP_CipherFinal_ex(&ctx, dst, (int*)dlen)) ++ if (!EVP_CipherFinal_ex(ctx, dst, (int*)dlen)) + return MY_AES_BAD_DATA; + return MY_AES_OK; + } +@@ -71,11 +78,9 @@ class MyCTX + class MyCTX_nopad : public MyCTX + { + public: +- const uchar *key; +- int klen; +- + MyCTX_nopad() : MyCTX() { } + ~MyCTX_nopad() { } ++ unsigned int buf_len; + + int init(const EVP_CIPHER *cipher, int encrypt, const uchar *key, uint klen, + const uchar *iv, uint ivlen) +@@ -83,16 +88,39 @@ class MyCTX_nopad : public MyCTX + compile_time_assert(MY_AES_CTX_SIZE >= sizeof(MyCTX_nopad)); + this->key= key; + this->klen= klen; ++ this->buf_len= 0; ++ /* FIX-ME: ++ For the sake of backward compatibility we do some strange hack here: ++ Since ECB doesn't need an IV (and therefore is considered kind of ++ insecure) we need to store the specified iv. ++ The last nonpadding block will be encrypted with an additional ++ expensive crypt_call in ctr mode instead ++ of encrypting the entire plain text in ctr-mode */ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) ++ const unsigned char *oiv= EVP_CIPHER_CTX_original_iv(ctx); ++#else ++ const unsigned char *oiv= ctx->oiv; ++#endif ++ memcpy((char *)oiv, iv, ivlen); ++ + int res= MyCTX::init(cipher, encrypt, key, klen, iv, ivlen); +- memcpy(ctx.oiv, iv, ivlen); // in ECB mode OpenSSL doesn't do that itself +- EVP_CIPHER_CTX_set_padding(&ctx, 0); ++ ++ EVP_CIPHER_CTX_set_padding(ctx, 0); + return res; + } + ++ int update(const uchar *src, uint slen, uchar *dst, uint *dlen) ++ { ++ buf_len= slen % MY_AES_BLOCK_SIZE; ++ return MyCTX::update(src, slen, dst, dlen); ++ } ++ + int finish(uchar *dst, uint *dlen) + { +- if (ctx.buf_len) ++ if (buf_len) + { ++ const uchar *org_iv; ++ unsigned char *buf; + /* + Not much we can do, block ciphers cannot encrypt data that aren't + a multiple of the block length. At least not without padding. +@@ -101,14 +129,22 @@ class MyCTX_nopad : public MyCTX + uchar mask[MY_AES_BLOCK_SIZE]; + uint mlen; + ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) ++ org_iv= EVP_CIPHER_CTX_original_iv(ctx); ++ buf= EVP_CIPHER_CTX_buf_noconst(ctx); ++#else ++ org_iv= ctx->oiv; ++ buf= ctx->buf; ++#endif ++ + my_aes_crypt(MY_AES_ECB, ENCRYPTION_FLAG_ENCRYPT | ENCRYPTION_FLAG_NOPAD, +- ctx.oiv, sizeof(mask), mask, &mlen, key, klen, 0, 0); ++ org_iv, sizeof(mask), mask, &mlen, key, klen, 0, 0); + DBUG_ASSERT(mlen == sizeof(mask)); + +- for (int i=0; i < ctx.buf_len; i++) +- dst[i]= ctx.buf[i] ^ mask[i]; ++ for (uint i=0; i < buf_len; i++) ++ dst[i]= buf[i] ^ mask[i]; + } +- *dlen= ctx.buf_len; ++ *dlen= buf_len; + return MY_AES_OK; + } + }; +@@ -142,8 +178,9 @@ make_aes_dispatcher(gcm) + class MyCTX_gcm : public MyCTX + { + public: +- const uchar *aad; ++ const uchar *aad= NULL; + int aadlen; ++ my_bool encrypt; + MyCTX_gcm() : MyCTX() { } + ~MyCTX_gcm() { } + +@@ -152,9 +189,10 @@ class MyCTX_gcm : public MyCTX + { + compile_time_assert(MY_AES_CTX_SIZE >= sizeof(MyCTX_gcm)); + int res= MyCTX::init(cipher, encrypt, key, klen, iv, ivlen); +- int real_ivlen= EVP_CIPHER_CTX_iv_length(&ctx); ++ int real_ivlen= EVP_CIPHER_CTX_iv_length(ctx); + aad= iv + real_ivlen; + aadlen= ivlen - real_ivlen; ++ this->encrypt= encrypt; + return res; + } + +@@ -166,15 +204,15 @@ class MyCTX_gcm : public MyCTX + before decrypting the data. it can encrypt data piecewise, like, first + half, then the second half, but it must decrypt all at once + */ +- if (!ctx.encrypt) ++ if (!this->encrypt) + { + slen-= MY_AES_BLOCK_SIZE; +- if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, MY_AES_BLOCK_SIZE, ++ if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, MY_AES_BLOCK_SIZE, + (void*)(src + slen))) + return MY_AES_OPENSSL_ERROR; + } +- int unused; +- if (aadlen && !EVP_CipherUpdate(&ctx, NULL, &unused, aad, aadlen)) ++ int unused= 0; ++ if (aadlen && !EVP_CipherUpdate(ctx, NULL, &unused, aad, aadlen)) + return MY_AES_OPENSSL_ERROR; + aadlen= 0; + return MyCTX::update(src, slen, dst, dlen); +@@ -182,14 +220,14 @@ class MyCTX_gcm : public MyCTX + + int finish(uchar *dst, uint *dlen) + { +- int fin; +- if (!EVP_CipherFinal_ex(&ctx, dst, &fin)) ++ int fin= 0; ++ if (!EVP_CipherFinal_ex(ctx, dst, &fin)) + return MY_AES_BAD_DATA; + DBUG_ASSERT(fin == 0); + +- if (ctx.encrypt) ++ if (this->encrypt) + { +- if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, MY_AES_BLOCK_SIZE, dst)) ++ if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, MY_AES_BLOCK_SIZE, dst)) + return MY_AES_OPENSSL_ERROR; + *dlen= MY_AES_BLOCK_SIZE; + } +@@ -257,12 +295,20 @@ int my_aes_crypt(enum my_aes_mode mode, int flags, + { + void *ctx= alloca(MY_AES_CTX_SIZE); + int res1, res2; +- uint d1, d2; ++ uint d1= 0, d2= 0; + if ((res1= my_aes_crypt_init(ctx, mode, flags, key, klen, iv, ivlen))) + return res1; + res1= my_aes_crypt_update(ctx, src, slen, dst, &d1); + res2= my_aes_crypt_finish(ctx, dst + d1, &d2); + *dlen= d1 + d2; ++ /* in case of failure clear error queue */ ++#ifndef HAVE_YASSL ++ /* since we don't check the crypto error messages we need to ++ clear the error queue - otherwise subsequent crypto or tls/ssl ++ calls will fail */ ++ if (!*dlen) ++ ERR_clear_error(); ++#endif + return res1 ? res1 : res2; + } + +@@ -301,7 +347,6 @@ int my_random_bytes(uchar* buf, int num) + return MY_AES_OK; + } + #else +-#include <openssl/rand.h> + + int my_random_bytes(uchar *buf, int num) + { +@@ -311,7 +356,7 @@ int my_random_bytes(uchar *buf, int num) + instead of whatever random engine is currently set in OpenSSL. That way + we are guaranteed to have a non-blocking random. + */ +- RAND_METHOD *rand = RAND_SSLeay(); ++ RAND_METHOD *rand = RAND_OpenSSL(); + if (rand == NULL || rand->bytes(buf, num) != 1) + return MY_AES_OPENSSL_ERROR; + return MY_AES_OK; +diff --git a/mysys_ssl/my_md5.cc b/mysys_ssl/my_md5.cc +index 7139ea9b6ff..02c01dd7148 100644 +--- a/mysys_ssl/my_md5.cc ++++ b/mysys_ssl/my_md5.cc +@@ -27,6 +27,8 @@ + #include <my_md5.h> + #include <stdarg.h> + ++#define MA_HASH_CTX_SIZE 512 ++ + #if defined(HAVE_YASSL) + #include "md5.hpp" + +@@ -57,11 +59,18 @@ static void md5_result(MD5_CONTEXT *context, uchar digest[MD5_HASH_SIZE]) + } + + #elif defined(HAVE_OPENSSL) ++ ++ + #include <openssl/evp.h> ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++#define EVP_MD_CTX_reset(X) EVP_MD_CTX_cleanup(X) ++#endif + typedef EVP_MD_CTX MD5_CONTEXT; + + static void md5_init(MD5_CONTEXT *context) + { ++ memset(context, 0, my_md5_context_size()); + EVP_MD_CTX_init(context); + #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW + /* Ok to ignore FIPS: MD5 is not used for crypto here */ +@@ -83,7 +92,7 @@ static void md5_input(MD5_CONTEXT *context, const uchar *buf, unsigned len) + static void md5_result(MD5_CONTEXT *context, uchar digest[MD5_HASH_SIZE]) + { + EVP_DigestFinal_ex(context, digest, NULL); +- EVP_MD_CTX_cleanup(context); ++ EVP_MD_CTX_reset(context); + } + + #endif /* HAVE_YASSL */ +@@ -99,11 +108,14 @@ static void md5_result(MD5_CONTEXT *context, uchar digest[MD5_HASH_SIZE]) + */ + void my_md5(uchar *digest, const char *buf, size_t len) + { ++#ifdef HAVE_YASSL + MD5_CONTEXT md5_context; +- +- md5_init_fast(&md5_context); +- md5_input(&md5_context, (const uchar *)buf, len); +- md5_result(&md5_context, digest); ++#else ++ unsigned char md5_context[MA_HASH_CTX_SIZE]; ++#endif ++ md5_init_fast((MD5_CONTEXT *)&md5_context); ++ md5_input((MD5_CONTEXT *)&md5_context, (const uchar *)buf, len); ++ md5_result((MD5_CONTEXT *)&md5_context, digest); + } + + +@@ -122,22 +134,25 @@ void my_md5(uchar *digest, const char *buf, size_t len) + void my_md5_multi(uchar *digest, ...) + { + va_list args; +- va_start(args, digest); +- +- MD5_CONTEXT md5_context; + const uchar *str; ++#ifdef HAVE_YASSL ++ MD5_CONTEXT md5_context; ++#else ++ unsigned char md5_context[MA_HASH_CTX_SIZE]; ++#endif ++ va_start(args, digest); + +- md5_init_fast(&md5_context); ++ md5_init_fast((MD5_CONTEXT *)&md5_context); + for (str= va_arg(args, const uchar*); str; str= va_arg(args, const uchar*)) +- md5_input(&md5_context, str, va_arg(args, size_t)); ++ md5_input((MD5_CONTEXT *)&md5_context, str, va_arg(args, size_t)); + +- md5_result(&md5_context, digest); ++ md5_result((MD5_CONTEXT *)&md5_context, digest); + va_end(args); + } + + size_t my_md5_context_size() + { +- return sizeof(MD5_CONTEXT); ++ return MA_HASH_CTX_SIZE; + } + + void my_md5_init(void *context) +diff --git a/mysys_ssl/yassl.cc b/mysys_ssl/yassl.cc +index 9717870fe26..9e6f90d8d77 100644 +--- a/mysys_ssl/yassl.cc ++++ b/mysys_ssl/yassl.cc +@@ -24,6 +24,7 @@ + + #include <openssl/ssl.h> + #include "aes.hpp" ++#include <my_sys.h> + + using yaSSL::yaERR_remove_state; + +@@ -75,12 +76,26 @@ static void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) + ctx->final_used= ctx->buf_len= ctx->flags= 0; + } + ++static EVP_CIPHER_CTX *EVP_CIPHER_CTX_new() ++{ ++ EVP_CIPHER_CTX *ctx= (EVP_CIPHER_CTX *)my_malloc(sizeof(EVP_CIPHER_CTX), MYF(0)); ++ if (ctx) ++ EVP_CIPHER_CTX_init(ctx); ++ return ctx; ++} ++ + static int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *ctx) + { + TAO(ctx)->~AES(); + return 1; + } + ++static void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) ++{ ++ EVP_CIPHER_CTX_cleanup(ctx); ++ my_free(ctx); ++} ++ + static int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) + { + if (pad) +diff --git a/sql-common/client.c b/sql-common/client.c +index a918060a848..d881080b55a 100644 +--- a/sql-common/client.c ++++ b/sql-common/client.c +@@ -104,6 +104,10 @@ my_bool net_flush(NET *net); + #define CONNECT_TIMEOUT 0 + #endif + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) || defined(HAVE_YASSL) ++#define ASN1_STRING_get0_data(X) ASN1_STRING_data(X) ++#endif ++ + #include "client_settings.h" + #include <sql_common.h> + #include <mysql/client_plugin.h> +@@ -1842,7 +1846,7 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const c + goto error; + } + +- cn= (char *) ASN1_STRING_data(cn_asn1); ++ cn= (char *) ASN1_STRING_get0_data(cn_asn1); + + if ((size_t)ASN1_STRING_length(cn_asn1) != strlen(cn)) + { +diff --git a/sql/mysqld.cc b/sql/mysqld.cc +index 0bf57d9543b..d6a7c6b4931 100644 +--- a/sql/mysqld.cc ++++ b/sql/mysqld.cc +@@ -111,6 +111,7 @@ + #endif + + #include <my_systemd.h> ++#include <my_crypt.h> + + #define mysqld_charset &my_charset_latin1 + +@@ -120,6 +121,7 @@ + #define HAVE_CLOSE_SERVER_SOCK 1 + #endif + ++ + extern "C" { // Because of SCO 3.2V4.2 + #include <sys/stat.h> + #ifndef __GNU_LIBRARY__ +@@ -1456,6 +1458,8 @@ scheduler_functions *thread_scheduler= &thread_scheduler_struct, + #ifdef HAVE_OPENSSL + #include <openssl/crypto.h> + #ifndef HAVE_YASSL ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + typedef struct CRYPTO_dynlock_value + { + mysql_rwlock_t lock; +@@ -1467,6 +1471,7 @@ static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int); + static void openssl_lock_function(int, int, const char *, int); + static void openssl_lock(int, openssl_lock_t *, const char *, int); + #endif ++#endif + char *des_key_file; + #ifndef EMBEDDED_LIBRARY + struct st_VioSSLFd *ssl_acceptor_fd; +@@ -2243,9 +2248,11 @@ static void clean_up_mutexes() + #ifdef HAVE_OPENSSL + mysql_mutex_destroy(&LOCK_des_key_file); + #ifndef HAVE_YASSL ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + for (int i= 0; i < CRYPTO_num_locks(); ++i) + mysql_rwlock_destroy(&openssl_stdlocks[i].lock); + OPENSSL_free(openssl_stdlocks); ++#endif + #endif /* HAVE_YASSL */ + #endif /* HAVE_OPENSSL */ + #ifdef HAVE_REPLICATION +@@ -4595,6 +4602,7 @@ static int init_thread_environment() + mysql_mutex_init(key_LOCK_des_key_file, + &LOCK_des_key_file, MY_MUTEX_INIT_FAST); + #ifndef HAVE_YASSL ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() * + sizeof(openssl_lock_t)); + for (int i= 0; i < CRYPTO_num_locks(); ++i) +@@ -4605,6 +4613,7 @@ static int init_thread_environment() + CRYPTO_set_locking_callback(openssl_lock_function); + #endif + #endif ++#endif + mysql_rwlock_init(key_rwlock_LOCK_sys_init_connect, &LOCK_sys_init_connect); + mysql_rwlock_init(key_rwlock_LOCK_sys_init_slave, &LOCK_sys_init_slave); + mysql_rwlock_init(key_rwlock_LOCK_grant, &LOCK_grant); +@@ -4638,6 +4647,7 @@ static int init_thread_environment() + + + #if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL) ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + static openssl_lock_t *openssl_dynlock_create(const char *file, int line) + { + openssl_lock_t *lock= new openssl_lock_t; +@@ -4697,6 +4707,7 @@ static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, + abort(); + } + } ++#endif + #endif /* HAVE_OPENSSL */ + + +@@ -4726,8 +4737,9 @@ static void init_ssl() + while ((err= ERR_get_error())) + sql_print_warning("SSL error: %s", ERR_error_string(err, NULL)); + } +- else ++ else { + ERR_remove_state(0); ++ } + } + else + { +diff --git a/sql/slave.cc b/sql/slave.cc +index f95dd60287b..636965c4619 100644 +--- a/sql/slave.cc ++++ b/sql/slave.cc +@@ -60,6 +60,11 @@ + #include "debug_sync.h" + #include "rpl_parallel.h" + ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++#define ERR_remove_state(X) ++#elif defined(HAVE_ERR_remove_thread_state) ++#define ERR_remove_state(X) ERR_remove_thread_state(NULL) ++#endif + + #define FLAGSTR(V,F) ((V)&(F)?#F" ":"") + +@@ -4505,7 +4510,11 @@ log space"); + DBUG_LEAVE; // Must match DBUG_ENTER() + my_thread_end(); + #ifdef HAVE_OPENSSL ++#if OPENSSL_VERSION_NUMBER < 0x10000000L + ERR_remove_state(0); ++#elif OPENSSL_VERSION_NUMBER < 0x10100000L ++ ERR_remove_thread_state(0); ++#endif + #endif + pthread_exit(0); + return 0; // Avoid compiler warnings +@@ -5166,7 +5175,11 @@ pthread_handler_t handle_slave_sql(void *arg) + DBUG_LEAVE; // Must match DBUG_ENTER() + my_thread_end(); + #ifdef HAVE_OPENSSL ++#if OPENSSL_VERSION_NUMBER < 0x10000000L + ERR_remove_state(0); ++#elif OPENSSL_VERSION_NUMBER < 0x10100000L ++ ERR_remove_thread_state(0); ++#endif + #endif + pthread_exit(0); + return 0; // Avoid compiler warnings +diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c +index 52b624d3376..497047cac72 100644 +--- a/vio/viosslfactories.c ++++ b/vio/viosslfactories.c +@@ -17,17 +17,27 @@ + #include "vio_priv.h" + + #ifdef HAVE_OPENSSL +-#ifndef HAVE_YASSL ++#if defined(HAVE_YASSL) || defined(LIBRESSL_VERSION_NUMBER) ++#define OPENSSL_init_ssl(X,Y) SSL_library_init() ++#else + #include <openssl/dh.h> + #include <openssl/bn.h> ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++#define ERR_remove_state(X) ++#else ++#define OPENSSL_init_ssl(X,Y) SSL_library_init() ++#endif ++ + #endif + + static my_bool ssl_algorithms_added = FALSE; + static my_bool ssl_error_strings_loaded= FALSE; + + /* the function below was generated with "openssl dhparam -2 -C 2048" */ +-static +-DH *get_dh2048() ++ ++/* {{{ get_dh_2048 */ ++static DH *get_dh_2048() + { + static unsigned char dh2048_p[]={ + 0xA1,0xBB,0x7C,0x20,0xC5,0x5B,0xC0,0x7B,0x21,0x8B,0xD6,0xA8, +@@ -57,18 +67,32 @@ DH *get_dh2048() + 0x02, + }; + DH *dh; +- +- if ((dh=DH_new()) == NULL) return(NULL); +- dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL); +- dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL); +- if ((dh->p == NULL) || (dh->g == NULL)) +- { DH_free(dh); return(NULL); } +- return(dh); ++ if ((dh=DH_new()) == NULL) ++ return(NULL); ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++ (dh)->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL); ++ (dh)->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL); ++ if ((dh)->p == NULL || (dh)->g == NULL) ++ { DH_free(dh); return NULL; } ++#else ++ { ++ BIGNUM *dhp_bn= BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL), ++ *dhg_bn= BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL); ++ if (dhp_bn == NULL || dhg_bn == NULL || ++ !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) ++ { ++ DH_free(dh); ++ BN_free(dhp_bn); ++ BN_free(dhg_bn); ++ return NULL; ++ } ++ } ++#endif ++ return dh; + } + +- + static const char* +-ssl_error_string[] = ++ssl_error_string[] = + { + "No error", + "Unable to get certificate", +@@ -148,9 +172,7 @@ static void check_ssl_init() + if (!ssl_algorithms_added) + { + ssl_algorithms_added= TRUE; +- SSL_library_init(); +- OpenSSL_add_all_algorithms(); +- ++ OPENSSL_init_ssl(0, NULL); + } + + if (!ssl_error_strings_loaded) +@@ -265,7 +287,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, + /* DH stuff */ + if (!is_client_method) + { +- dh=get_dh2048(); ++ dh=get_dh_2048(); + if (!SSL_CTX_set_tmp_dh(ssl_fd->ssl_context, dh)) + { + *error= SSL_INITERR_DH; +From 1e73c46c82f65ef59485f4789cc0642a03bb2494 Mon Sep 17 00:00:00 2001 +From: Sergei Golubchik <serg@mariadb.org> +Date: Wed, 3 May 2017 21:22:59 +0200 +Subject: [PATCH 2/2] MDEV-10332 support for OpenSSL 1.1 and LibreSSL + +post-review fixes: +* move all ssl implementation related ifdefs/defines to one file + (ssl_compat.h) +* work around OpenSSL-1.1 desire to malloc every EVP context by + run-time checking that context allocated on the stack is big enough + (openssl.c) +* use newer version of the AWS SDK for OpenSSL 1.1 +* use get_dh2048() function as generated by openssl 1.1 + (viosslfactories.c) + +Upstream commit: ccca4f43c92916c347210a7f9a8126f2aa3f6c31 +--- + include/my_crypt.h | 15 ----- + include/ssl_compat.h | 75 +++++++++++++++++++++ + include/violite.h | 12 ---- + mysql-test/mysql-test-run.pl | 2 +- + mysql-test/t/openssl_6975.test | 7 +- + mysql-test/t/ssl_8k_key.test | 5 +- + mysys_ssl/CMakeLists.txt | 1 + + mysys_ssl/my_crypt.cc | 102 +++++++++++------------------ + mysys_ssl/my_md5.cc | 85 +++++++++--------------- + mysys_ssl/openssl.c | 71 ++++++++++++++++++++ + mysys_ssl/yassl.cc | 19 ------ + plugin/aws_key_management/CMakeLists.txt | 10 +++ + sql-common/client.c | 8 +-- + sql/mysqld.cc | 49 +++++++------- + sql/slave.cc | 19 +----- + vio/vio.c | 1 + + vio/viosslfactories.c | 108 +++++++++++++------------------ + 17 files changed, 305 insertions(+), 284 deletions(-) + create mode 100644 include/ssl_compat.h + create mode 100644 mysys_ssl/openssl.c + +diff --git a/include/my_crypt.h b/include/my_crypt.h +index e7dd9d80100..719e349bfb9 100644 +--- a/include/my_crypt.h ++++ b/include/my_crypt.h +@@ -21,19 +21,4 @@ + #include <my_config.h> /* HAVE_EncryptAes128{Ctr,Gcm} */ + #include <mysql/service_my_crypt.h> + +-/* OpenSSL version specific definitions */ +-#if !defined(HAVE_YASSL) && defined(OPENSSL_VERSION_NUMBER) +-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) +-#define ERR_remove_state(X) +-#else +-#define EVP_CIPHER_CTX_reset(X) EVP_CIPHER_CTX_cleanup(X) +-#define RAND_OpenSSL() RAND_SSLeay(); +-#if defined(HAVE_ERR_remove_thread_state) +-#define ERR_remove_state(X) ERR_remove_thread_state(NULL) +-#endif +-#endif +-#elif defined(HAVE_YASSL) +-#define EVP_CIPHER_CTX_reset(X) EVP_CIPHER_CTX_cleanup(X) +-#endif /* !defined(HAVE_YASSL) */ +- + #endif /* MY_CRYPT_INCLUDED */ +diff --git a/include/ssl_compat.h b/include/ssl_compat.h +new file mode 100644 +index 00000000000..b0e3ed497cd +--- /dev/null ++++ b/include/ssl_compat.h +@@ -0,0 +1,75 @@ ++/* ++ Copyright (c) 2016, 2017 MariaDB Corporation ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; version 2 of the License. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ ++ ++#include <openssl/opensslv.h> ++ ++/* OpenSSL version specific definitions */ ++#if !defined(HAVE_YASSL) && defined(OPENSSL_VERSION_NUMBER) ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) ++#define HAVE_X509_check_host 1 ++#endif ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) ++#define HAVE_OPENSSL11 1 ++#define ERR_remove_state(X) ERR_clear_error() ++#define EVP_MD_CTX_cleanup(X) EVP_MD_CTX_reset(X) ++#define EVP_CIPHER_CTX_SIZE 168 ++#define EVP_MD_CTX_SIZE 48 ++#undef EVP_MD_CTX_init ++#define EVP_MD_CTX_init(X) do { bzero((X), EVP_MD_CTX_SIZE); EVP_MD_CTX_reset(X); } while(0) ++#undef EVP_CIPHER_CTX_init ++#define EVP_CIPHER_CTX_init(X) do { bzero((X), EVP_CIPHER_CTX_SIZE); EVP_CIPHER_CTX_reset(X); } while(0) ++ ++#else ++#define HAVE_OPENSSL10 1 ++/* ++ Unfortunately RAND_bytes manual page does not provide any guarantees ++ in relation to blocking behavior. Here we explicitly use SSLeay random ++ instead of whatever random engine is currently set in OpenSSL. That way ++ we are guaranteed to have a non-blocking random. ++*/ ++#define RAND_OpenSSL() RAND_SSLeay() ++ ++#ifdef HAVE_ERR_remove_thread_state ++#define ERR_remove_state(X) ERR_remove_thread_state(NULL) ++#endif /* HAVE_ERR_remove_thread_state */ ++ ++#endif /* HAVE_OPENSSL11 */ ++ ++#elif defined(HAVE_YASSL) ++#define BN_free(X) do { } while(0) ++#endif /* !defined(HAVE_YASSL) */ ++ ++#ifndef HAVE_OPENSSL11 ++#define ASN1_STRING_get0_data(X) ASN1_STRING_data(X) ++#define OPENSSL_init_ssl(X,Y) SSL_library_init() ++#define DH_set0_pqg(D,P,Q,G) ((D)->p= (P), (D)->g= (G)) ++#define EVP_CIPHER_CTX_buf_noconst(ctx) ((ctx)->buf) ++#define EVP_CIPHER_CTX_encrypting(ctx) ((ctx)->encrypt) ++#define EVP_CIPHER_CTX_SIZE sizeof(EVP_CIPHER_CTX) ++#define EVP_MD_CTX_SIZE sizeof(EVP_MD_CTX) ++#endif ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++ ++int check_openssl_compatibility(); ++ ++#ifdef __cplusplus ++} ++#endif +diff --git a/include/violite.h b/include/violite.h +index 23800696e5a..572d4741c80 100644 +--- a/include/violite.h ++++ b/include/violite.h +@@ -123,13 +123,6 @@ int vio_getnameinfo(const struct sockaddr *sa, + int flags); + + #ifdef HAVE_OPENSSL +-#include <openssl/opensslv.h> +-#if OPENSSL_VERSION_NUMBER < 0x0090700f +-#define DES_cblock des_cblock +-#define DES_key_schedule des_key_schedule +-#define DES_set_key_unchecked(k,ks) des_set_key_unchecked((k),*(ks)) +-#define DES_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e) des_ede3_cbc_encrypt((i),(o),(l),*(k1),*(k2),*(k3),(iv),(e)) +-#endif + /* apple deprecated openssl in MacOSX Lion */ + #ifdef __APPLE__ + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +@@ -146,11 +139,6 @@ typedef my_socket YASSL_SOCKET_T; + #include <openssl/ssl.h> + #include <openssl/err.h> + +-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) +-#define ERR_remove_state(X) +-#elif defined(HAVE_ERR_remove_thread_state) +-#define ERR_remove_state(X) ERR_remove_thread_state(NULL) +-#endif + enum enum_ssl_init_error + { + SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY, +diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl +index 7241d2f2ea9..21dff82736e 100755 +--- a/mysql-test/mysql-test-run.pl ++++ b/mysql-test/mysql-test-run.pl +@@ -2304,7 +2304,7 @@ sub environment_setup { + $ENV{'MYSQL_PLUGIN'}= $exe_mysql_plugin; + $ENV{'MYSQL_EMBEDDED'}= $exe_mysql_embedded; + +- my $client_config_exe= ++ my $client_config_exe= + native_path("$bindir/libmariadb/mariadb_config$opt_vs_config/mariadb_config"); + my $tls_info= `$client_config_exe --tlsinfo`; + ($ENV{CLIENT_TLS_LIBRARY},$ENV{CLIENT_TLS_LIBRARY_VERSION})= +diff --git a/mysql-test/t/openssl_6975.test b/mysql-test/t/openssl_6975.test +index 6cf5d82cf54..6a82d013fb6 100644 +--- a/mysql-test/t/openssl_6975.test ++++ b/mysql-test/t/openssl_6975.test +@@ -19,9 +19,8 @@ let $mysql=$MYSQL --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$ + disable_abort_on_error; + echo TLS1.2 ciphers: user is ok with any cipher; + exec $mysql --ssl-cipher=AES128-SHA256; +---replace_result DHE-RSA-CHACHA20-POLY1305 DHE-RSA-AES256-GCM-SHA384 +---replace_result ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 +-exec $mysql --ssl-cipher=TLSv1.2 ++--replace_result DHE-RSA-CHACHA20-POLY1305 DHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ++exec $mysql --ssl-cipher=TLSv1.2; + echo TLS1.2 ciphers: user requires SSLv3 cipher AES128-SHA; + exec $mysql --user ssl_sslv3 --ssl-cipher=AES128-SHA256; + exec $mysql --user ssl_sslv3 --ssl-cipher=TLSv1.2; +@@ -31,7 +30,7 @@ exec $mysql --user ssl_tls12 --ssl-cipher=TLSv1.2; + + echo SSLv3 ciphers: user is ok with any cipher; + exec $mysql --ssl-cipher=AES256-SHA; +-exec $mysql --ssl-cipher=DHE-RSA-AES256-SHA ++exec $mysql --ssl-cipher=SSLv3; + echo SSLv3 ciphers: user requires SSLv3 cipher AES128-SHA; + exec $mysql --user ssl_sslv3 --ssl-cipher=AES128-SHA; + exec $mysql --user ssl_sslv3 --ssl-cipher=SSLv3; +diff --git a/mysql-test/t/ssl_8k_key.test b/mysql-test/t/ssl_8k_key.test +index 470d577edb8..9d5b382726e 100644 +--- a/mysql-test/t/ssl_8k_key.test ++++ b/mysql-test/t/ssl_8k_key.test +@@ -1,6 +1,5 @@ +-# This test should work in embedded server after we fix mysqltest +--- source include/require_openssl_client.inc +--- source include/not_embedded.inc ++# schannel does not support keys longer than 4k ++-- source include/not_windows.inc + + -- source include/have_ssl_communication.inc + # +diff --git a/mysys_ssl/CMakeLists.txt b/mysys_ssl/CMakeLists.txt +index 4f6f7458c5b..f8a767ed6f3 100644 +--- a/mysys_ssl/CMakeLists.txt ++++ b/mysys_ssl/CMakeLists.txt +@@ -28,6 +28,7 @@ SET(MYSYS_SSL_HIDDEN_SOURCES + my_sha384.cc + my_sha512.cc + my_md5.cc ++ openssl.c + ) + + SET(MYSYS_SSL_SOURCES +diff --git a/mysys_ssl/my_crypt.cc b/mysys_ssl/my_crypt.cc +index 0ff49a2c427..ed1c82dbac6 100644 +--- a/mysys_ssl/my_crypt.cc ++++ b/mysys_ssl/my_crypt.cc +@@ -1,6 +1,6 @@ + /* + Copyright (c) 2014 Google Inc. +- Copyright (c) 2014, 2015 MariaDB Corporation ++ Copyright (c) 2014, 2017 MariaDB Corporation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -21,30 +21,31 @@ + #ifdef HAVE_YASSL + #include "yassl.cc" + #else +- + #include <openssl/evp.h> + #include <openssl/aes.h> + #include <openssl/err.h> + #include <openssl/rand.h> +- + #endif +-#include <my_crypt.h> + +-#define MY_CIPHER_CTX_SIZE 384 ++#include <my_crypt.h> ++#include <ssl_compat.h> + + class MyCTX + { + public: ++ char ctx_buf[EVP_CIPHER_CTX_SIZE]; + EVP_CIPHER_CTX *ctx; +- const uchar *key; +- unsigned int klen; +- MyCTX() { +- ctx= EVP_CIPHER_CTX_new(); +- } +- virtual ~MyCTX() { +- EVP_CIPHER_CTX_free(ctx); +- ERR_remove_state(0); +- } ++ ++ MyCTX() ++ { ++ ctx= (EVP_CIPHER_CTX *)ctx_buf; ++ EVP_CIPHER_CTX_init(ctx); ++ } ++ virtual ~MyCTX() ++ { ++ EVP_CIPHER_CTX_cleanup(ctx); ++ ERR_remove_state(0); ++ } + + virtual int init(const EVP_CIPHER *cipher, int encrypt, const uchar *key, + uint klen, const uchar *iv, uint ivlen) +@@ -78,9 +79,12 @@ class MyCTX + class MyCTX_nopad : public MyCTX + { + public: ++ const uchar *key; ++ uint klen, buf_len; ++ uchar oiv[MY_AES_BLOCK_SIZE]; ++ + MyCTX_nopad() : MyCTX() { } + ~MyCTX_nopad() { } +- unsigned int buf_len; + + int init(const EVP_CIPHER *cipher, int encrypt, const uchar *key, uint klen, + const uchar *iv, uint ivlen) +@@ -89,19 +93,8 @@ class MyCTX_nopad : public MyCTX + this->key= key; + this->klen= klen; + this->buf_len= 0; +- /* FIX-ME: +- For the sake of backward compatibility we do some strange hack here: +- Since ECB doesn't need an IV (and therefore is considered kind of +- insecure) we need to store the specified iv. +- The last nonpadding block will be encrypted with an additional +- expensive crypt_call in ctr mode instead +- of encrypting the entire plain text in ctr-mode */ +-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) +- const unsigned char *oiv= EVP_CIPHER_CTX_original_iv(ctx); +-#else +- const unsigned char *oiv= ctx->oiv; +-#endif +- memcpy((char *)oiv, iv, ivlen); ++ memcpy(oiv, iv, ivlen); ++ DBUG_ASSERT(ivlen == 0 || ivlen == sizeof(oiv)); + + int res= MyCTX::init(cipher, encrypt, key, klen, iv, ivlen); + +@@ -111,34 +104,30 @@ class MyCTX_nopad : public MyCTX + + int update(const uchar *src, uint slen, uchar *dst, uint *dlen) + { +- buf_len= slen % MY_AES_BLOCK_SIZE; ++ buf_len+= slen; + return MyCTX::update(src, slen, dst, dlen); + } + + int finish(uchar *dst, uint *dlen) + { ++ buf_len %= MY_AES_BLOCK_SIZE; + if (buf_len) + { +- const uchar *org_iv; +- unsigned char *buf; ++ uchar *buf= EVP_CIPHER_CTX_buf_noconst(ctx); + /* + Not much we can do, block ciphers cannot encrypt data that aren't + a multiple of the block length. At least not without padding. + Let's do something CTR-like for the last partial block. ++ ++ NOTE this assumes that there are only buf_len bytes in the buf. ++ If OpenSSL will change that, we'll need to change the implementation ++ of this class too. + */ + uchar mask[MY_AES_BLOCK_SIZE]; + uint mlen; + +-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) +- org_iv= EVP_CIPHER_CTX_original_iv(ctx); +- buf= EVP_CIPHER_CTX_buf_noconst(ctx); +-#else +- org_iv= ctx->oiv; +- buf= ctx->buf; +-#endif +- + my_aes_crypt(MY_AES_ECB, ENCRYPTION_FLAG_ENCRYPT | ENCRYPTION_FLAG_NOPAD, +- org_iv, sizeof(mask), mask, &mlen, key, klen, 0, 0); ++ oiv, sizeof(mask), mask, &mlen, key, klen, 0, 0); + DBUG_ASSERT(mlen == sizeof(mask)); + + for (uint i=0; i < buf_len; i++) +@@ -178,9 +167,8 @@ make_aes_dispatcher(gcm) + class MyCTX_gcm : public MyCTX + { + public: +- const uchar *aad= NULL; ++ const uchar *aad; + int aadlen; +- my_bool encrypt; + MyCTX_gcm() : MyCTX() { } + ~MyCTX_gcm() { } + +@@ -192,7 +180,6 @@ class MyCTX_gcm : public MyCTX + int real_ivlen= EVP_CIPHER_CTX_iv_length(ctx); + aad= iv + real_ivlen; + aadlen= ivlen - real_ivlen; +- this->encrypt= encrypt; + return res; + } + +@@ -204,14 +191,14 @@ class MyCTX_gcm : public MyCTX + before decrypting the data. it can encrypt data piecewise, like, first + half, then the second half, but it must decrypt all at once + */ +- if (!this->encrypt) ++ if (!EVP_CIPHER_CTX_encrypting(ctx)) + { + slen-= MY_AES_BLOCK_SIZE; + if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, MY_AES_BLOCK_SIZE, + (void*)(src + slen))) + return MY_AES_OPENSSL_ERROR; + } +- int unused= 0; ++ int unused; + if (aadlen && !EVP_CipherUpdate(ctx, NULL, &unused, aad, aadlen)) + return MY_AES_OPENSSL_ERROR; + aadlen= 0; +@@ -220,12 +207,12 @@ class MyCTX_gcm : public MyCTX + + int finish(uchar *dst, uint *dlen) + { +- int fin= 0; ++ int fin; + if (!EVP_CipherFinal_ex(ctx, dst, &fin)) + return MY_AES_BAD_DATA; + DBUG_ASSERT(fin == 0); + +- if (this->encrypt) ++ if (EVP_CIPHER_CTX_encrypting(ctx)) + { + if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, MY_AES_BLOCK_SIZE, dst)) + return MY_AES_OPENSSL_ERROR; +@@ -295,20 +282,15 @@ int my_aes_crypt(enum my_aes_mode mode, int flags, + { + void *ctx= alloca(MY_AES_CTX_SIZE); + int res1, res2; +- uint d1= 0, d2= 0; ++ uint d1= 0, d2; + if ((res1= my_aes_crypt_init(ctx, mode, flags, key, klen, iv, ivlen))) + return res1; + res1= my_aes_crypt_update(ctx, src, slen, dst, &d1); + res2= my_aes_crypt_finish(ctx, dst + d1, &d2); +- *dlen= d1 + d2; +- /* in case of failure clear error queue */ +-#ifndef HAVE_YASSL +- /* since we don't check the crypto error messages we need to +- clear the error queue - otherwise subsequent crypto or tls/ssl +- calls will fail */ +- if (!*dlen) +- ERR_clear_error(); +-#endif ++ if (res1 || res2) ++ ERR_remove_state(0); /* in case of failure clear error queue */ ++ else ++ *dlen= d1 + d2; + return res1 ? res1 : res2; + } + +@@ -350,12 +332,6 @@ int my_random_bytes(uchar* buf, int num) + + int my_random_bytes(uchar *buf, int num) + { +- /* +- Unfortunately RAND_bytes manual page does not provide any guarantees +- in relation to blocking behavior. Here we explicitly use SSLeay random +- instead of whatever random engine is currently set in OpenSSL. That way +- we are guaranteed to have a non-blocking random. +- */ + RAND_METHOD *rand = RAND_OpenSSL(); + if (rand == NULL || rand->bytes(buf, num) != 1) + return MY_AES_OPENSSL_ERROR; +diff --git a/mysys_ssl/my_md5.cc b/mysys_ssl/my_md5.cc +index 02c01dd7148..0105082b7e1 100644 +--- a/mysys_ssl/my_md5.cc ++++ b/mysys_ssl/my_md5.cc +@@ -1,5 +1,5 @@ + /* Copyright (c) 2012, Oracle and/or its affiliates. +- Copyright (c) 2014, SkySQL Ab. ++ Copyright (c) 2017, MariaDB Corporation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -27,50 +27,34 @@ + #include <my_md5.h> + #include <stdarg.h> + +-#define MA_HASH_CTX_SIZE 512 +- + #if defined(HAVE_YASSL) + #include "md5.hpp" ++#include <ssl_compat.h> + +-typedef TaoCrypt::MD5 MD5_CONTEXT; ++typedef TaoCrypt::MD5 EVP_MD_CTX; + +-static void md5_init(MD5_CONTEXT *context) ++static void md5_init(EVP_MD_CTX *context) + { +- context= new(context) MD5_CONTEXT; ++ context= new(context) EVP_MD_CTX; + context->Init(); + } + +-/* +- this is a variant of md5_init to be used in this file only. +- does nothing for yassl, because the context's constructor was called automatically. +-*/ +-static void md5_init_fast(MD5_CONTEXT *context) +-{ +-} +- +-static void md5_input(MD5_CONTEXT *context, const uchar *buf, unsigned len) ++static void md5_input(EVP_MD_CTX *context, const uchar *buf, unsigned len) + { + context->Update((const TaoCrypt::byte *) buf, len); + } + +-static void md5_result(MD5_CONTEXT *context, uchar digest[MD5_HASH_SIZE]) ++static void md5_result(EVP_MD_CTX *context, uchar digest[MD5_HASH_SIZE]) + { + context->Final((TaoCrypt::byte *) digest); + } + + #elif defined(HAVE_OPENSSL) +- +- + #include <openssl/evp.h> ++#include <ssl_compat.h> + +-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) +-#define EVP_MD_CTX_reset(X) EVP_MD_CTX_cleanup(X) +-#endif +-typedef EVP_MD_CTX MD5_CONTEXT; +- +-static void md5_init(MD5_CONTEXT *context) ++static void md5_init(EVP_MD_CTX *context) + { +- memset(context, 0, my_md5_context_size()); + EVP_MD_CTX_init(context); + #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW + /* Ok to ignore FIPS: MD5 is not used for crypto here */ +@@ -79,20 +63,15 @@ static void md5_init(MD5_CONTEXT *context) + EVP_DigestInit_ex(context, EVP_md5(), NULL); + } + +-static void md5_init_fast(MD5_CONTEXT *context) +-{ +- md5_init(context); +-} +- +-static void md5_input(MD5_CONTEXT *context, const uchar *buf, unsigned len) ++static void md5_input(EVP_MD_CTX *context, const uchar *buf, unsigned len) + { + EVP_DigestUpdate(context, buf, len); + } + +-static void md5_result(MD5_CONTEXT *context, uchar digest[MD5_HASH_SIZE]) ++static void md5_result(EVP_MD_CTX *context, uchar digest[MD5_HASH_SIZE]) + { + EVP_DigestFinal_ex(context, digest, NULL); +- EVP_MD_CTX_reset(context); ++ EVP_MD_CTX_cleanup(context); + } + + #endif /* HAVE_YASSL */ +@@ -108,26 +87,23 @@ static void md5_result(MD5_CONTEXT *context, uchar digest[MD5_HASH_SIZE]) + */ + void my_md5(uchar *digest, const char *buf, size_t len) + { +-#ifdef HAVE_YASSL +- MD5_CONTEXT md5_context; +-#else +- unsigned char md5_context[MA_HASH_CTX_SIZE]; +-#endif +- md5_init_fast((MD5_CONTEXT *)&md5_context); +- md5_input((MD5_CONTEXT *)&md5_context, (const uchar *)buf, len); +- md5_result((MD5_CONTEXT *)&md5_context, digest); ++ char ctx_buf[EVP_MD_CTX_SIZE]; ++ EVP_MD_CTX * const ctx= (EVP_MD_CTX*)ctx_buf; ++ md5_init(ctx); ++ md5_input(ctx, (const uchar *)buf, len); ++ md5_result(ctx, digest); + } + + + /** + Wrapper function to compute MD5 message digest for +- two messages in order to emulate md5(msg1, msg2). ++ many messages, concatenated. + + @param digest [out] Computed MD5 digest + @param buf1 [in] First message + @param len1 [in] Length of first message +- @param buf2 [in] Second message +- @param len2 [in] Length of second message ++ ... ++ @param bufN [in] NULL terminates the list of buf,len pairs. + + @return void + */ +@@ -135,37 +111,34 @@ void my_md5_multi(uchar *digest, ...) + { + va_list args; + const uchar *str; +-#ifdef HAVE_YASSL +- MD5_CONTEXT md5_context; +-#else +- unsigned char md5_context[MA_HASH_CTX_SIZE]; +-#endif ++ char ctx_buf[EVP_MD_CTX_SIZE]; ++ EVP_MD_CTX * const ctx= (EVP_MD_CTX*)ctx_buf; + va_start(args, digest); + +- md5_init_fast((MD5_CONTEXT *)&md5_context); ++ md5_init(ctx); + for (str= va_arg(args, const uchar*); str; str= va_arg(args, const uchar*)) +- md5_input((MD5_CONTEXT *)&md5_context, str, va_arg(args, size_t)); ++ md5_input(ctx, str, va_arg(args, size_t)); + +- md5_result((MD5_CONTEXT *)&md5_context, digest); ++ md5_result(ctx, digest); + va_end(args); + } + + size_t my_md5_context_size() + { +- return MA_HASH_CTX_SIZE; ++ return EVP_MD_CTX_SIZE; + } + + void my_md5_init(void *context) + { +- md5_init((MD5_CONTEXT *)context); ++ md5_init((EVP_MD_CTX *)context); + } + + void my_md5_input(void *context, const uchar *buf, size_t len) + { +- md5_input((MD5_CONTEXT *)context, buf, len); ++ md5_input((EVP_MD_CTX *)context, buf, len); + } + + void my_md5_result(void *context, uchar *digest) + { +- md5_result((MD5_CONTEXT *)context, digest); ++ md5_result((EVP_MD_CTX *)context, digest); + } +diff --git a/mysys_ssl/openssl.c b/mysys_ssl/openssl.c +new file mode 100644 +index 00000000000..a3f1ca29ec1 +--- /dev/null ++++ b/mysys_ssl/openssl.c +@@ -0,0 +1,71 @@ ++/* ++ Copyright (c) 2017, MariaDB Corporation. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; version 2 of the License. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ ++ ++#include <my_global.h> ++#include <ssl_compat.h> ++ ++#ifdef HAVE_YASSL ++ ++int check_openssl_compatibility() ++{ ++ return 0; ++} ++#else ++#include <openssl/evp.h> ++ ++#ifdef HAVE_OPENSSL11 ++typedef void *(*CRYPTO_malloc_t)(size_t, const char *, int); ++#endif ++ ++#ifdef HAVE_OPENSSL10 ++typedef void *(*CRYPTO_malloc_t)(size_t); ++#define CRYPTO_malloc malloc ++#define CRYPTO_realloc realloc ++#define CRYPTO_free free ++#endif ++ ++static uint allocated_size, allocated_count; ++ ++static void *coc_malloc(size_t size) ++{ ++ allocated_size+= size; ++ allocated_count++; ++ return malloc(size); ++} ++ ++int check_openssl_compatibility() ++{ ++ EVP_CIPHER_CTX *evp_ctx; ++ EVP_MD_CTX *md5_ctx; ++ ++ CRYPTO_set_mem_functions((CRYPTO_malloc_t)coc_malloc, CRYPTO_realloc, CRYPTO_free); ++ ++ allocated_size= allocated_count= 0; ++ evp_ctx= EVP_CIPHER_CTX_new(); ++ EVP_CIPHER_CTX_free(evp_ctx); ++ if (allocated_count != 1 || allocated_size > EVP_CIPHER_CTX_SIZE) ++ return 1; ++ ++ allocated_size= allocated_count= 0; ++ md5_ctx= EVP_MD_CTX_create(); ++ EVP_MD_CTX_destroy(md5_ctx); ++ if (allocated_count != 1 || allocated_size > EVP_MD_CTX_SIZE) ++ return 1; ++ ++ CRYPTO_set_mem_functions(CRYPTO_malloc, CRYPTO_realloc, CRYPTO_free); ++ return 0; ++} ++#endif +diff --git a/mysys_ssl/yassl.cc b/mysys_ssl/yassl.cc +index 9e6f90d8d77..aa5631f2ab8 100644 +--- a/mysys_ssl/yassl.cc ++++ b/mysys_ssl/yassl.cc +@@ -24,7 +24,6 @@ + + #include <openssl/ssl.h> + #include "aes.hpp" +-#include <my_sys.h> + + using yaSSL::yaERR_remove_state; + +@@ -45,7 +44,6 @@ typedef struct + int buf_len; + int final_used; + uchar tao_buf[sizeof(TaoCrypt::AES)]; // TaoCrypt::AES object +- uchar oiv[TaoCrypt::AES::BLOCK_SIZE]; // original IV + uchar buf[TaoCrypt::AES::BLOCK_SIZE]; // last partial input block + uchar final[TaoCrypt::AES::BLOCK_SIZE]; // last decrypted (output) block + } EVP_CIPHER_CTX; +@@ -76,26 +74,12 @@ static void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) + ctx->final_used= ctx->buf_len= ctx->flags= 0; + } + +-static EVP_CIPHER_CTX *EVP_CIPHER_CTX_new() +-{ +- EVP_CIPHER_CTX *ctx= (EVP_CIPHER_CTX *)my_malloc(sizeof(EVP_CIPHER_CTX), MYF(0)); +- if (ctx) +- EVP_CIPHER_CTX_init(ctx); +- return ctx; +-} +- + static int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *ctx) + { + TAO(ctx)->~AES(); + return 1; + } + +-static void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) +-{ +- EVP_CIPHER_CTX_cleanup(ctx); +- my_free(ctx); +-} +- + static int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) + { + if (pad) +@@ -112,10 +96,7 @@ static int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + : TaoCrypt::DECRYPTION, cipher->mode); + TAO(ctx)->SetKey(key, cipher->key_len); + if (iv) +- { + TAO(ctx)->SetIV(iv); +- memcpy(ctx->oiv, iv, TaoCrypt::AES::BLOCK_SIZE); +- } + ctx->encrypt= enc; + ctx->key_len= cipher->key_len; + ctx->flags|= cipher->mode == TaoCrypt::CBC ? EVP_CIPH_CBC_MODE : EVP_CIPH_ECB_MODE; +diff --git a/plugin/aws_key_management/CMakeLists.txt b/plugin/aws_key_management/CMakeLists.txt +index 1ad96dd9f19..8ea0452fa6b 100644 +--- a/plugin/aws_key_management/CMakeLists.txt ++++ b/plugin/aws_key_management/CMakeLists.txt +@@ -113,6 +113,16 @@ ELSE() + SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LOCATION ${loc}) + ENDFOREACH() + ++ # To be compatible with older cmake, we use older version of the SDK ++ # We increase the version for macs however, so the newest mac could built it. ++ IF(APPLE) ++ SET(GIT_TAG "1.0.100") ++ ELSEIF(_OPENSSL_VERSION VERSION_EQUAL "1.1") ++ SET(GIT_TAG "1.0.114") ++ ELSE() ++ SET(GIT_TAG "1.0.8") ++ ENDIF() ++ + SET(AWS_SDK_PATCH_COMMAND ) + ExternalProject_Add( + aws_sdk_cpp +diff --git a/sql-common/client.c b/sql-common/client.c +index d881080b55a..eb2899410d4 100644 +--- a/sql-common/client.c ++++ b/sql-common/client.c +@@ -104,11 +104,8 @@ my_bool net_flush(NET *net); + #define CONNECT_TIMEOUT 0 + #endif + +-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) || defined(HAVE_YASSL) +-#define ASN1_STRING_get0_data(X) ASN1_STRING_data(X) +-#endif +- + #include "client_settings.h" ++#include <ssl_compat.h> + #include <sql_common.h> + #include <mysql/client_plugin.h> + #include <my_context.h> +@@ -1772,9 +1769,8 @@ mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused))) + + #if defined(HAVE_OPENSSL) + +-#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(HAVE_YASSL) ++#ifdef HAVE_X509_check_host + #include <openssl/x509v3.h> +-#define HAVE_X509_check_host + #endif + + static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const char **errptr) +diff --git a/sql/mysqld.cc b/sql/mysqld.cc +index d6a7c6b4931..904695d8742 100644 +--- a/sql/mysqld.cc ++++ b/sql/mysqld.cc +@@ -111,7 +111,6 @@ + #endif + + #include <my_systemd.h> +-#include <my_crypt.h> + + #define mysqld_charset &my_charset_latin1 + +@@ -121,7 +120,6 @@ + #define HAVE_CLOSE_SERVER_SOCK 1 + #endif + +- + extern "C" { // Because of SCO 3.2V4.2 + #include <sys/stat.h> + #ifndef __GNU_LIBRARY__ +@@ -339,9 +337,13 @@ static PSI_thread_key key_thread_handle_con_sockets; + static PSI_thread_key key_thread_handle_shutdown; + #endif /* __WIN__ */ + +-#if defined (HAVE_OPENSSL) && !defined(HAVE_YASSL) ++#ifdef HAVE_OPENSSL ++#include <ssl_compat.h> ++ ++#ifdef HAVE_OPENSSL10 + static PSI_rwlock_key key_rwlock_openssl; + #endif ++#endif + #endif /* HAVE_PSI_INTERFACE */ + + #ifdef HAVE_NPTL +@@ -987,7 +989,7 @@ PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger, + + static PSI_rwlock_info all_server_rwlocks[]= + { +-#if defined (HAVE_OPENSSL) && !defined(HAVE_YASSL) ++#ifdef HAVE_OPENSSL10 + { &key_rwlock_openssl, "CRYPTO_dynlock_value::lock", 0}, + #endif + { &key_rwlock_LOCK_grant, "LOCK_grant", PSI_FLAG_GLOBAL}, +@@ -1457,9 +1459,7 @@ scheduler_functions *thread_scheduler= &thread_scheduler_struct, + + #ifdef HAVE_OPENSSL + #include <openssl/crypto.h> +-#ifndef HAVE_YASSL +- +-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++#ifdef HAVE_OPENSSL10 + typedef struct CRYPTO_dynlock_value + { + mysql_rwlock_t lock; +@@ -1470,8 +1470,7 @@ static openssl_lock_t *openssl_dynlock_create(const char *, int); + static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int); + static void openssl_lock_function(int, int, const char *, int); + static void openssl_lock(int, openssl_lock_t *, const char *, int); +-#endif +-#endif ++#endif /* HAVE_OPENSSL10 */ + char *des_key_file; + #ifndef EMBEDDED_LIBRARY + struct st_VioSSLFd *ssl_acceptor_fd; +@@ -2247,13 +2246,11 @@ static void clean_up_mutexes() + mysql_mutex_destroy(&LOCK_global_index_stats); + #ifdef HAVE_OPENSSL + mysql_mutex_destroy(&LOCK_des_key_file); +-#ifndef HAVE_YASSL +-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++#ifdef HAVE_OPENSSL10 + for (int i= 0; i < CRYPTO_num_locks(); ++i) + mysql_rwlock_destroy(&openssl_stdlocks[i].lock); + OPENSSL_free(openssl_stdlocks); +-#endif +-#endif /* HAVE_YASSL */ ++#endif /* HAVE_OPENSSL10 */ + #endif /* HAVE_OPENSSL */ + #ifdef HAVE_REPLICATION + mysql_mutex_destroy(&LOCK_rpl_status); +@@ -4055,6 +4052,14 @@ static int init_common_variables() + return 1; + } + ++#ifdef HAVE_OPENSSL ++ if (check_openssl_compatibility()) ++ { ++ sql_print_error("Incompatible OpenSSL version. Cannot continue..."); ++ return 1; ++ } ++#endif ++ + if (init_thread_environment() || + mysql_init_variables()) + return 1; +@@ -4601,8 +4606,7 @@ static int init_thread_environment() + #ifdef HAVE_OPENSSL + mysql_mutex_init(key_LOCK_des_key_file, + &LOCK_des_key_file, MY_MUTEX_INIT_FAST); +-#ifndef HAVE_YASSL +-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++#ifdef HAVE_OPENSSL10 + openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() * + sizeof(openssl_lock_t)); + for (int i= 0; i < CRYPTO_num_locks(); ++i) +@@ -4611,9 +4615,8 @@ static int init_thread_environment() + CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy); + CRYPTO_set_dynlock_lock_callback(openssl_lock); + CRYPTO_set_locking_callback(openssl_lock_function); +-#endif +-#endif +-#endif ++#endif /* HAVE_OPENSSL10 */ ++#endif /* HAVE_OPENSSL */ + mysql_rwlock_init(key_rwlock_LOCK_sys_init_connect, &LOCK_sys_init_connect); + mysql_rwlock_init(key_rwlock_LOCK_sys_init_slave, &LOCK_sys_init_slave); + mysql_rwlock_init(key_rwlock_LOCK_grant, &LOCK_grant); +@@ -4646,8 +4649,7 @@ static int init_thread_environment() + } + + +-#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL) +-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++#ifdef HAVE_OPENSSL10 + static openssl_lock_t *openssl_dynlock_create(const char *file, int line) + { + openssl_lock_t *lock= new openssl_lock_t; +@@ -4707,9 +4709,7 @@ static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, + abort(); + } + } +-#endif +-#endif /* HAVE_OPENSSL */ +- ++#endif /* HAVE_OPENSSL10 */ + + static void init_ssl() + { +@@ -4737,9 +4737,8 @@ static void init_ssl() + while ((err= ERR_get_error())) + sql_print_warning("SSL error: %s", ERR_error_string(err, NULL)); + } +- else { ++ else + ERR_remove_state(0); +- } + } + else + { +diff --git a/sql/slave.cc b/sql/slave.cc +index 636965c4619..6882156564c 100644 +--- a/sql/slave.cc ++++ b/sql/slave.cc +@@ -40,6 +40,7 @@ + #include <my_dir.h> + #include <sql_common.h> + #include <errmsg.h> ++#include <ssl_compat.h> + #include <mysqld_error.h> + #include <mysys_err.h> + #include "rpl_handler.h" +@@ -60,12 +61,6 @@ + #include "debug_sync.h" + #include "rpl_parallel.h" + +-#if OPENSSL_VERSION_NUMBER >= 0x10100000L +-#define ERR_remove_state(X) +-#elif defined(HAVE_ERR_remove_thread_state) +-#define ERR_remove_state(X) ERR_remove_thread_state(NULL) +-#endif +- + #define FLAGSTR(V,F) ((V)&(F)?#F" ":"") + + #define MAX_SLAVE_RETRY_PAUSE 5 +@@ -4509,13 +4504,7 @@ log space"); + + DBUG_LEAVE; // Must match DBUG_ENTER() + my_thread_end(); +-#ifdef HAVE_OPENSSL +-#if OPENSSL_VERSION_NUMBER < 0x10000000L + ERR_remove_state(0); +-#elif OPENSSL_VERSION_NUMBER < 0x10100000L +- ERR_remove_thread_state(0); +-#endif +-#endif + pthread_exit(0); + return 0; // Avoid compiler warnings + } +@@ -5174,13 +5163,7 @@ pthread_handler_t handle_slave_sql(void *arg) + + DBUG_LEAVE; // Must match DBUG_ENTER() + my_thread_end(); +-#ifdef HAVE_OPENSSL +-#if OPENSSL_VERSION_NUMBER < 0x10000000L + ERR_remove_state(0); +-#elif OPENSSL_VERSION_NUMBER < 0x10100000L +- ERR_remove_thread_state(0); +-#endif +-#endif + pthread_exit(0); + return 0; // Avoid compiler warnings + } +diff --git a/vio/vio.c b/vio/vio.c +index e3bc8ca8ab8..44d06092184 100644 +--- a/vio/vio.c ++++ b/vio/vio.c +@@ -22,6 +22,7 @@ + */ + + #include "vio_priv.h" ++#include "ssl_compat.h" + + #ifdef _WIN32 + +diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c +index 497047cac72..71ef2879464 100644 +--- a/vio/viosslfactories.c ++++ b/vio/viosslfactories.c +@@ -15,20 +15,12 @@ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + + #include "vio_priv.h" ++#include <ssl_compat.h> + + #ifdef HAVE_OPENSSL +-#if defined(HAVE_YASSL) || defined(LIBRESSL_VERSION_NUMBER) +-#define OPENSSL_init_ssl(X,Y) SSL_library_init() +-#else ++#ifndef HAVE_YASSL + #include <openssl/dh.h> + #include <openssl/bn.h> +- +-#if OPENSSL_VERSION_NUMBER >= 0x10100000L +-#define ERR_remove_state(X) +-#else +-#define OPENSSL_init_ssl(X,Y) SSL_library_init() +-#endif +- + #endif + + static my_bool ssl_algorithms_added = FALSE; +@@ -36,59 +28,51 @@ static my_bool ssl_error_strings_loaded= FALSE; + + /* the function below was generated with "openssl dhparam -2 -C 2048" */ + +-/* {{{ get_dh_2048 */ +-static DH *get_dh_2048() ++static ++DH *get_dh2048() + { +- static unsigned char dh2048_p[]={ +- 0xA1,0xBB,0x7C,0x20,0xC5,0x5B,0xC0,0x7B,0x21,0x8B,0xD6,0xA8, +- 0x15,0xFC,0x3B,0xBA,0xAB,0x9F,0xDF,0x68,0xC4,0x79,0x78,0x0D, +- 0xC1,0x12,0x64,0xE4,0x15,0xC9,0x66,0xDB,0xF6,0xCB,0xB3,0x39, +- 0x02,0x5B,0x78,0x62,0xFB,0x09,0xAE,0x09,0x6B,0xDD,0xD4,0x5D, +- 0x97,0xBC,0xDC,0x7F,0xE6,0xD6,0xF1,0xCB,0xF5,0xEB,0xDA,0xA7, +- 0x2E,0x5A,0x43,0x2B,0xE9,0x40,0xE2,0x85,0x00,0x1C,0xC0,0x0A, +- 0x98,0x77,0xA9,0x31,0xDE,0x0B,0x75,0x4D,0x1E,0x1F,0x16,0x83, +- 0xCA,0xDE,0xBD,0x21,0xFC,0xC1,0x82,0x37,0x36,0x33,0x0B,0x66, +- 0x06,0x3C,0xF3,0xAF,0x21,0x57,0x57,0x80,0xF6,0x94,0x1B,0xA9, +- 0xD4,0xF6,0x8F,0x18,0x62,0x0E,0xC4,0x22,0xF9,0x5B,0x62,0xCC, +- 0x3F,0x19,0x95,0xCF,0x4B,0x00,0xA6,0x6C,0x0B,0xAF,0x9F,0xD5, +- 0xFA,0x3D,0x6D,0xDA,0x30,0x83,0x07,0x91,0xAC,0x15,0xFF,0x8F, +- 0x59,0x54,0xEA,0x25,0xBC,0x4E,0xEB,0x6A,0x54,0xDF,0x75,0x09, +- 0x72,0x0F,0xEF,0x23,0x70,0xE0,0xA8,0x04,0xEA,0xFF,0x90,0x54, +- 0xCD,0x84,0x18,0xC0,0x75,0x91,0x99,0x0F,0xA1,0x78,0x0C,0x07, +- 0xB7,0xC5,0xDE,0x55,0x06,0x7B,0x95,0x68,0x2C,0x33,0x39,0xBC, +- 0x2C,0xD0,0x6D,0xDD,0xFA,0xDC,0xB5,0x8F,0x82,0x39,0xF8,0x67, +- 0x44,0xF1,0xD8,0xF7,0x78,0x11,0x9A,0x77,0x9B,0x53,0x47,0xD6, +- 0x2B,0x5D,0x67,0xB8,0xB7,0xBC,0xC1,0xD7,0x79,0x62,0x15,0xC2, +- 0xC5,0x83,0x97,0xA7,0xF8,0xB4,0x9C,0xF6,0x8F,0x9A,0xC7,0xDA, +- 0x1B,0xBB,0x87,0x07,0xA7,0x71,0xAD,0xB2,0x8A,0x50,0xF8,0x26, +- 0x12,0xB7,0x3E,0x0B, +- }; +- static unsigned char dh2048_g[]={ +- 0x02, +- }; +- DH *dh; +- if ((dh=DH_new()) == NULL) +- return(NULL); +-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) +- (dh)->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL); +- (dh)->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL); +- if ((dh)->p == NULL || (dh)->g == NULL) +- { DH_free(dh); return NULL; } +-#else +- { +- BIGNUM *dhp_bn= BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL), +- *dhg_bn= BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL); +- if (dhp_bn == NULL || dhg_bn == NULL || +- !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) +- { +- DH_free(dh); +- BN_free(dhp_bn); +- BN_free(dhg_bn); +- return NULL; ++ static unsigned char dhp_2048[] = { ++ 0xA1,0xBB,0x7C,0x20,0xC5,0x5B,0xC0,0x7B,0x21,0x8B,0xD6,0xA8, ++ 0x15,0xFC,0x3B,0xBA,0xAB,0x9F,0xDF,0x68,0xC4,0x79,0x78,0x0D, ++ 0xC1,0x12,0x64,0xE4,0x15,0xC9,0x66,0xDB,0xF6,0xCB,0xB3,0x39, ++ 0x02,0x5B,0x78,0x62,0xFB,0x09,0xAE,0x09,0x6B,0xDD,0xD4,0x5D, ++ 0x97,0xBC,0xDC,0x7F,0xE6,0xD6,0xF1,0xCB,0xF5,0xEB,0xDA,0xA7, ++ 0x2E,0x5A,0x43,0x2B,0xE9,0x40,0xE2,0x85,0x00,0x1C,0xC0,0x0A, ++ 0x98,0x77,0xA9,0x31,0xDE,0x0B,0x75,0x4D,0x1E,0x1F,0x16,0x83, ++ 0xCA,0xDE,0xBD,0x21,0xFC,0xC1,0x82,0x37,0x36,0x33,0x0B,0x66, ++ 0x06,0x3C,0xF3,0xAF,0x21,0x57,0x57,0x80,0xF6,0x94,0x1B,0xA9, ++ 0xD4,0xF6,0x8F,0x18,0x62,0x0E,0xC4,0x22,0xF9,0x5B,0x62,0xCC, ++ 0x3F,0x19,0x95,0xCF,0x4B,0x00,0xA6,0x6C,0x0B,0xAF,0x9F,0xD5, ++ 0xFA,0x3D,0x6D,0xDA,0x30,0x83,0x07,0x91,0xAC,0x15,0xFF,0x8F, ++ 0x59,0x54,0xEA,0x25,0xBC,0x4E,0xEB,0x6A,0x54,0xDF,0x75,0x09, ++ 0x72,0x0F,0xEF,0x23,0x70,0xE0,0xA8,0x04,0xEA,0xFF,0x90,0x54, ++ 0xCD,0x84,0x18,0xC0,0x75,0x91,0x99,0x0F,0xA1,0x78,0x0C,0x07, ++ 0xB7,0xC5,0xDE,0x55,0x06,0x7B,0x95,0x68,0x2C,0x33,0x39,0xBC, ++ 0x2C,0xD0,0x6D,0xDD,0xFA,0xDC,0xB5,0x8F,0x82,0x39,0xF8,0x67, ++ 0x44,0xF1,0xD8,0xF7,0x78,0x11,0x9A,0x77,0x9B,0x53,0x47,0xD6, ++ 0x2B,0x5D,0x67,0xB8,0xB7,0xBC,0xC1,0xD7,0x79,0x62,0x15,0xC2, ++ 0xC5,0x83,0x97,0xA7,0xF8,0xB4,0x9C,0xF6,0x8F,0x9A,0xC7,0xDA, ++ 0x1B,0xBB,0x87,0x07,0xA7,0x71,0xAD,0xB2,0x8A,0x50,0xF8,0x26, ++ 0x12,0xB7,0x3E,0x0B, ++ }; ++ static unsigned char dhg_2048[] = { ++ 0x02 ++ }; ++ DH *dh = DH_new(); ++ BIGNUM *dhp_bn, *dhg_bn; ++ ++ if (dh == NULL) ++ return NULL; ++ dhp_bn = BN_bin2bn(dhp_2048, sizeof (dhp_2048), NULL); ++ dhg_bn = BN_bin2bn(dhg_2048, sizeof (dhg_2048), NULL); ++ if (dhp_bn == NULL || dhg_bn == NULL ++ || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) { ++ DH_free(dh); ++ BN_free(dhp_bn); ++ BN_free(dhg_bn); ++ return NULL; + } +- } +-#endif +- return dh; ++ return dh; + } + + static const char* +@@ -287,7 +271,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, + /* DH stuff */ + if (!is_client_method) + { +- dh=get_dh_2048(); ++ dh=get_dh2048(); + if (!SSL_CTX_set_tmp_dh(ssl_fd->ssl_context, dh)) + { + *error= SSL_INITERR_DH; diff --git a/extra/mariadb/PKGBUILD b/extra/mariadb/PKGBUILD index 54592775d..77ba25c71 100644 --- a/extra/mariadb/PKGBUILD +++ b/extra/mariadb/PKGBUILD @@ -9,34 +9,35 @@ pkgbase=mariadb pkgname=('libmariadbclient' 'mariadb-clients' 'mytop' 'mariadb') pkgver=10.1.23 _pkgver=${pkgver/.a/a} -pkgrel=1 +pkgrel=2 arch=('i686' 'x86_64') license=('GPL') url='http://mariadb.org/' -makedepends=('cmake' 'zlib' 'libaio' 'libxml2' 'pcre' 'jemalloc' +makedepends=('cmake' 'zlib' 'libaio' 'libxml2' 'openssl' 'pcre' 'jemalloc' 'lz4' 'boost' 'libevent' 'systemd') validpgpkeys=('199369E5404BD5FC7D2FE43BCBCB082A1BB943DB') # MariaDB Package Signing Key <package-signing-key@mariadb.org> -source=(https://ftp.heanet.ie/mirrors/mariadb/mariadb-$pkgver/source/mariadb-$pkgver.tar.gz{,.asc} - mariadb-sysusers.conf - mariadb-tmpfile.conf) +source=("https://ftp.heanet.ie/mirrors/mariadb/mariadb-$pkgver/source/mariadb-$pkgver.tar.gz"{,.asc} + '0001-openssl-1-1-0.patch' + 'mariadb-sysusers.conf' + 'mariadb-tmpfile.conf') sha256sums=('54d8114e24bfa5e3ebdc7d69e071ad1471912847ea481b227d204f9d644300bf' 'SKIP' + 'f337505ce421aea82693ab95372ce93fde3ea0351e0b6b78c26c9e1154df174c' 'e1a22777c65854041f16fc0a2db3218d17b4d7e7ec7ab7a77cf49c71277c1515' '2af318c52ae0fe5428e8a9245d1b0fc3bc5ce153842d1563329ceb1edfa83ddd') -# This ships with bundled SSL library until proper support for openssl 1.1.0 -# is available. -# TODO: Switch back to system openssl -# -> add 'openssl' to dependencies -# -> switch to '-DWITH_SSL=system' in cmake command - prepare() { + cd $pkgbase-$_pkgver/ + # Changes to the upstream unit files: # * remove the alias from unit files, we install symlinks in package function # * enable PrivateTmp for a little bit more security sed -i -e '/^Alias/d' \ -e '/^PrivateTmp/c PrivateTmp=true' \ - $pkgbase-$_pkgver/support-files/mariadb{,@}.service.in + support-files/mariadb{,@}.service.in + + # openssl 1.1.0 + patch -Np1 < "${srcdir}"/0001-openssl-1-1-0.patch } build() { @@ -68,7 +69,7 @@ build() { -DWITH_SYSTEMD=yes \ -DWITH_READLINE=ON \ -DWITH_ZLIB=system \ - -DWITH_SSL=bundled \ + -DWITH_SSL=system \ -DWITH_PCRE=system \ -DWITH_LIBWRAP=OFF \ -DWITH_JEMALLOC=ON \