Commit 18087b04 authored by Venkata Sidagam's avatar Venkata Sidagam

Bug #13115401: -SSL-KEY VALUE IS NOT VALIDATED AND IT ALLOWS INSECURE

               CONNECTIONS IF SPE

Problem description: -ssl-key value is not validated, you can assign any bogus 
text to --ssl-key and it is not verified that it exists, and more importantly, 
it allows the client to connect to mysqld.

Fix: Added proper validations checks for --ssl-key.

Note:
1) Documentation changes require for 5.1, 5.5, 5.6 and trunk in the sections
   listed below and the details are :

 http://dev.mysql.com/doc/refman/5.6/en/ssl-options.html#option_general_ssl
    and
 REQUIRE SSL section of
 http://dev.mysql.com/doc/refman/5.6/en/grant.html

2) Client having with option '--ssl', should able to get ssl connection. This 
will be implemented as part of separate fix in 5.6 and trunk.
parent 2f30b340
...@@ -747,7 +747,7 @@ void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback vc) ...@@ -747,7 +747,7 @@ void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback vc)
int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file, int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file,
const char* path) const char* path)
{ {
int ret = SSL_SUCCESS; int ret = SSL_FAILURE;
const int HALF_PATH = 128; const int HALF_PATH = 128;
if (file) ret = read_file(ctx, file, SSL_FILETYPE_PEM, CA); if (file) ret = read_file(ctx, file, SSL_FILETYPE_PEM, CA);
......
...@@ -44,9 +44,9 @@ ERROR 42000: DELETE command denied to user 'ssl_user4'@'localhost' for table 't1 ...@@ -44,9 +44,9 @@ ERROR 42000: DELETE command denied to user 'ssl_user4'@'localhost' for table 't1
drop user ssl_user1@localhost, ssl_user2@localhost, drop user ssl_user1@localhost, ssl_user2@localhost,
ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost; ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost;
drop table t1; drop table t1;
mysqltest: Could not open connection 'default': 2026 SSL connection error mysqltest: Could not open connection 'default': 2026 SSL connection error: xxxx
mysqltest: Could not open connection 'default': 2026 SSL connection error mysqltest: Could not open connection 'default': 2026 SSL connection error: xxxx
mysqltest: Could not open connection 'default': 2026 SSL connection error mysqltest: Could not open connection 'default': 2026 SSL connection error: xxxx
SSL error: Unable to get private key from '' SSL error: Unable to get private key from ''
mysqltest: Could not open connection 'default': 2026 SSL connection error mysqltest: Could not open connection 'default': 2026 SSL connection error
SSL error: Unable to get certificate from '' SSL error: Unable to get certificate from ''
......
...@@ -73,22 +73,28 @@ drop table t1; ...@@ -73,22 +73,28 @@ drop table t1;
# a different cacert # a different cacert
# #
--exec echo "this query should not execute;" > $MYSQLTEST_VARDIR/tmp/test.sql --exec echo "this query should not execute;" > $MYSQLTEST_VARDIR/tmp/test.sql
--replace_regex /2026 SSL connection error.*/2026 SSL connection error: xxxx/
--error 1 --error 1
--exec $MYSQL_TEST --ssl-ca=$MYSQL_TEST_DIR/std_data/untrusted-cacert.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 --exec $MYSQL_TEST --ssl-ca=$MYSQL_TEST_DIR/std_data/untrusted-cacert.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
--echo
# #
# Test that we can't open connection to server if we are using # Test that we can't open connection to server if we are using
# a blank ca # a blank ca
# #
--replace_regex /2026 SSL connection error.*/2026 SSL connection error: xxxx/
--error 1 --error 1
--exec $MYSQL_TEST --ssl-ca= --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 --exec $MYSQL_TEST --ssl-ca= --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
--echo
# #
# Test that we can't open connection to server if we are using # Test that we can't open connection to server if we are using
# a nonexistent ca file # a nonexistent ca file
# #
--replace_regex /2026 SSL connection error.*/2026 SSL connection error: xxxx/
--error 1 --error 1
--exec $MYSQL_TEST --ssl-ca=nonexisting_file.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 --exec $MYSQL_TEST --ssl-ca=nonexisting_file.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
--echo
# #
# Test that we can't open connection to server if we are using # Test that we can't open connection to server if we are using
......
...@@ -101,47 +101,51 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file, ...@@ -101,47 +101,51 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file,
DBUG_ENTER("vio_set_cert_stuff"); DBUG_ENTER("vio_set_cert_stuff");
DBUG_PRINT("enter", ("ctx: 0x%lx cert_file: %s key_file: %s", DBUG_PRINT("enter", ("ctx: 0x%lx cert_file: %s key_file: %s",
(long) ctx, cert_file, key_file)); (long) ctx, cert_file, key_file));
if (cert_file)
{
if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0)
{
*error= SSL_INITERR_CERT;
DBUG_PRINT("error",("%s from file '%s'", sslGetErrString(*error), cert_file));
DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE););
fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error),
cert_file);
fflush(stderr);
DBUG_RETURN(1);
}
if (!key_file) if (!cert_file && key_file)
key_file= cert_file; cert_file= key_file;
if (!key_file && cert_file)
key_file= cert_file;
if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) if (cert_file &&
{ SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0)
*error= SSL_INITERR_KEY; {
DBUG_PRINT("error", ("%s from file '%s'", sslGetErrString(*error), key_file)); *error= SSL_INITERR_CERT;
DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); DBUG_PRINT("error",("%s from file '%s'", sslGetErrString(*error), cert_file));
fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error), DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE););
key_file); fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error),
fflush(stderr); cert_file);
DBUG_RETURN(1); fflush(stderr);
} DBUG_RETURN(1);
}
/* if (key_file &&
If we are using DSA, we can copy the parameters from the private key SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0)
Now we know that a key and cert have been set against the SSL context {
*/ *error= SSL_INITERR_KEY;
if (!SSL_CTX_check_private_key(ctx)) DBUG_PRINT("error", ("%s from file '%s'", sslGetErrString(*error), key_file));
{ DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE););
*error= SSL_INITERR_NOMATCH; fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error),
DBUG_PRINT("error", ("%s",sslGetErrString(*error))); key_file);
DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); fflush(stderr);
fprintf(stderr, "SSL error: %s\n", sslGetErrString(*error)); DBUG_RETURN(1);
fflush(stderr); }
DBUG_RETURN(1);
} /*
If we are using DSA, we can copy the parameters from the private key
Now we know that a key and cert have been set against the SSL context
*/
if (cert_file && !SSL_CTX_check_private_key(ctx))
{
*error= SSL_INITERR_NOMATCH;
DBUG_PRINT("error", ("%s",sslGetErrString(*error)));
DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE););
fprintf(stderr, "SSL error: %s\n", sslGetErrString(*error));
fflush(stderr);
DBUG_RETURN(1);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -253,6 +257,20 @@ new_VioSSLFd(const char *key_file, const char *cert_file, ...@@ -253,6 +257,20 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
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")); DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
if (ca_file || ca_path)
{
/* fail only if ca file or ca path were supplied and looking into
them fails. */
*error= SSL_INITERR_BAD_PATHS;
DBUG_PRINT("error", ("SSL_CTX_load_verify_locations failed : %s",
sslGetErrString(*error)));
report_errors();
SSL_CTX_free(ssl_fd->ssl_context);
my_free((void*)ssl_fd,MYF(0));
DBUG_RETURN(0);
}
/* otherwise go use the defaults */
if (SSL_CTX_set_default_verify_paths(ssl_fd->ssl_context) == 0) if (SSL_CTX_set_default_verify_paths(ssl_fd->ssl_context) == 0)
{ {
*error= SSL_INITERR_BAD_PATHS; *error= SSL_INITERR_BAD_PATHS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment