summaryrefslogtreecommitdiff
path: root/sql-common/client.c
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-02-15 22:50:59 +0100
committerSergei Golubchik <serg@mariadb.org>2016-02-15 22:50:59 +0100
commit271fed41061e25faa47b7a28108cf101ebb3551d (patch)
tree733bf84d468a1d47c71c87cfcee33098a090e3c5 /sql-common/client.c
parentff26d93a8c25d667709180ad13a090309631990d (diff)
parente1385f2083f782d7064db3c0059fcca45bfcb2a4 (diff)
downloadmariadb-git-271fed41061e25faa47b7a28108cf101ebb3551d.tar.gz
Merge branch '5.5' into 10.0
Diffstat (limited to 'sql-common/client.c')
-rw-r--r--sql-common/client.c89
1 files changed, 57 insertions, 32 deletions
diff --git a/sql-common/client.c b/sql-common/client.c
index 8ad50e00eaf..26f02734d25 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1,5 +1,5 @@
-/* Copyright (c) 2003, 2014, Oracle and/or its affiliates.
- Copyright (c) 2009, 2015, MariaDB
+/* Copyright (c) 2003, 2016, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2016, MariaDB
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
@@ -1755,38 +1755,39 @@ mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused)))
static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const char **errptr)
{
SSL *ssl;
- X509 *server_cert;
- X509_NAME *x509sn;
- int cn_pos;
- X509_NAME_ENTRY *cn_entry;
- ASN1_STRING *cn_asn1;
- const char *cn_str;
+ X509 *server_cert= NULL;
+ char *cn= NULL;
+ int cn_loc= -1;
+ ASN1_STRING *cn_asn1= NULL;
+ X509_NAME_ENTRY *cn_entry= NULL;
+ X509_NAME *subject= NULL;
+ int ret_validation= 1;
+
DBUG_ENTER("ssl_verify_server_cert");
DBUG_PRINT("enter", ("server_hostname: %s", server_hostname));
if (!(ssl= (SSL*)vio->ssl_arg))
{
*errptr= "No SSL pointer found";
- DBUG_RETURN(1);
+ goto error;
}
if (!server_hostname)
{
*errptr= "No server hostname supplied";
- DBUG_RETURN(1);
+ goto error;
}
if (!(server_cert= SSL_get_peer_certificate(ssl)))
{
*errptr= "Could not get server certificate";
- DBUG_RETURN(1);
+ goto error;
}
if (X509_V_OK != SSL_get_verify_result(ssl))
{
*errptr= "Failed to verify the server certificate";
- X509_free(server_cert);
- DBUG_RETURN(1);
+ goto error;
}
/*
We already know that the certificate exchanged was valid; the SSL library
@@ -1794,33 +1795,57 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const c
are what we expect.
*/
- x509sn= X509_get_subject_name(server_cert);
-
- if ((cn_pos= X509_NAME_get_index_by_NID(x509sn, NID_commonName, -1)) < 0)
- goto err;
+ /*
+ 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.
+ */
- if (!(cn_entry= X509_NAME_get_entry(x509sn, cn_pos)))
- goto err;
+ subject= X509_get_subject_name(server_cert);
+ cn_loc= X509_NAME_get_index_by_NID(subject, NID_commonName, -1);
+ if (cn_loc < 0)
+ {
+ *errptr= "Failed to get CN location in the certificate subject";
+ goto error;
+ }
- if (!(cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry)))
- goto err;
+ cn_entry= X509_NAME_get_entry(subject, cn_loc);
+ if (cn_entry == NULL)
+ {
+ *errptr= "Failed to get CN entry using CN location";
+ goto error;
+ }
- cn_str = (char *)ASN1_STRING_data(cn_asn1);
+ cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry);
+ if (cn_asn1 == NULL)
+ {
+ *errptr= "Failed to get CN from CN entry";
+ goto error;
+ }
- /* Make sure there is no embedded \0 in the CN */
- if ((size_t)ASN1_STRING_length(cn_asn1) != strlen(cn_str))
- goto err;
+ cn= (char *) ASN1_STRING_data(cn_asn1);
- if (strcmp(cn_str, server_hostname))
- goto err;
+ if ((size_t)ASN1_STRING_length(cn_asn1) != strlen(cn))
+ {
+ *errptr= "NULL embedded in the certificate CN";
+ goto error;
+ }
- X509_free (server_cert);
- DBUG_RETURN(0);
+ DBUG_PRINT("info", ("Server hostname in cert: %s", cn));
+ if (!strcmp(cn, server_hostname))
+ {
+ /* Success */
+ ret_validation= 0;
+ }
-err:
- X509_free(server_cert);
*errptr= "SSL certificate validation failure";
- DBUG_RETURN(1);
+
+error:
+ if (server_cert != NULL)
+ X509_free (server_cert);
+ DBUG_RETURN(ret_validation);
}
#endif /* HAVE_OPENSSL */