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
CONC-286:
- Force TLS/SSL connection if finger print options were specified - Allow hex finger prints with colon separated 2 digit numbers
This commit is contained in:
@@ -119,21 +119,48 @@ my_bool ma_pvio_tls_get_protocol_version(MARIADB_TLS *ctls, struct st_ssl_versio
|
|||||||
return ma_tls_get_protocol_version(ctls, version);
|
return ma_tls_get_protocol_version(ctls, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
static my_bool ma_pvio_tls_compare_fp(const char *fp1, unsigned int fp1_len,
|
static char ma_hex2int(char c)
|
||||||
const char *fp2, unsigned int fp2_len)
|
|
||||||
{
|
{
|
||||||
char hexstr[64];
|
if (c >= '0' && c <= '9')
|
||||||
|
return c - '0';
|
||||||
|
if (c >= 'A' && c <= 'F')
|
||||||
|
return 10 + c - 'A';
|
||||||
|
if (c >= 'a' && c <= 'f')
|
||||||
|
return 10 + c - 'a';
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
fp1_len= (unsigned int)mysql_hex_string(hexstr, fp1, fp1_len);
|
static my_bool ma_pvio_tls_compare_fp(const char *cert_fp,
|
||||||
if (fp1_len != fp2_len)
|
unsigned int cert_fp_len,
|
||||||
|
const char *fp, unsigned int fp_len)
|
||||||
|
{
|
||||||
|
char *p= (char *)fp,
|
||||||
|
*c;
|
||||||
|
|
||||||
|
/* check length */
|
||||||
|
if (cert_fp_len != 20)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#ifdef WIN32
|
/* We support two formats:
|
||||||
if (strnicmp(hexstr, fp2, fp1_len) != 0)
|
2 digits hex numbers, separated by colons (length=59)
|
||||||
#else
|
20 * 2 digits hex numbers without separators (length = 40)
|
||||||
if (strncasecmp(hexstr, fp2, fp1_len) != 0)
|
*/
|
||||||
#endif
|
if (fp_len != (strchr(fp, ':') ? 59 : 40))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
for(c= (char *)cert_fp; c < cert_fp + cert_fp_len; c++)
|
||||||
|
{
|
||||||
|
char d1, d2;
|
||||||
|
if (*p == ':')
|
||||||
|
p++;
|
||||||
|
if (p - fp > fp_len -1)
|
||||||
|
return 1;
|
||||||
|
if ((d1 = ma_hex2int(*p)) == - 1 ||
|
||||||
|
(d2 = ma_hex2int(*(p+1))) == -1 ||
|
||||||
|
(char)(d1 * 16 + d2) != *c)
|
||||||
|
return 1;
|
||||||
|
p+= 2;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2983,10 +2983,12 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
case MARIADB_OPT_SSL_FP:
|
case MARIADB_OPT_SSL_FP:
|
||||||
case MARIADB_OPT_TLS_PEER_FP:
|
case MARIADB_OPT_TLS_PEER_FP:
|
||||||
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, tls_fp, (char *)arg1);
|
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, tls_fp, (char *)arg1);
|
||||||
|
mysql->options.use_ssl= 1;
|
||||||
break;
|
break;
|
||||||
case MARIADB_OPT_SSL_FP_LIST:
|
case MARIADB_OPT_SSL_FP_LIST:
|
||||||
case MARIADB_OPT_TLS_PEER_FP_LIST:
|
case MARIADB_OPT_TLS_PEER_FP_LIST:
|
||||||
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, tls_fp_list, (char *)arg1);
|
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, tls_fp_list, (char *)arg1);
|
||||||
|
mysql->options.use_ssl= 1;
|
||||||
break;
|
break;
|
||||||
case MARIADB_OPT_TLS_PASSPHRASE:
|
case MARIADB_OPT_TLS_PASSPHRASE:
|
||||||
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, tls_pw, (char *)arg1);
|
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, tls_pw, (char *)arg1);
|
||||||
|
@@ -1347,6 +1347,9 @@ static int my_verify_callback(gnutls_session_t ssl)
|
|||||||
|
|
||||||
if (status & GNUTLS_CERT_INVALID)
|
if (status & GNUTLS_CERT_INVALID)
|
||||||
{
|
{
|
||||||
|
char errbuf[100];
|
||||||
|
snprintf(errbuf, 99, "CA Verification failed (Status: %d)", status);
|
||||||
|
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, errbuf);
|
||||||
return GNUTLS_E_CERTIFICATE_ERROR;
|
return GNUTLS_E_CERTIFICATE_ERROR;
|
||||||
}
|
}
|
||||||
/* Up to here the process is the same for X.509 certificates and
|
/* Up to here the process is the same for X.509 certificates and
|
||||||
|
@@ -50,8 +50,12 @@ int check_skip_ssl()
|
|||||||
}
|
}
|
||||||
if (!(ssldir= getenv("SECURE_LOAD_PATH")))
|
if (!(ssldir= getenv("SECURE_LOAD_PATH")))
|
||||||
{
|
{
|
||||||
diag("certificate directory not found");
|
ssldir= "@CERT_PATH@";
|
||||||
return 1;
|
if (!strlen(ssldir))
|
||||||
|
{
|
||||||
|
diag("certificate directory not found");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
snprintf(sslcert, FNLEN - 1, "%s/%s", ssldir, "client-cert.pem");
|
snprintf(sslcert, FNLEN - 1, "%s/%s", ssldir, "client-cert.pem");
|
||||||
snprintf(sslkey, FNLEN - 1, "%s/%s", ssldir, "client-key.pem");
|
snprintf(sslkey, FNLEN - 1, "%s/%s", ssldir, "client-key.pem");
|
||||||
@@ -744,6 +748,12 @@ static int test_ssl_fp(MYSQL *unused __attribute__((unused)))
|
|||||||
if (check_skip_ssl())
|
if (check_skip_ssl())
|
||||||
return SKIP;
|
return SKIP;
|
||||||
|
|
||||||
|
if (!ssl_cert_finger_print[0])
|
||||||
|
{
|
||||||
|
diag("No fingerprint available");
|
||||||
|
return SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
my= mysql_init(NULL);
|
my= mysql_init(NULL);
|
||||||
FAIL_IF(!my, "mysql_init() failed");
|
FAIL_IF(!my, "mysql_init() failed");
|
||||||
|
|
||||||
@@ -780,6 +790,11 @@ static int test_ssl_fp_list(MYSQL *unused __attribute__((unused)))
|
|||||||
if (check_skip_ssl())
|
if (check_skip_ssl())
|
||||||
return SKIP;
|
return SKIP;
|
||||||
|
|
||||||
|
if (!ssl_cert_finger_print[0])
|
||||||
|
{
|
||||||
|
diag("No fingerprint available");
|
||||||
|
return SKIP;
|
||||||
|
}
|
||||||
my= mysql_init(NULL);
|
my= mysql_init(NULL);
|
||||||
FAIL_IF(!my, "mysql_init() failed");
|
FAIL_IF(!my, "mysql_init() failed");
|
||||||
|
|
||||||
@@ -1091,8 +1106,35 @@ static int drop_ssl_user(MYSQL *mysql)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_conc286(MYSQL *unused __attribute__((unused)))
|
||||||
|
{
|
||||||
|
MYSQL *my;
|
||||||
|
|
||||||
|
if (check_skip_ssl())
|
||||||
|
return SKIP;
|
||||||
|
|
||||||
|
if (!ssl_cert_finger_print[0])
|
||||||
|
{
|
||||||
|
diag("No fingerprint available");
|
||||||
|
return SKIP;
|
||||||
|
}
|
||||||
|
my= mysql_init(NULL);
|
||||||
|
FAIL_IF(!my, "mysql_init() failed");
|
||||||
|
|
||||||
|
mysql_options(my, MARIADB_OPT_SSL_FP, ssl_cert_finger_print);
|
||||||
|
|
||||||
|
FAIL_IF(!mysql_real_connect(my, hostname, username, password, schema,
|
||||||
|
port, socketname, 0), mysql_error(my));
|
||||||
|
|
||||||
|
FAIL_IF(check_cipher(my) != 0, "Invalid cipher");
|
||||||
|
|
||||||
|
mysql_close(my);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
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_conc286", test_conc286, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_ssl_timeout", test_ssl_timeout, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_ssl_timeout", test_ssl_timeout, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_openssl_1", test_openssl_1, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_openssl_1", test_openssl_1, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
#ifndef HAVE_SCHANNEL
|
#ifndef HAVE_SCHANNEL
|
||||||
|
Reference in New Issue
Block a user