summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArun Kuruvila <arun.kuruvila@oracle.com>2016-03-01 10:17:25 +0530
committerArun Kuruvila <arun.kuruvila@oracle.com>2016-03-01 10:17:25 +0530
commitc7e68606c02b7f87a48c27eb358d4d07480f40f4 (patch)
treeedae67bf14337b657398d7007e8ba2eccd846e6a
parent96f680aa6589138058a820987e5cf8600f024e81 (diff)
downloadmariadb-git-c7e68606c02b7f87a48c27eb358d4d07480f40f4.tar.gz
Bug#21920657: SSL-CA FAILS SILENTLY IF THE PATH CANNOT BE
FOUND Description:- Failure during the validation of CA certificate path which is provided as an option for 'ssl-ca' returns two different errors for YaSSL and OPENSSL. Analysis:- 'ssl-ca', option used for specifying the ssl ca certificate path. Failing to validate this certificate with OPENSSL returns an error, "ERROR 2026 (HY000): SSL connection error: SSL_CTX_set_default_verify_paths failed". While YASSL returns "ERROR 2026 (HY000): SSL connection error: ASN: bad other signature confirmation". Error returned by the OPENSSL is correct since "SSL_CTX_load_verify_locations()" returns 0 (in case of OPENSSL) for the failure and sets error as "SSL_INITERR_BAD_PATHS". In case of YASSL, "SSL_CTX_load_verify_locations()" returns an error number which is less than or equal to 0 in case of error. Error numbers for YASSL is mentioned in the file, 'extra/yassl/include/openssl/ssl.h'(line no : 292). Also 'ssl-ca' does not accept tilde home directory path substitution. Fix:- The condition which checks for the error in the "SSL_CTX_load_verify_locations()" is changed in order to accommodate YASSL as well. A logic is written in "mysql_ssl_set()" in order accept the tilde home directory path substitution for all ssl options.
-rw-r--r--mysql-test/r/ssl_ca.result24
-rw-r--r--mysql-test/t/ssl_ca.test35
-rw-r--r--sql-common/client.c23
-rw-r--r--vio/viosslfactories.c4
4 files changed, 80 insertions, 6 deletions
diff --git a/mysql-test/r/ssl_ca.result b/mysql-test/r/ssl_ca.result
new file mode 100644
index 00000000000..ffc5671f85f
--- /dev/null
+++ b/mysql-test/r/ssl_ca.result
@@ -0,0 +1,24 @@
+#
+# Bug#21920657: SSL-CA FAILS SILENTLY IF THE PATH CANNOT BE FOUND
+#
+# try to connect with wrong '--ssl-ca' path : should fail
+ERROR 2026 (HY000): SSL connection error: SSL_CTX_set_default_verify_paths failed
+# try to connect with correct '--ssl-ca' path : should connect
+Variable_name Value
+Ssl_cipher DHE-RSA-AES256-SHA
+#
+# Bug#21920678: SSL-CA DOES NOT ACCEPT ~USER TILDE HOME DIRECTORY
+# PATH SUBSTITUTION
+#
+# try to connect with '--ssl-ca' option using tilde home directoy
+# path substitution : should connect
+Variable_name Value
+Ssl_cipher DHE-RSA-AES256-SHA
+# try to connect with '--ssl-key' option using tilde home directoy
+# path substitution : should connect
+Variable_name Value
+Ssl_cipher DHE-RSA-AES256-SHA
+# try to connect with '--ssl-cert' option using tilde home directoy
+# path substitution : should connect
+Variable_name Value
+Ssl_cipher DHE-RSA-AES256-SHA
diff --git a/mysql-test/t/ssl_ca.test b/mysql-test/t/ssl_ca.test
new file mode 100644
index 00000000000..92695de4b0d
--- /dev/null
+++ b/mysql-test/t/ssl_ca.test
@@ -0,0 +1,35 @@
+--source include/have_ssl.inc
+--source include/not_embedded.inc
+
+--echo #
+--echo # Bug#21920657: SSL-CA FAILS SILENTLY IF THE PATH CANNOT BE FOUND
+--echo #
+
+--echo # try to connect with wrong '--ssl-ca' path : should fail
+--error 1
+--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/wrong-cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" 2>&1
+
+--echo # try to connect with correct '--ssl-ca' path : should connect
+--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'"
+
+--echo #
+--echo # Bug#21920678: SSL-CA DOES NOT ACCEPT ~USER TILDE HOME DIRECTORY
+--echo # PATH SUBSTITUTION
+--echo #
+
+--let $mysql_test_dir_path= `SELECT REPLACE('$MYSQL_TEST_DIR', '$HOME', '~')`
+
+--echo # try to connect with '--ssl-ca' option using tilde home directoy
+--echo # path substitution : should connect
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL --ssl-ca=$mysql_test_dir_path/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'"
+
+--echo # try to connect with '--ssl-key' option using tilde home directoy
+--echo # path substitution : should connect
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$mysql_test_dir_path/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'"
+
+--echo # try to connect with '--ssl-cert' option using tilde home directoy
+--echo # path substitution : should connect
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$mysql_test_dir_path/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'"
diff --git a/sql-common/client.c b/sql-common/client.c
index 0ef70eb7f56..cd9b6a71c53 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1204,6 +1204,21 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd)
my_strdup((STR), MYF(MY_WME)) : NULL; \
} while (0)
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
+static char *set_ssl_option_unpack_path(const char *arg)
+{
+ char *opt_var= NULL;
+ if (arg)
+ {
+ char *buff= (char *)my_malloc(FN_REFLEN + 1, MYF(MY_WME));
+ unpack_filename(buff, (char *)arg);
+ opt_var= my_strdup(buff, MYF(MY_WME));
+ my_free(buff);
+ }
+ return opt_var;
+}
+#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
+
void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group)
{
@@ -1798,10 +1813,10 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
{
DBUG_ENTER("mysql_ssl_set");
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
- mysql->options.ssl_key= strdup_if_not_null(key);
- mysql->options.ssl_cert= strdup_if_not_null(cert);
- mysql->options.ssl_ca= strdup_if_not_null(ca);
- mysql->options.ssl_capath= strdup_if_not_null(capath);
+ mysql->options.ssl_key= set_ssl_option_unpack_path(key);
+ mysql->options.ssl_cert= set_ssl_option_unpack_path(cert);
+ mysql->options.ssl_ca= set_ssl_option_unpack_path(ca);
+ mysql->options.ssl_capath= set_ssl_option_unpack_path(capath);
mysql->options.ssl_cipher= strdup_if_not_null(cipher);
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
DBUG_RETURN(0);
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index ea46d9c0302..3aa1c873163 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -250,7 +250,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
}
/* Load certs from the trusted ca */
- if (SSL_CTX_load_verify_locations(ssl_fd->ssl_context, ca_file, ca_path) == 0)
+ if (SSL_CTX_load_verify_locations(ssl_fd->ssl_context, ca_file, ca_path) <= 0)
{
DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
if (ca_file || ca_path)