You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-08 14:02:17 +03:00
Added support for ssl server certification:
mysql_options: Added support MYSQL_OPT_SSL_VALIDATE_SERVER_CERT flag added my_ssl_verify_server_cert which extracts the hostname and compares it with mysql->host
This commit is contained in:
@@ -35,6 +35,7 @@ int my_ssl_close(Vio *vio);
|
|||||||
size_t my_ssl_write(Vio *vio, const uchar* buf, size_t size);
|
size_t my_ssl_write(Vio *vio, const uchar* buf, size_t size);
|
||||||
SSL *my_ssl_init(MYSQL *mysql);
|
SSL *my_ssl_init(MYSQL *mysql);
|
||||||
int my_ssl_connect(SSL *ssl);
|
int my_ssl_connect(SSL *ssl);
|
||||||
|
int my_ssl_verify_server_cert(SSL *ssl);
|
||||||
|
|
||||||
int my_ssl_start(MYSQL *mysql);
|
int my_ssl_start(MYSQL *mysql);
|
||||||
void my_ssl_end(void);
|
void my_ssl_end(void);
|
||||||
|
@@ -2771,6 +2771,12 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
|
||||||
|
if (*(uint *)arg)
|
||||||
|
mysql->options.client_flag |= CLIENT_SSL_VERIFY_SERVER_CERT;
|
||||||
|
else
|
||||||
|
mysql->options.client_flag &= ~CLIENT_SSL_VERIFY_SERVER_CERT;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
@@ -209,7 +209,7 @@ static int my_ssl_set_certs(SSL *ssl)
|
|||||||
int have_cert= 0;
|
int have_cert= 0;
|
||||||
MYSQL *mysql;
|
MYSQL *mysql;
|
||||||
|
|
||||||
DBUG_ENTER("my_ssl_connect");
|
DBUG_ENTER("my_ssl_set_certs");
|
||||||
|
|
||||||
/* Make sure that ssl was allocated and
|
/* Make sure that ssl was allocated and
|
||||||
ssl_system was initialized */
|
ssl_system was initialized */
|
||||||
@@ -377,7 +377,6 @@ int my_ssl_connect(SSL *ssl)
|
|||||||
|
|
||||||
if (SSL_connect(ssl) != 1)
|
if (SSL_connect(ssl) != 1)
|
||||||
{
|
{
|
||||||
printf("connect failed\n");
|
|
||||||
my_SSL_error(mysql);
|
my_SSL_error(mysql);
|
||||||
/* restore blocking mode */
|
/* restore blocking mode */
|
||||||
if (!blocking)
|
if (!blocking)
|
||||||
@@ -390,6 +389,62 @@ int my_ssl_connect(SSL *ssl)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
verify server certificate
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_ssl_verify_server_cert()
|
||||||
|
MYSQL mysql
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
1 Error
|
||||||
|
0 OK
|
||||||
|
*/
|
||||||
|
|
||||||
|
int my_ssl_verify_server_cert(SSL *ssl)
|
||||||
|
{
|
||||||
|
X509 *cert;
|
||||||
|
MYSQL *mysql;
|
||||||
|
char *p1, *p2, buf[256];
|
||||||
|
|
||||||
|
DBUG_ENTER("my_ssl_verify_server_cert");
|
||||||
|
|
||||||
|
mysql= (MYSQL *)SSL_get_app_data(ssl);
|
||||||
|
|
||||||
|
if (!mysql->host)
|
||||||
|
{
|
||||||
|
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||||
|
ER(CR_SSL_CONNECTION_ERROR),
|
||||||
|
"Invalid (empty) hostname");
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(cert= SSL_get_peer_certificate(ssl)))
|
||||||
|
{
|
||||||
|
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||||
|
ER(CR_SSL_CONNECTION_ERROR),
|
||||||
|
"Unable to get server certificate");
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_NAME_oneline(X509_get_subject_name(cert), buf, 256);
|
||||||
|
X509_free(cert);
|
||||||
|
|
||||||
|
/* Extract the server name from buffer:
|
||||||
|
Format: ....CN=/hostname/.... */
|
||||||
|
if ((p1= strstr(buf, "/CN=")))
|
||||||
|
{
|
||||||
|
p1+= 4;
|
||||||
|
if ((p2= strchr(p1, '/')))
|
||||||
|
*p2= 0;
|
||||||
|
if (!strcmp(mysql->host, p1))
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||||
|
ER(CR_SSL_CONNECTION_ERROR),
|
||||||
|
"Validation of SSL server certificate failed");
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
write to ssl socket
|
write to ssl socket
|
||||||
|
|
||||||
|
@@ -352,7 +352,10 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
|
|||||||
SSL_free(ssl);
|
SSL_free(ssl);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
/* todo: server certification verification */
|
|
||||||
|
if (mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT &&
|
||||||
|
my_ssl_verify_server_cert(ssl))
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
|
|
||||||
|
@@ -249,6 +249,36 @@ static int test_conc50(MYSQL *my)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int verify_ssl_server_cert(MYSQL *my)
|
||||||
|
{
|
||||||
|
MYSQL *mysql;
|
||||||
|
uint verify= 1;
|
||||||
|
|
||||||
|
if (check_skip_ssl())
|
||||||
|
return SKIP;
|
||||||
|
|
||||||
|
mysql= mysql_init(NULL);
|
||||||
|
FAIL_IF(!mysql, "Can't allocate memory");
|
||||||
|
|
||||||
|
mysql_ssl_set(mysql, NULL, NULL, "./certs/ca-cert.pem", NULL, NULL);
|
||||||
|
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &verify);
|
||||||
|
|
||||||
|
mysql_real_connect(mysql, hostname, username, password, schema,
|
||||||
|
port, socketname, 0);
|
||||||
|
|
||||||
|
if (!strcmp(mysql->host, "localhost"))
|
||||||
|
{
|
||||||
|
FAIL_IF(mysql_errno(mysql), "No error expected");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FAIL_IF(mysql_errno(mysql) != 2026, "Expected errno 2026");
|
||||||
|
}
|
||||||
|
mysql_close(mysql);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int test_bug62743(MYSQL *my)
|
static int test_bug62743(MYSQL *my)
|
||||||
{
|
{
|
||||||
MYSQL *mysql;
|
MYSQL *mysql;
|
||||||
@@ -272,6 +302,7 @@ static int test_bug62743(MYSQL *my)
|
|||||||
struct my_tests_st my_tests[] = {
|
struct my_tests_st my_tests[] = {
|
||||||
{"test_ssl", test_ssl, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_ssl", test_ssl, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_conc50", test_conc50, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_conc50", test_conc50, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
|
{"verify_ssl_server_cert", verify_ssl_server_cert, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_bug62743", test_bug62743, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_bug62743", test_bug62743, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_phpbug51647", test_phpbug51647, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
{"test_phpbug51647", test_phpbug51647, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
{"test_ssl_cipher", test_ssl_cipher, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
{"test_ssl_cipher", test_ssl_cipher, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
|
Reference in New Issue
Block a user