Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/violite.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ struct st_VioSSLFd
const char *ca_file,const char *ca_path,
const char *cipher, enum enum_ssl_init_error *error,
const char *crl_file, const char *crl_path,
ulonglong tls_version, const char *passphrase);
ulonglong tls_version, const char *passphrase,
const char **alt_key_files, const char **alt_cert_files,
uint alt_cert_count);
void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd);
#endif /* HAVE_OPENSSL */

Expand Down
12 changes: 12 additions & 0 deletions mysql-test/lib/generate-ssl-certs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ cp -v client-cert.crl crldir/`openssl x509 -in client-cert.pem -noout -issuer_ha

rm -rf demoCA

# ECDSA server certificate signed by test CA
openssl ecparam -genkey -name prime256v1 -out server-ecdsa-key.pem
openssl req -new -key server-ecdsa-key.pem -out server-ecdsa.csr -subj '/CN=localhost' -batch
openssl x509 -req -in server-ecdsa.csr -CA cacert.pem -CAkey cakey.pem -CAcreateserial -out server-ecdsa-cert.pem -days 7300
rm -f server-ecdsa.csr

# EdDSA (Ed25519) server certificate signed by test CA
openssl genpkey -algorithm Ed25519 -out server-eddsa-key.pem
openssl req -new -key server-eddsa-key.pem -out server-eddsa.csr -subj '/CN=localhost' -batch
openssl x509 -req -in server-eddsa.csr -CA cacert.pem -CAkey cakey.pem -CAcreateserial -out server-eddsa-cert.pem -days 7300
rm -f server-eddsa.csr cacert.srl

# --- Certificate Chain ---
# These tests are inspired from the following commit from MySQL Server
# https://github.com/mysql/mysql-server/commit/969afef933f1872c5f38ea93047ef05c4509c335
Expand Down
2 changes: 2 additions & 0 deletions mysql-test/main/ssl.result
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ variable_name
Ssl_cipher
Ssl_cipher_list
Ssl_default_timeout
Ssl_server_cert_type
Ssl_server_not_after
Ssl_server_not_before
Ssl_verify_depth
Expand All @@ -12,6 +13,7 @@ Ssl_version
Ssl_cipher
Ssl_cipher_list
Ssl_default_timeout
Ssl_server_cert_type
Ssl_server_not_after
Ssl_server_not_before
Ssl_verify_depth
Expand Down
66 changes: 66 additions & 0 deletions mysql-test/main/ssl_multi_cert.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#
# Restart server with RSA (primary), ECDSA and EdDSA certs
#
# Kill the server
# restart: --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-eddsa-cert.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-eddsa-key.pem --tls-version=TLSv1.2
#
# Verify Ssl_server_cert_types global status shows all three types
#
SHOW GLOBAL STATUS LIKE 'Ssl_server_cert_types';
Variable_name Value
Ssl_server_cert_types RSA, ECDSA, EdDSA
#
# Test 1: Connect with RSA cipher - should get RSA cert
#
connect rsa_con,localhost,root,,,,,SSL-CIPHER=ECDHE-RSA-AES128-GCM-SHA256;
SHOW STATUS LIKE 'Ssl_cipher';
Variable_name Value
Ssl_cipher ECDHE-RSA-AES128-GCM-SHA256
SHOW STATUS LIKE 'Ssl_server_cert_type';
Variable_name Value
Ssl_server_cert_type RSA
disconnect rsa_con;
#
# Test 2: Connect with ECDSA cipher - should get ECDSA cert
#
connection default;
connect ecdsa_con,localhost,root,,,,,SSL-CIPHER=ECDHE-ECDSA-AES128-GCM-SHA256;
SHOW STATUS LIKE 'Ssl_cipher';
Variable_name Value
Ssl_cipher ECDHE-ECDSA-AES128-GCM-SHA256
SHOW STATUS LIKE 'Ssl_server_cert_type';
Variable_name Value
Ssl_server_cert_type ECDSA
disconnect ecdsa_con;
#
# Test 3: Connect with default ciphers - should succeed
#
connection default;
connect default_con,localhost,root,,,,,SSL;
SELECT (VARIABLE_VALUE <> '') AS have_ssl FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_cipher';
have_ssl
1
disconnect default_con;
connection default;
#
# Test 4: TLS 1.3 with all three cert types (EdDSA requires TLS 1.3)
#
connection default;
# Kill the server
# restart: --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-eddsa-cert.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-eddsa-key.pem --tls-version=TLSv1.3
SHOW GLOBAL STATUS LIKE 'Ssl_server_cert_types';
Variable_name Value
Ssl_server_cert_types RSA, ECDSA, EdDSA
connect tls13_con,localhost,root,,,,,SSL;
# TLS 1.3 connection should use one of the loaded cert types
Ssl_server_cert_type is valid: OK
SHOW STATUS LIKE 'Ssl_version';
Variable_name Value
Ssl_version TLSv1.3
disconnect tls13_con;
connection default;
#
# Cleanup
#
# Kill the server
# restart
84 changes: 84 additions & 0 deletions mysql-test/main/ssl_multi_cert.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#
# Test RSA + ECDSA + EdDSA certificate support via repeated --ssl-cert / --ssl-key
#
--source include/have_ssl_communication.inc

# Skip on WolfSSL which may not support multiple certs
if (`select @@version_ssl_library like 'wolfSSL%'`) {
skip WolfSSL;
}

# Ed25519 requires OpenSSL 1.1.1+
if (`select @@version_ssl_library like 'OpenSSL 1.0%' or @@version_ssl_library like 'OpenSSL 1.1.0%'`) {
skip OpenSSL too old for Ed25519;
}

--echo #
--echo # Restart server with RSA (primary), ECDSA and EdDSA certs
--echo #

--let $restart_parameters=--ssl-cert-add=$MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem --ssl-key-add=$MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem --ssl-cert-add=$MYSQL_TEST_DIR/std_data/server-eddsa-cert.pem --ssl-key-add=$MYSQL_TEST_DIR/std_data/server-eddsa-key.pem --tls-version=TLSv1.2
--source include/kill_mysqld.inc
--source include/start_mysqld.inc

--echo #
--echo # Verify Ssl_server_cert_types global status shows all three types
--echo #
SHOW GLOBAL STATUS LIKE 'Ssl_server_cert_types';

--echo #
--echo # Test 1: Connect with RSA cipher - should get RSA cert
--echo #
connect (rsa_con,localhost,root,,,,,SSL-CIPHER=ECDHE-RSA-AES128-GCM-SHA256);
SHOW STATUS LIKE 'Ssl_cipher';
SHOW STATUS LIKE 'Ssl_server_cert_type';
disconnect rsa_con;

--echo #
--echo # Test 2: Connect with ECDSA cipher - should get ECDSA cert
--echo #
connection default;
connect (ecdsa_con,localhost,root,,,,,SSL-CIPHER=ECDHE-ECDSA-AES128-GCM-SHA256);
SHOW STATUS LIKE 'Ssl_cipher';
SHOW STATUS LIKE 'Ssl_server_cert_type';
disconnect ecdsa_con;

--echo #
--echo # Test 3: Connect with default ciphers - should succeed
--echo #
connection default;
connect (default_con,localhost,root,,,,,SSL);
SELECT (VARIABLE_VALUE <> '') AS have_ssl FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_cipher';
disconnect default_con;
connection default;

--echo #
--echo # Test 4: TLS 1.3 with all three cert types (EdDSA requires TLS 1.3)
--echo #

connection default;
--let $restart_parameters=--ssl-cert-add=$MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem --ssl-key-add=$MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem --ssl-cert-add=$MYSQL_TEST_DIR/std_data/server-eddsa-cert.pem --ssl-key-add=$MYSQL_TEST_DIR/std_data/server-eddsa-key.pem --tls-version=TLSv1.3
--source include/kill_mysqld.inc
--source include/start_mysqld.inc

SHOW GLOBAL STATUS LIKE 'Ssl_server_cert_types';

connect (tls13_con,localhost,root,,,,,SSL);
--echo # TLS 1.3 connection should use one of the loaded cert types
--let $cert_type= query_get_value(SHOW STATUS LIKE 'Ssl_server_cert_type', Value, 1)
if (`SELECT '$cert_type' NOT IN ('RSA', 'ECDSA', 'EdDSA')`) {
--echo # ERROR: Unexpected cert type: $cert_type
--die Ssl_server_cert_type is not RSA, ECDSA, or EdDSA
}
--echo Ssl_server_cert_type is valid: OK
SHOW STATUS LIKE 'Ssl_version';
disconnect tls13_con;
connection default;

--echo #
--echo # Cleanup
--echo #

--let $restart_parameters=
--source include/kill_mysqld.inc
--source include/start_mysqld.inc
87 changes: 87 additions & 0 deletions mysql-test/main/ssl_multi_cert_errors.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#
# Test 1: --ssl-cert-add with invalid file
#
FOUND 1 /\[ERROR\] SSL error: Unable to get certificate/ in ssl_multi_cert_errors.err
#
# Test 2: --ssl-key-add with invalid file
#
FOUND 1 /\[ERROR\] SSL error: Unable to get private key/ in ssl_multi_cert_errors.err
#
# Test 3: --ssl-cert-add without --ssl-key-add (count mismatch)
#
FOUND 1 /Mismatched --ssl-cert-add/--ssl-key-add/ in ssl_multi_cert_errors.err
#
# Test 4: --ssl-key-add without --ssl-cert-add (count mismatch)
#
FOUND 1 /Mismatched --ssl-cert-add/--ssl-key-add/ in ssl_multi_cert_errors.err
#
# Test 5: same cert type added twice (OpenSSL replaces, last wins)
#
# restart: --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-cert.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-key.pem
SELECT 1;
1
1
# Kill the server
#
# Test 6: one valid cert-add + one invalid cert-add (invalid /etc/hosts)
#
FOUND 1 /\[ERROR\] SSL error: Unable to get certificate/ in ssl_multi_cert_errors.err
#
# Test 7: add second pair (RSA + ECDSA), verify Ssl_server_cert_types
#
# restart: --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem
Ssl_server_cert_types contains RSA and ECDSA: OK
#
# Test 8: FLUSH SSL reloads alt certs correctly
#
FLUSH SSL;
After FLUSH SSL, Ssl_server_cert_types still contains RSA and ECDSA: OK
#
# Test 9: --ssl-cert override + --ssl-cert-add (no interference)
#
# Kill the server
# restart: --ssl-cert=MYSQL_TEST_DIR/std_data/server-cert.pem --ssl-key=MYSQL_TEST_DIR/std_data/server-key.pem --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem
--ssl-cert override + --ssl-cert-add: OK
# Kill the server
#
# Test 10: --ssl-cert-add then --ssl-cert resets alt certs
# (like --plugin-load resets --plugin-load-add)
#
# restart: --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem --ssl-cert=MYSQL_TEST_DIR/std_data/server-cert.pem --ssl-key=MYSQL_TEST_DIR/std_data/server-key.pem
--ssl-cert-add then --ssl-cert resets alt certs: OK
# Kill the server
#
# Test 11: --ssl-cert-add alongside my.cnf default (appends to existing)
#
# restart: --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem
--ssl-cert-add alongside my.cnf default: OK
# Kill the server
#
# Test 12: --ssl-cert-add as sole cert (--ssl-cert= clears, first add becomes primary)
#
# restart: --ssl-cert= --ssl-key= --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem
--ssl-cert-add as sole cert (first add becomes primary): OK
# Kill the server
#
# Test 13: cert-adds before key-adds (order independent)
# --ssl-cert-add --ssl-cert-add --ssl-key-add --ssl-key-add
#
# restart: --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-new-cert.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem --ssl-key-add=MYSQL_TEST_DIR/std_data/server-new-key.pem
cert-adds before key-adds (order independent): OK
# Kill the server
#
# Test 14: --ssl-key override resets alt keys independently
#
# restart: --ssl-key-add=MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem --ssl-key=MYSQL_TEST_DIR/std_data/server-key.pem --ssl-cert=MYSQL_TEST_DIR/std_data/server-cert.pem
--ssl-key override resets alt keys: OK
# Kill the server
#
# Test 15: --ssl-key-add as sole key (--ssl-key= clears, first add becomes primary)
#
# restart: --ssl-cert= --ssl-key= --ssl-key-add=MYSQL_TEST_DIR/std_data/server-ecdsa-key.pem --ssl-cert-add=MYSQL_TEST_DIR/std_data/server-ecdsa-cert.pem
--ssl-key-add as sole key (first add becomes primary): OK
# Kill the server
#
# Cleanup
#
# restart
Loading