diff options
author | Georg Richter <georg@mariadb.com> | 2021-07-04 13:49:41 +0200 |
---|---|---|
committer | Georg Richter <georg@mariadb.com> | 2021-07-05 08:14:52 +0200 |
commit | de02d91fed7f7290885dd22e20de4b3f78000b02 (patch) | |
tree | 0478551017622b74059bd477d8b0dc5ee138b725 | |
parent | 83684fc9a4d81f15fee1888123cc7f7a4e298c4f (diff) | |
download | mariadb-git-bb-10.6-MDEV-26049.tar.gz |
MDEV-26049bb-10.6-MDEV-26049
1. In the previous implementation the status variable 'Ssl_cipher_list'
returned the built-in cipher suites for OpenSSL and (which is wrong)
for WolfSSL the current cipher in use. This patch displays all supported
cipher suites for WolfSSL and doesn't require a secure connection anymore.
2. A new status variable 'Ssl_shared_ciphers' was added which returns
the cipher suites supported from both client and server considering TLS
protocol version. This feature is fully supported by OpenSSL only, while
WolfSSL supports this feature via OpenSSL compatibility layer it returns
only the cipher suite used by current connection.
3. Fixed ssl_cipher test:
Also allow testing against OpenSSL by limiting the TLS version to
TLSv1.1 and 1.2.
-rw-r--r-- | mysql-test/main/MDEV-26049.result | 10 | ||||
-rw-r--r-- | mysql-test/main/MDEV-26049.test | 26 | ||||
-rw-r--r-- | mysql-test/main/ssl_cipher.result | 2 | ||||
-rw-r--r-- | mysql-test/main/ssl_cipher.test | 8 | ||||
-rwxr-xr-x[-rw-r--r--] | sql/mysqld.cc | 35 |
5 files changed, 73 insertions, 8 deletions
diff --git a/mysql-test/main/MDEV-26049.result b/mysql-test/main/MDEV-26049.result new file mode 100644 index 00000000000..a8d738f453f --- /dev/null +++ b/mysql-test/main/MDEV-26049.result @@ -0,0 +1,10 @@ +TRUE_EXPECTED +1 +TRUE_EXPECTED +1 +FALSE_EXPECTED +0 +TRUE_EXPECTED +1 +FALSE_EXPECTED +0 diff --git a/mysql-test/main/MDEV-26049.test b/mysql-test/main/MDEV-26049.test new file mode 100644 index 00000000000..d68da6c794c --- /dev/null +++ b/mysql-test/main/MDEV-26049.test @@ -0,0 +1,26 @@ +# Tests for SSL connections, only run if mysqld is compiled +# with support for SSL. + +-- source include/have_ssl_communication.inc + +# Make sure WolfSSL doesn't return cipher in use only for ssl_cipher_list. +# ssl_cipher_list shouldn't be empty for non secure connections. +--exec $MYSQL -e"select count(*) AS TRUE_EXPECTED from information_schema.session_status where variable_name = 'SSL_CIPHER_LIST' and locate(':', variable_value) > 0" + + +# Note: WolfSSL does support SSL_get_shared_ciphers via OpenSSL compatibility layer, however +# it returns only the cipher in use. Therefore we bypass when testing against WolfSSL by checking +# if there is only one cipher suite returned (locate(':', variable_value) = 0) + +# check shared ciphers for TLSv1.1: They should contain a valid cipher <= TLSc1.1, but no TLSv1.2 ciphers +--exec $MYSQL --ssl --tls_version=TLSv1.1 -e "SELECT count(*) as TRUE_EXPECTED from information_schema.session_status where variable_name='SSL_SHARED_CIPHERS' and (locate('AES256-SHA', variable_value) > 0 OR /* WolfSSL */ locate(':', variable_value)=0)" + +# check that a TLSv1.2 cipher isn't in list of TLSv1 ciphers +--exec $MYSQL --ssl --tls_version=TLSv1.1 -e "SELECT count(*) AS FALSE_EXPECTED from information_schema.session_status where variable_name='SSL_SHARED_CIPHERS' and locate('AES256-SHA256', variable_value) > 0" + +# check that TLSv1.2 contain AES256-SHA256 (TLSv1.2 cipher) +--exec $MYSQL --ssl --tls_version=TLSv1.2 -e "SELECT count(*) AS TRUE_EXPECTED from information_schema.session_status where variable_name='SSL_SHARED_CIPHERS' and (locate('AES256-SHA256', variable_value) > 0 OR /* WolfSSL */ locate(':', variable_value)=0)" + +# check that TLSv1.2 contains no TLSv1.3 cipher +--exec $MYSQL --ssl --tls_version=TLSv1.2 -e "SELECT count(*) AS FALSE_EXPECTED from information_schema.session_status where variable_name='SSL_SHARED_CIPHERS' and locate('TLS_AES_256_GCM_SHA384', variable_value) > 0" + diff --git a/mysql-test/main/ssl_cipher.result b/mysql-test/main/ssl_cipher.result index 930d384eda9..2728014b219 100644 --- a/mysql-test/main/ssl_cipher.result +++ b/mysql-test/main/ssl_cipher.result @@ -61,7 +61,7 @@ connect ssl_con,localhost,root,,,,,SSL; SHOW STATUS LIKE 'Ssl_cipher'; Variable_name Value Ssl_cipher AES128-SHA -SHOW STATUS LIKE 'Ssl_cipher_list'; +SELECT 'Ssl_cipher_list' as Variable_name, 'AES128-SHA' as Value from information_schema.session_status where variable_name='SSL_CIPHER_LIST' and locate('AES128-SHA', variable_value) > 0; Variable_name Value Ssl_cipher_list AES128-SHA disconnect ssl_con; diff --git a/mysql-test/main/ssl_cipher.test b/mysql-test/main/ssl_cipher.test index 36549d76d02..f9385e21c85 100644 --- a/mysql-test/main/ssl_cipher.test +++ b/mysql-test/main/ssl_cipher.test @@ -4,9 +4,9 @@ # --source include/have_ssl_communication.inc -if (`select @@version_ssl_library like 'OpenSSL 1.1.1%'`) { - skip OpenSSL 1.1.1; -} +#if (`select @@version_ssl_library like 'OpenSSL 1.1.1%'`) { +# skip OpenSSL 1.1.1; +#} create user ssl_user1@localhost require SSL; create user ssl_user2@localhost require cipher 'AES256-SHA'; @@ -98,6 +98,6 @@ let $restart_parameters=--ssl-cipher=AES128-SHA; source include/restart_mysqld.inc; connect (ssl_con,localhost,root,,,,,SSL); SHOW STATUS LIKE 'Ssl_cipher'; -SHOW STATUS LIKE 'Ssl_cipher_list'; +SELECT 'Ssl_cipher_list' as Variable_name, 'AES128-SHA' as Value from information_schema.session_status where variable_name='SSL_CIPHER_LIST' and locate('AES128-SHA', variable_value) > 0; disconnect ssl_con; connection default; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 698bcfff0f7..f0ec88f2a39 100644..100755 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6919,17 +6919,42 @@ static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff, return 0; } +static int show_ssl_get_shared_ciphers(THD *thd, SHOW_VAR *var, char *buff, + enum enum_var_type scope) +{ + var->type= SHOW_CHAR; + var->value= buff; + + if (thd->vio_ok() && thd->net.vio->ssl_arg) + { + char *end= buff + SHOW_VAR_FUNC_BUFF_SIZE; + memset(buff, 0, end - buff); + if (SSL_get_shared_ciphers((SSL *)thd->net.vio->ssl_arg, buff, (int)(end - buff - 1))) + buff+= strlen(buff); + } + *buff=0; + return 0; +} + static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff, enum enum_var_type scope) { var->type= SHOW_CHAR; var->value= buff; - if (thd->vio_ok() && thd->net.vio->ssl_arg) + + char *end= buff + SHOW_VAR_FUNC_BUFF_SIZE; + memset(buff, 0, end - buff); +#ifdef HAVE_WOLFSSL + if (wolfSSL_get_ciphers(buff, (int)(end - buff - 1)) == SSL_SUCCESS) + buff+= strlen(buff); +#else { int i; const char *p; - char *end= buff + SHOW_VAR_FUNC_BUFF_SIZE; - for (i=0; (p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i)) && + SSL *ssl= thd->net.vio->ssl_arg ? + (SSL *)thd->net.vio->ssl_arg : SSL_new(ssl_acceptor_fd->ssl_context); + + for (i=0; (p= SSL_get_cipher_list(ssl,i)) && buff < end; i++) { buff= strnmov(buff, p, end-buff-1); @@ -6937,7 +6962,10 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff, } if (i) buff--; + if (!thd->net.vio->ssl_arg) + SSL_free(ssl); } +#endif *buff=0; return 0; } @@ -7384,6 +7412,7 @@ SHOW_VAR status_vars[]= { {"Ssl_session_cache_size", (char*) &ssl_acceptor_stats.cache_size, SHOW_LONG}, {"Ssl_session_cache_timeouts", (char*) &ssl_acceptor_stats.zero, SHOW_LONG}, {"Ssl_sessions_reused", (char*) &ssl_acceptor_stats.zero, SHOW_LONG}, + {"Ssl_shared_ciphers", (char*) &show_ssl_get_shared_ciphers, SHOW_SIMPLE_FUNC}, {"Ssl_used_session_cache_entries",(char*) &ssl_acceptor_stats.zero, SHOW_LONG}, {"Ssl_verify_depth", (char*) &show_ssl_get_verify_depth, SHOW_SIMPLE_FUNC}, {"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_SIMPLE_FUNC}, |