summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <msvensson@neptunus.(none)>2006-04-18 17:58:27 +0200
committerunknown <msvensson@neptunus.(none)>2006-04-18 17:58:27 +0200
commitc1d64ccc1b227e862f5cbaa991ce5525c59ab2ef (patch)
tree64442542d9a9aa7ed4cfe1f7d0a101de3e8418b1
parentc3babee88a1384a8fa4eee64a3eab610ef728661 (diff)
downloadmariadb-git-c1d64ccc1b227e862f5cbaa991ce5525c59ab2ef.tar.gz
Bug#17208 SSL: client does not verify server certificate
- Add new function 'ssl_verify_server_cert' which is used if we are connecting to the server with SSL. It will compare the hostname in the server's cert against the hostname that we used when connecting to the server. Will reject the connection if hostname does not match. - Add new option "OPT_SSL_VERIFY_SERVER_CERT" to be passed to mysql_options which will turn on checking of servers cert. - Add new argument "ssl-verify-server-cert" to all mysql* clients which will activate the above option. - Generate a new server cert with 1024 bits that has "localhost" as the server name. SSL/server-cert.pem: Generate a new server cert that has "localhost" as CN, so that we can test to verify the hostname we connected against with the hostname in the cert client/client_priv.h: Add OPT_SSL_VERIFY_CERT client/mysql.cc: Pass the variable "opt_ssl_verify_server_cert" to the mysql_options function. It's processed/included by include/sslopt*.h files client/mysqladmin.cc: Pass the variable "opt_ssl_verify_server_cert" to the mysql_options function. It's processed/included by include/sslopt*.h files client/mysqldump.c: Pass the variable "opt_ssl_verify_server_cert" to the mysql_options function. It's processed/included by include/sslopt*.h files client/mysqlimport.c: Pass the variable "opt_ssl_verify_server_cert" to the mysql_options function. It's processed/included by include/sslopt*.h files client/mysqlshow.c: Pass the variable "opt_ssl_verify_server_cert" to the mysql_options function. It's processed/included by include/sslopt*.h files client/mysqltest.c: Always set opt_ssl_verify_server_cert on in mysqltest if we are using SSL include/mysql.h: Add variable ssl_verify_cerver_cert include/sslopt-longopts.h: Add ssl-verify-server-cert options to all clients. include/sslopt-vars.h: Add opt_ssl_varify_server_cert to all clients. sql-common/client.c: Add ssl_vertify_server_cert function which is executed if user has set the option ssl_verify_cerver_cert vio/viosslfactories.c: Ask the SSL library to verify servers cert by setting the SSL_VERIFY_PEER flag
-rw-r--r--SSL/server-cert.pem78
-rw-r--r--client/client_priv.h2
-rw-r--r--client/mysql.cc2
-rw-r--r--client/mysqladmin.cc2
-rw-r--r--client/mysqldump.c2
-rw-r--r--client/mysqlimport.c2
-rw-r--r--client/mysqlshow.c2
-rw-r--r--client/mysqltest.c11
-rw-r--r--include/mysql.h4
-rw-r--r--include/sslopt-longopts.h7
-rw-r--r--include/sslopt-vars.h3
-rw-r--r--sql-common/client.c86
-rw-r--r--vio/viosslfactories.c8
13 files changed, 159 insertions, 50 deletions
diff --git a/SSL/server-cert.pem b/SSL/server-cert.pem
index debf7026e3c..4ef70ed5095 100644
--- a/SSL/server-cert.pem
+++ b/SSL/server-cert.pem
@@ -1,13 +1,14 @@
Certificate:
Data:
Version: 3 (0x2)
- Serial Number: 2 (0x2)
+ Serial Number:
+ e9:07:d1:01:94:ee:66:ca
Signature Algorithm: md5WithRSAEncryption
- Issuer: C=SE, L=Uppsala, O=MySQL AB, CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
+ Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB, CN=localhost/emailAddress=abstract.mysql.developer@mysql.com
Validity
- Not Before: Sep 12 16:22:06 2003 GMT
- Not After : Sep 9 16:22:06 2013 GMT
- Subject: C=SE, L=Uppsala, O=MySQL AB, CN=MySQL Server/Email=abstract.mysql.developer@mysql.com
+ Not Before: Apr 18 15:35:37 2006 GMT
+ Not After : Jan 12 15:35:37 2009 GMT
+ Subject: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB, CN=localhost/emailAddress=abstract.mysql.developer@mysql.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
@@ -23,45 +24,42 @@ Certificate:
3d:0e:4d:2a:a8:b8:ca:99:8d
Exponent: 65537 (0x10001)
X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
6E:E4:9B:6A:C5:EA:E4:E6:C7:EF:D7:1E:C8:63:45:60:2B:1B:D4:D4
X509v3 Authority Key Identifier:
- keyid:88:98:65:D9:F3:F2:8B:03:1D:66:60:61:23:FA:AD:73:6D:D3:68:92
- DirName:/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
- serial:00
+ keyid:6E:E4:9B:6A:C5:EA:E4:E6:C7:EF:D7:1E:C8:63:45:60:2B:1B:D4:D4
+ DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB/CN=localhost/emailAddress=abstract.mysql.developer@mysql.com
+ serial:E9:07:D1:01:94:EE:66:CA
+ X509v3 Basic Constraints:
+ CA:TRUE
Signature Algorithm: md5WithRSAEncryption
- 31:77:69:b9:bd:ab:29:f3:fc:5a:09:16:6f:5d:42:ea:ba:01:
- 55:69:e3:75:cf:b8:d1:b7:b9:bf:da:63:85:8c:48:92:06:60:
- 76:97:e0:00:78:4b:ad:da:ab:6a:90:6d:8b:03:a8:b1:e9:09:
- 78:e1:29:98:56:12:60:6b:42:fe:e8:a7:c4:f8:d6:15:07:e8:
- 2b:c2:d8:8a:e5:1b:2e:51:08:9b:56:e3:b3:7a:4c:3e:e5:be:
- 4a:4d:f8:65:7b:a8:21:e0:ca:fe:8b:ab:d7:ec:f2:2d:f7:d0:
- bf:d7:c5:23:1c:08:d8:aa:57:c7:f3:5f:ba:33:3f:78:d1:f4:
- 8e:5e
+ 1f:03:59:6e:ff:1f:9d:c7:19:9e:8e:b2:1a:c0:0b:9e:ee:94:
+ 35:77:2a:93:04:ea:d5:a8:fc:36:5a:5b:e3:1c:02:b8:cf:04:
+ 6e:21:b0:27:f6:96:6e:d6:8f:cd:02:cf:23:f3:e7:ff:6a:ee:
+ a9:09:c5:c9:07:81:b6:d2:bc:bd:13:47:0d:7b:76:f6:8a:c4:
+ 76:24:f8:4c:4e:26:fc:d8:c0:1f:3d:40:19:43:8e:41:ab:99:
+ 3a:99:9b:24:7c:ae:78:f3:df:2f:a2:ed:8f:27:0a:0a:0b:04:
+ bf:25:74:88:87:96:c8:68:d5:bc:5b:a0:ef:14:aa:53:6e:c4:
+ a3:e3
-----BEGIN CERTIFICATE-----
-MIIDkTCCAvqgAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCU0Ux
-EDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMSEwHwYDVQQDExhB
-YnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAvBgkqhkiG9w0BCQEWImFic3RyYWN0
-Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wHhcNMDMwOTEyMTYyMjA2WhcNMTMw
-OTA5MTYyMjA2WjB8MQswCQYDVQQGEwJTRTEQMA4GA1UEBxMHVXBwc2FsYTERMA8G
-A1UEChMITXlTUUwgQUIxFTATBgNVBAMTDE15U1FMIFNlcnZlcjExMC8GCSqGSIb3
-DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2ZWxvcGVyQG15c3FsLmNvbTCBnzANBgkq
-hkiG9w0BAQEFAAOBjQAwgYkCgYEA6YZ6VYSITL6k+JJzMBJJC3qFhzk0OQ19C40Y
-wheVE1LSP1UQV8g/WvWy+ovQZ0nMqoL8n84AtHPzNtI608KwDhTD1LIhdKHwMYFg
-h5hzXBDBsRpN8fOwmD/w15ebK/3VIXmyL+tkFcmbnfyeLdT4BFvqqXVLQsM9Dk0q
-qLjKmY0CAwEAAaOCARQwggEQMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9w
-ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRu5Jtqxerk5sfv
-1x7IY0VgKxvU1DCBtQYDVR0jBIGtMIGqgBSImGXZ8/KLAx1mYGEj+q1zbdNokqGB
-jqSBizCBiDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoT
-CE15U1FMIEFCMSEwHwYDVQQDExhBYnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAv
-BgkqhkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb22C
-AQAwDQYJKoZIhvcNAQEEBQADgYEAMXdpub2rKfP8WgkWb11C6roBVWnjdc+40be5
-v9pjhYxIkgZgdpfgAHhLrdqrapBtiwOosekJeOEpmFYSYGtC/uinxPjWFQfoK8LY
-iuUbLlEIm1bjs3pMPuW+Sk34ZXuoIeDK/our1+zyLffQv9fFIxwI2KpXx/NfujM/
-eNH0jl4=
+MIIDijCCAvOgAwIBAgIJAOkH0QGU7mbKMA0GCSqGSIb3DQEBBAUAMIGLMQswCQYD
+VQQGEwJTRTEQMA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8G
+A1UEChMITXlTUUwgQUIxEjAQBgNVBAMTCWxvY2FsaG9zdDExMC8GCSqGSIb3DQEJ
+ARYiYWJzdHJhY3QubXlzcWwuZGV2ZWxvcGVyQG15c3FsLmNvbTAeFw0wNjA0MTgx
+NTM1MzdaFw0wOTAxMTIxNTM1MzdaMIGLMQswCQYDVQQGEwJTRTEQMA4GA1UECBMH
+VXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxEjAQ
+BgNVBAMTCWxvY2FsaG9zdDExMC8GCSqGSIb3DQEJARYiYWJzdHJhY3QubXlzcWwu
+ZGV2ZWxvcGVyQG15c3FsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
+6YZ6VYSITL6k+JJzMBJJC3qFhzk0OQ19C40YwheVE1LSP1UQV8g/WvWy+ovQZ0nM
+qoL8n84AtHPzNtI608KwDhTD1LIhdKHwMYFgh5hzXBDBsRpN8fOwmD/w15ebK/3V
+IXmyL+tkFcmbnfyeLdT4BFvqqXVLQsM9Dk0qqLjKmY0CAwEAAaOB8zCB8DAdBgNV
+HQ4EFgQUbuSbasXq5ObH79ceyGNFYCsb1NQwgcAGA1UdIwSBuDCBtYAUbuSbasXq
+5ObH79ceyGNFYCsb1NShgZGkgY4wgYsxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdV
+cHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQjESMBAG
+A1UEAxMJbG9jYWxob3N0MTEwLwYJKoZIhvcNAQkBFiJhYnN0cmFjdC5teXNxbC5k
+ZXZlbG9wZXJAbXlzcWwuY29tggkA6QfRAZTuZsowDAYDVR0TBAUwAwEB/zANBgkq
+hkiG9w0BAQQFAAOBgQAfA1lu/x+dxxmejrIawAue7pQ1dyqTBOrVqPw2WlvjHAK4
+zwRuIbAn9pZu1o/NAs8j8+f/au6pCcXJB4G20ry9E0cNe3b2isR2JPhMTib82MAf
+PUAZQ45Bq5k6mZskfK54898vou2PJwoKCwS/JXSIh5bIaNW8W6DvFKpTbsSj4w==
-----END CERTIFICATE-----
diff --git a/client/client_priv.h b/client/client_priv.h
index a9d5364df49..9e011144836 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -51,5 +51,5 @@ enum options_client
#endif
OPT_TRIGGERS,
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
- OPT_TZ_UTC, OPT_AUTO_CLOSE
+ OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_SSL_VERIFY_SERVER_CERT
};
diff --git a/client/mysql.cc b/client/mysql.cc
index cd4cbf49918..7c1e70cfda2 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -3123,6 +3123,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
#endif
if (opt_protocol)
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 5b52d524f8e..57ab4e071fb 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -340,6 +340,8 @@ int main(int argc,char *argv[])
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
#endif
if (opt_protocol)
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 78f12593f46..ee6d7b9d12b 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -905,6 +905,8 @@ static int dbConnect(char *host, char *user,char *passwd)
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 8694093f06b..1f9b96f91be 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -384,6 +384,8 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd)
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 504f0d9844b..d090495ff81 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -109,6 +109,8 @@ int main(int argc, char **argv)
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
#endif
if (opt_protocol)
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
diff --git a/client/mysqltest.c b/client/mysqltest.c
index e51d83270b5..7257958311f 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -108,7 +108,7 @@ enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC,
OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
OPT_SSL_CIPHER,OPT_PS_PROTOCOL,OPT_SP_PROTOCOL,OPT_CURSOR_PROTOCOL,
- OPT_VIEW_PROTOCOL};
+ OPT_VIEW_PROTOCOL, OPT_SSL_VERIFY_SERVER_CERT};
/* ************************************************************************ */
/*
@@ -2378,8 +2378,12 @@ int do_connect(struct st_query *q)
#ifdef HAVE_OPENSSL
if (opt_use_ssl || con_ssl)
+ {
mysql_ssl_set(&next_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&next_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ &opt_ssl_verify_server_cert);
+ }
#endif
if (con_sock && !free_con_sock && *con_sock && *con_sock != FN_LIBCHAR)
con_sock=fn_format(buff, con_sock, TMPDIR, "",0);
@@ -4604,9 +4608,14 @@ int main(int argc, char **argv)
mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_NAME, charset_name);
#ifdef HAVE_OPENSSL
+ opt_ssl_verify_server_cert= TRUE; /* Always on in mysqltest */
if (opt_use_ssl)
+ {
mysql_ssl_set(&cur_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&cur_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ &opt_ssl_verify_server_cert);
+ }
#endif
if (!(cur_con->name = my_strdup("default", MYF(MY_WME))))
diff --git a/include/mysql.h b/include/mysql.h
index 925a4525378..7149224dcdd 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -149,7 +149,8 @@ enum mysql_option
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
- MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT
+ MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT
};
struct st_mysql_options {
@@ -164,6 +165,7 @@ struct st_mysql_options {
char *ssl_ca; /* PEM CA file */
char *ssl_capath; /* PEM directory of CA-s? */
char *ssl_cipher; /* cipher to use */
+ my_bool ssl_verify_server_cert; /* if to verify server cert */
char *shared_memory_base_name;
unsigned long max_allowed_packet;
my_bool use_ssl; /* if to use SSL or not */
diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h
index dc3b0922327..f444a7eb7ce 100644
--- a/include/sslopt-longopts.h
+++ b/include/sslopt-longopts.h
@@ -37,5 +37,10 @@
{"ssl-cipher", OPT_SSL_CIPHER, "SSL cipher to use (implies --ssl).",
(gptr*) &opt_ssl_cipher, (gptr*) &opt_ssl_cipher, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
-
+#ifdef MYSQL_CLIENT
+ {"ssl-verify-server-cert", OPT_SSL_VERIFY_SERVER_CERT,
+ "Verify servers \"Common Name\" in it's cert against hostname used when connecting. This option is disabled by default.",
+ (gptr*) &opt_ssl_verify_server_cert, (gptr*) &opt_ssl_verify_server_cert,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
#endif /* HAVE_OPENSSL */
diff --git a/include/sslopt-vars.h b/include/sslopt-vars.h
index 164cf541381..8e5f3434396 100644
--- a/include/sslopt-vars.h
+++ b/include/sslopt-vars.h
@@ -21,4 +21,7 @@ static char *opt_ssl_cert = 0;
static char *opt_ssl_ca = 0;
static char *opt_ssl_capath = 0;
static char *opt_ssl_cipher = 0;
+#ifdef MYSQL_CLIENT
+static my_bool opt_ssl_verify_server_cert= 0;
+#endif
#endif
diff --git a/sql-common/client.c b/sql-common/client.c
index b24b92014d6..13a816b05b9 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1500,6 +1500,7 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
mysql->options.ssl_ca= strdup_if_not_null(ca);
mysql->options.ssl_capath= strdup_if_not_null(capath);
mysql->options.ssl_cipher= strdup_if_not_null(cipher);
+ mysql->options.ssl_verify_server_cert= FALSE; /* Off by default */
#endif /* HAVE_OPENSSL */
DBUG_RETURN(0);
}
@@ -1521,7 +1522,7 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
- my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
if (ssl_fd)
SSL_CTX_free(ssl_fd->ssl_context);
my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
@@ -1534,6 +1535,77 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
mysql->connector_fd = 0;
DBUG_VOID_RETURN;
}
+
+/*
+ Check the server's (subject) Common Name against the
+ hostname we connected to
+
+ SYNOPSIS
+ ssl_verify_server_cert()
+ vio pointer to a SSL connected vio
+ server_hostname name of the server that we connected to
+
+ RETURN VALUES
+ 0 Success
+ 1 Failed to validate server
+
+ */
+static int ssl_verify_server_cert(Vio *vio, const char* server_hostname)
+{
+ SSL *ssl;
+ X509 *server_cert;
+ char *cp1, *cp2;
+ char buf[256];
+ DBUG_ENTER("ssl_verify_server_cert");
+ DBUG_PRINT("enter", ("server_hostname: %s", server_hostname));
+
+ if (!(ssl= (SSL*)vio->ssl_arg))
+ {
+ DBUG_PRINT("error", ("No SSL pointer found"));
+ DBUG_RETURN(1);
+ }
+
+ if (!server_hostname)
+ {
+ DBUG_PRINT("error", ("No server hostname supplied"));
+ DBUG_RETURN(1);
+ }
+
+ if (!(server_cert= SSL_get_peer_certificate(ssl)))
+ {
+ DBUG_PRINT("error", ("Could not get server certificate"));
+ DBUG_RETURN(1);
+ }
+
+ /*
+ We already know that the certificate exchanged was valid; the SSL library
+ handled that. Now we need to verify that the contents of the certificate
+ are what we expect.
+ */
+
+ X509_NAME_oneline(X509_get_subject_name(server_cert), buf, sizeof(buf));
+ X509_free (server_cert);
+
+ DBUG_PRINT("info", ("hostname in cert: %s", buf));
+ cp1 = strstr(buf, "/CN=");
+ if (cp1)
+ {
+ cp1 += 4; // Skip the "/CN=" that we found
+ // Search for next / which might be the delimiter for email
+ cp2 = strchr(cp1, '/');
+ if (cp2)
+ *cp2 = '\0';
+ DBUG_PRINT("info", ("Server hostname in cert: %s", cp1));
+ if (!strcmp(cp1, server_hostname))
+ {
+ /* Success */
+ DBUG_RETURN(0);
+ }
+ }
+ DBUG_PRINT("error", ("SSL certificate validation failure"));
+ DBUG_RETURN(1);
+}
+
#endif /* HAVE_OPENSSL */
@@ -2049,7 +2121,14 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
}
DBUG_PRINT("info", ("IO layer change done!"));
- /* TODO Verify server cert */
+ /* Verify server cert */
+ if (mysql->options.ssl_verify_server_cert &&
+ ssl_verify_server_cert(mysql->net.vio, mysql->host))
+ {
+ set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
+ goto error;
+ }
+
}
#endif /* HAVE_OPENSSL */
@@ -2789,6 +2868,9 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
case MYSQL_OPT_RECONNECT:
mysql->reconnect= *(my_bool *) arg;
break;
+ case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
+ mysql->options.ssl_verify_server_cert= *(my_bool *) arg;
+ break;
default:
DBUG_RETURN(1);
}
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index d6356f1adca..2b3e80a98e4 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -290,20 +290,20 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
const char *cipher)
{
struct st_VioSSLFd *ssl_fd;
- int verify= SSL_VERIFY_NONE;
+ int verify= SSL_VERIFY_PEER;
if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
ca_path, cipher, TLSv1_client_method())))
{
return 0;
}
+
/* Init the the VioSSLFd as a "connector" ie. the client side */
/*
The verify_callback function is used to control the behaviour
- when the SSL_VERIFY_PEER flag is set. Here it is SSL_VERIFY_NONE
- and thus callback is set to NULL
+ when the SSL_VERIFY_PEER flag is set.
*/
- SSL_CTX_set_verify(ssl_fd->ssl_context, verify, NULL);
+ SSL_CTX_set_verify(ssl_fd->ssl_context, verify, vio_verify_callback);
return ssl_fd;
}