mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-31855 validate ssl certificates using client password
if the client enabled --ssl-verify-server-cert, then the server certificate is verified as follows: * if --ssl-ca or --ssl-capath were specified, the cert must have a proper signature by the specified CA (or CA in the path) and the cert's hostname must match the server's hostname. If the cert isn't signed or a hostname is wrong - the connection is aborted. * if MARIADB_OPT_TLS_PEER_FP was used and the fingerprint matches, the connection is allowed, if it doesn't match - aborted. * If the connection uses unix socket or named pipes - it's allowed. (consistent with server's --require-secure-transport behavior) otherwise the cert is still in doubt, we don't know if we can trust it or there's an active MitM in progress. * If the user has provided no password or the server requested an authentication plugin that sends the password in cleartext - the connection is aborted. * Perform the authentication. If the server accepts the password, it'll send SHA2(scramble || password hash || cert fingerprint) with the OK packet. * Verify the SHA2 digest, if it matches - the connection is allowed, otherwise it's aborted.
This commit is contained in:
84
mysql-test/main/ssl_autoverify.test
Normal file
84
mysql-test/main/ssl_autoverify.test
Normal file
@ -0,0 +1,84 @@
|
||||
source include/platform.inc;
|
||||
source include/not_embedded.inc;
|
||||
if (!$AUTH_ED25519_SO) {
|
||||
skip No auth_ed25519 plugin;
|
||||
}
|
||||
if (!$DIALOG_EXAMPLES_SO) {
|
||||
skip No dialog_examples plugin;
|
||||
}
|
||||
|
||||
install soname 'auth_ed25519';
|
||||
install plugin three_attempts soname 'dialog_examples';
|
||||
|
||||
create user native@'%' identified via mysql_native_password using password('foo');
|
||||
create user ed@'%' identified via ed25519 using password('bar');
|
||||
create user nohash@'%' identified via three_attempts using 'onetwothree';
|
||||
create user multi@'%' identified via mysql_native_password using password('pw1')
|
||||
or ed25519 using password('pw2');
|
||||
grant all privileges on test.* to native@'%';
|
||||
grant all privileges on test.* to ed@'%';
|
||||
grant all privileges on test.* to nohash@'%';
|
||||
grant all privileges on test.* to multi@'%';
|
||||
|
||||
create function have_ssl() returns char(3)
|
||||
return (select if(variable_value > '','yes','no') as 'have_ssl'
|
||||
from information_schema.session_status
|
||||
where variable_name='ssl_cipher');
|
||||
|
||||
#
|
||||
# root user, no password, so cannot validate cert.
|
||||
#
|
||||
--echo # mysql -uroot --disable-ssl-verify-server-cert -e "select test.have_ssl()"
|
||||
--exec $MYSQL --protocol tcp -uroot --disable-ssl-verify-server-cert -e "select test.have_ssl()" 2>&1
|
||||
--echo # mysql -uroot --ssl-verify-server-cert -e "select test.have_ssl()"
|
||||
--replace_regex /TLS\/SSL error.*certificate[^\n]*/TLS\/SSL error: Failed to verify the server certificate/
|
||||
--error 1
|
||||
--exec $MYSQL --protocol tcp -uroot --ssl-verify-server-cert -e "select test.have_ssl()" 2>&1
|
||||
#
|
||||
# unless using a secure transport, like unix_socket or named pipes
|
||||
#
|
||||
# note that SSL works over unix_socket, and it doesn't work over named pipes
|
||||
# but the connection is allowed either way, as the transport is secure
|
||||
#
|
||||
let proto=socket;
|
||||
if ($MTR_COMBINATION_WIN) {
|
||||
let proto=pipe;
|
||||
}
|
||||
--echo # mysql --protocol $proto -uroot --ssl-verify-server-cert -e "select test.have_ssl()"
|
||||
--exec $MYSQL --protocol $proto -uroot --ssl-verify-server-cert -e "select test.have_ssl()" 2>&1
|
||||
#
|
||||
# mysql_native_password with password works fine
|
||||
#
|
||||
--echo # mysql -unative -pfoo --ssl-verify-server-cert -e "select test.have_ssl()"
|
||||
--exec $MYSQL --protocol tcp -unative -pfoo --ssl-verify-server-cert -e "select test.have_ssl()" 2>&1
|
||||
#
|
||||
# ed25519 with password works fine
|
||||
#
|
||||
--echo # mysql -ued -pbar --ssl-verify-server-cert -e "select test.have_ssl()"
|
||||
--exec $MYSQL --protocol tcp -ued -pbar --ssl-verify-server-cert -e "select test.have_ssl()" 2>&1
|
||||
#
|
||||
# three_attempts uses auth string as is, doesn't hash.
|
||||
# so it's not safe over untrusted connection and thus cannot validate cert
|
||||
#
|
||||
--echo # mysql -unohash -ponetwothree --disable-ssl-verify-server-cert -e "select test.have_ssl()"
|
||||
--exec $MYSQL --protocol tcp -unohash -ponetwothree --disable-ssl-verify-server-cert -e "select test.have_ssl()" 2>&1
|
||||
--echo # mysql -unohash -ponetwothree --ssl-verify-server-cert -e "select test.have_ssl()"
|
||||
--replace_regex /TLS\/SSL error.*certificate[^\n]*/TLS\/SSL error: Failed to verify the server certificate/
|
||||
--error 1
|
||||
--exec $MYSQL --protocol tcp -unohash -ponetwothree --ssl-verify-server-cert -e "select test.have_ssl()" 2>&1
|
||||
#
|
||||
# multi-auth case, both client and server must use
|
||||
# the same plugin for cert validation
|
||||
#
|
||||
--echo # mysql -umulti -ppw1 --ssl-verify-server-cert -e "select test.have_ssl()"
|
||||
--exec $MYSQL --protocol tcp -umulti -ppw1 --ssl-verify-server-cert -e "select test.have_ssl()" 2>&1
|
||||
--echo # mysql -umulti -ppw2 --ssl-verify-server-cert -e "select test.have_ssl()"
|
||||
--exec $MYSQL --protocol tcp -umulti -ppw2 --ssl-verify-server-cert -e "select test.have_ssl()" 2>&1
|
||||
|
||||
drop function have_ssl;
|
||||
drop user native@'%';
|
||||
drop user ed@'%';
|
||||
drop user nohash@'%';
|
||||
drop user multi@'%';
|
||||
uninstall plugin ed25519;
|
||||
uninstall plugin three_attempts;
|
Reference in New Issue
Block a user