summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Richter <georg@mariadb.com>2021-07-04 13:49:41 +0200
committerGeorg Richter <georg@mariadb.com>2021-07-05 08:14:52 +0200
commitde02d91fed7f7290885dd22e20de4b3f78000b02 (patch)
tree0478551017622b74059bd477d8b0dc5ee138b725
parent83684fc9a4d81f15fee1888123cc7f7a4e298c4f (diff)
downloadmariadb-git-bb-10.6-MDEV-26049.tar.gz
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.result10
-rw-r--r--mysql-test/main/MDEV-26049.test26
-rw-r--r--mysql-test/main/ssl_cipher.result2
-rw-r--r--mysql-test/main/ssl_cipher.test8
-rwxr-xr-x[-rw-r--r--]sql/mysqld.cc35
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},