From b85291e5db65b8b76e48e77aff74837331f1c4ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Sun, 4 Feb 2018 18:57:33 +0100 Subject: [PATCH] Use native host check from OpenSSL This results in support for Subject Alternative Name https://bugs.mysql.com/bug.php?id=68052 Note that https://www.openssl.org/docs/manmaster/man3/X509_check_host.html says: "Applications are encouraged to use X509_VERIFY_PARAM_set1_host() rather than explicitly calling X509_check_host(3)." Which is described on https://wiki.openssl.org/index.php/Hostname_validation However to use X509_VERIFY_PARAM_set1_host() we need to do that just before creating the connection. That should be done in ssl_do() which is called from sslconnect(). But then ssl_do() needs to know the ssl_mode and hostname, which it currently doesn't. Note that ssl_verify_server_cert() is called when the connection is already created. --- sql-common/client.cc | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/sql-common/client.cc b/sql-common/client.cc index ec315c759ba..3ac8b16e010 100644 --- a/sql-common/client.cc +++ b/sql-common/client.cc @@ -108,6 +108,10 @@ #define SOCKET_ERROR -1 #endif +#ifdef HAVE_OPENSSL +#include +#endif + #include #include @@ -2811,12 +2815,14 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const c { SSL *ssl; X509 *server_cert= NULL; - char *cn= NULL; + int ret_validation= 1; +#if OPENSSL_VERSION_NUMBER < 0x10100000L int cn_loc= -1; + char *cn= NULL; ASN1_STRING *cn_asn1= NULL; X509_NAME_ENTRY *cn_entry= NULL; X509_NAME *subject= NULL; - int ret_validation= 1; +#endif DBUG_ENTER("ssl_verify_server_cert"); DBUG_PRINT("enter", ("server_hostname: %s", server_hostname)); @@ -2850,13 +2856,17 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const c are what we expect. */ - /* - Some notes for future development - We should check host name in alternative name first and then if needed check in common name. - Currently yssl doesn't support alternative name. - openssl 1.0.2 support X509_check_host method for host name validation, we may need to start using - X509_check_host in the future. - */ + /* Use OpenSSL host check instead of our own if we have OpenSSL 1.1.0 or newer */ +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + if (X509_check_host(server_cert, server_hostname, strlen(server_hostname), X509_CHECK_FLAG_NO_WILDCARDS, 0) != 1) + { + *errptr= "Failed to verify the server certificate via X509_check_host"; + goto error; + } else { + /* Success */ + ret_validation= 0; + } +#else subject= X509_get_subject_name((X509 *) server_cert); // Find the CN location in the subject @@ -2903,6 +2913,7 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const c ret_validation= 0; } +#endif *errptr= "SSL certificate validation failure"; error: