You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-07 02:42:49 +03:00
MDEV-14101: tls-version
Client part of MDEV-14101: Add support for tls-version, via mysql_options(mysql, MARIADB_OPT_TLS_VERSION, value) Accepted values are "TLSv1.1", "TLSv1.2" and "TLSv1.3". Fixed testcase openssl_1 for schannel
This commit is contained in:
@@ -10,6 +10,14 @@ enum enum_pvio_tls_type {
|
|||||||
SSL_TYPE_GNUTLS
|
SSL_TYPE_GNUTLS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define PROTOCOL_SSLV3 0
|
||||||
|
#define PROTOCOL_TLS_1_0 1
|
||||||
|
#define PROTOCOL_TLS_1_1 2
|
||||||
|
#define PROTOCOL_TLS_1_2 3
|
||||||
|
#define PROTOCOL_TLS_1_3 4
|
||||||
|
#define PROTOCOL_UNKNOWN 5
|
||||||
|
#define PROTOCOL_MAX PROTOCOL_TLS_1_3
|
||||||
|
|
||||||
#define TLS_VERSION_LENGTH 64
|
#define TLS_VERSION_LENGTH 64
|
||||||
extern char tls_library_version[TLS_VERSION_LENGTH];
|
extern char tls_library_version[TLS_VERSION_LENGTH];
|
||||||
|
|
||||||
@@ -19,11 +27,6 @@ typedef struct st_ma_pvio_tls {
|
|||||||
void *ssl;
|
void *ssl;
|
||||||
} MARIADB_TLS;
|
} MARIADB_TLS;
|
||||||
|
|
||||||
struct st_ssl_version {
|
|
||||||
unsigned int iversion;
|
|
||||||
char *cversion;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Function prototypes */
|
/* Function prototypes */
|
||||||
|
|
||||||
/* ma_tls_start
|
/* ma_tls_start
|
||||||
@@ -133,15 +136,15 @@ const char *ma_tls_get_cipher(MARIADB_TLS *ssl);
|
|||||||
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, char *fp, unsigned int fp_len);
|
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, char *fp, unsigned int fp_len);
|
||||||
|
|
||||||
/* ma_tls_get_protocol_version
|
/* ma_tls_get_protocol_version
|
||||||
returns protocol version in use
|
returns protocol version number in use
|
||||||
Parameter:
|
Parameter:
|
||||||
MARIADB_TLS MariaDB SSL container
|
MARIADB_TLS MariaDB SSL container
|
||||||
version pointer to ssl version info
|
|
||||||
Returns:
|
Returns:
|
||||||
0 success
|
protocol number
|
||||||
1 error
|
|
||||||
*/
|
*/
|
||||||
my_bool ma_tls_get_protocol_version(MARIADB_TLS *ctls, struct st_ssl_version *version);
|
int ma_tls_get_protocol_version(MARIADB_TLS *ctls);
|
||||||
|
const char *ma_pvio_tls_get_protocol_version(MARIADB_TLS *ctls);
|
||||||
|
int ma_pvio_tls_get_protocol_version_id(MARIADB_TLS *ctls);
|
||||||
|
|
||||||
/* Function prototypes */
|
/* Function prototypes */
|
||||||
MARIADB_TLS *ma_pvio_tls_init(MYSQL *mysql);
|
MARIADB_TLS *ma_pvio_tls_init(MYSQL *mysql);
|
||||||
@@ -153,7 +156,6 @@ int ma_pvio_tls_verify_server_cert(MARIADB_TLS *ctls);
|
|||||||
const char *ma_pvio_tls_cipher(MARIADB_TLS *ctls);
|
const char *ma_pvio_tls_cipher(MARIADB_TLS *ctls);
|
||||||
my_bool ma_pvio_tls_check_fp(MARIADB_TLS *ctls, const char *fp, const char *fp_list);
|
my_bool ma_pvio_tls_check_fp(MARIADB_TLS *ctls, const char *fp, const char *fp_list);
|
||||||
my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio);
|
my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio);
|
||||||
my_bool ma_pvio_tls_get_protocol_version(MARIADB_TLS *ctls, struct st_ssl_version *version);
|
|
||||||
void ma_pvio_tls_end();
|
void ma_pvio_tls_end();
|
||||||
|
|
||||||
#endif /* _ma_tls_h_ */
|
#endif /* _ma_tls_h_ */
|
||||||
|
@@ -204,6 +204,7 @@ extern const char *SQLSTATE_UNKNOWN;
|
|||||||
MYSQL_OPT_SSL_ENFORCE,
|
MYSQL_OPT_SSL_ENFORCE,
|
||||||
MYSQL_OPT_MAX_ALLOWED_PACKET,
|
MYSQL_OPT_MAX_ALLOWED_PACKET,
|
||||||
MYSQL_OPT_NET_BUFFER_LENGTH,
|
MYSQL_OPT_NET_BUFFER_LENGTH,
|
||||||
|
MYSQL_OPT_TLS_VERSION,
|
||||||
|
|
||||||
/* MariaDB specific */
|
/* MariaDB specific */
|
||||||
MYSQL_PROGRESS_CALLBACK=5999,
|
MYSQL_PROGRESS_CALLBACK=5999,
|
||||||
|
@@ -51,7 +51,8 @@
|
|||||||
my_bool ma_tls_initialized= FALSE;
|
my_bool ma_tls_initialized= FALSE;
|
||||||
unsigned int mariadb_deinitialize_ssl= 1;
|
unsigned int mariadb_deinitialize_ssl= 1;
|
||||||
|
|
||||||
const char *ssl_protocol_version[5]= {"TLS1.0", "TLS1.1", "TLS1.2"};
|
const char *tls_protocol_version[]=
|
||||||
|
{"SSLv3", "TLSv1.0", "TLSv1.1", "TLSv1.2", "TLSv1.3", "Unknown"};
|
||||||
|
|
||||||
MARIADB_TLS *ma_pvio_tls_init(MYSQL *mysql)
|
MARIADB_TLS *ma_pvio_tls_init(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
@@ -114,9 +115,19 @@ void ma_pvio_tls_end()
|
|||||||
ma_tls_end();
|
ma_tls_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
my_bool ma_pvio_tls_get_protocol_version(MARIADB_TLS *ctls, struct st_ssl_version *version)
|
int ma_pvio_tls_get_protocol_version_id(MARIADB_TLS *ctls)
|
||||||
{
|
{
|
||||||
return ma_tls_get_protocol_version(ctls, version);
|
return ma_tls_get_protocol_version(ctls);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *ma_pvio_tls_get_protocol_version(MARIADB_TLS *ctls)
|
||||||
|
{
|
||||||
|
int version;
|
||||||
|
|
||||||
|
version= ma_tls_get_protocol_version(ctls);
|
||||||
|
if (version < 0 || version > PROTOCOL_MAX)
|
||||||
|
return tls_protocol_version[PROTOCOL_UNKNOWN];
|
||||||
|
return tls_protocol_version[version];
|
||||||
}
|
}
|
||||||
|
|
||||||
static char ma_hex2int(char c)
|
static char ma_hex2int(char c)
|
||||||
|
@@ -135,7 +135,7 @@ struct st_mariadb_methods MARIADB_DEFAULT_METHODS;
|
|||||||
#define native_password_plugin_name "mysql_native_password"
|
#define native_password_plugin_name "mysql_native_password"
|
||||||
|
|
||||||
#define IS_CONNHDLR_ACTIVE(mysql)\
|
#define IS_CONNHDLR_ACTIVE(mysql)\
|
||||||
(((mysql)->extension->conn_hdlr))
|
((mysql)->extension && (mysql)->extension->conn_hdlr)
|
||||||
|
|
||||||
static void end_server(MYSQL *mysql);
|
static void end_server(MYSQL *mysql);
|
||||||
static void mysql_close_memory(MYSQL *mysql);
|
static void mysql_close_memory(MYSQL *mysql);
|
||||||
@@ -644,7 +644,8 @@ struct st_default_options mariadb_defaults[] =
|
|||||||
{MARIADB_OPT_SSL_FP, MARIADB_OPTION_STR, "ssl-fp"},
|
{MARIADB_OPT_SSL_FP, MARIADB_OPTION_STR, "ssl-fp"},
|
||||||
{MARIADB_OPT_SSL_FP_LIST, MARIADB_OPTION_STR, "ssl-fp-list"},
|
{MARIADB_OPT_SSL_FP_LIST, MARIADB_OPTION_STR, "ssl-fp-list"},
|
||||||
{MARIADB_OPT_SSL_FP_LIST, MARIADB_OPTION_STR, "ssl-fplist"},
|
{MARIADB_OPT_SSL_FP_LIST, MARIADB_OPTION_STR, "ssl-fplist"},
|
||||||
{MARIADB_OPT_TLS_PASSPHRASE, MARIADB_OPTION_STR, "ssl_passphrase"},
|
{MARIADB_OPT_TLS_PASSPHRASE, MARIADB_OPTION_STR, "ssl-passphrase"},
|
||||||
|
{MARIADB_OPT_TLS_VERSION, MARIADB_OPTION_STR, "tls_version"},
|
||||||
{MYSQL_OPT_BIND, MARIADB_OPTION_STR, "bind-address"},
|
{MYSQL_OPT_BIND, MARIADB_OPTION_STR, "bind-address"},
|
||||||
{0, 0, NULL}
|
{0, 0, NULL}
|
||||||
};
|
};
|
||||||
@@ -3003,6 +3004,10 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
OPT_SET_EXTENDED_VALUE(&mysql->options, proxy_header_len, arg2);
|
OPT_SET_EXTENDED_VALUE(&mysql->options, proxy_header_len, arg2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MARIADB_OPT_TLS_VERSION:
|
||||||
|
case MYSQL_OPT_TLS_VERSION:
|
||||||
|
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, tls_version, (char *)arg1);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return(-1);
|
return(-1);
|
||||||
@@ -3685,11 +3690,7 @@ my_bool STDCALL mariadb_get_infov(MYSQL *mysql, enum mariadb_value value, void *
|
|||||||
case MARIADB_CONNECTION_TLS_VERSION:
|
case MARIADB_CONNECTION_TLS_VERSION:
|
||||||
#ifdef HAVE_TLS
|
#ifdef HAVE_TLS
|
||||||
if (mysql && mysql->net.pvio && mysql->net.pvio->ctls)
|
if (mysql && mysql->net.pvio && mysql->net.pvio->ctls)
|
||||||
{
|
*((char **)arg)= (char *)ma_pvio_tls_get_protocol_version(mysql->net.pvio->ctls);
|
||||||
struct st_ssl_version version;
|
|
||||||
if (!ma_pvio_tls_get_protocol_version(mysql->net.pvio->ctls, &version))
|
|
||||||
*((char **)arg)= version.cversion;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
goto error;
|
goto error;
|
||||||
@@ -3697,11 +3698,7 @@ my_bool STDCALL mariadb_get_infov(MYSQL *mysql, enum mariadb_value value, void *
|
|||||||
case MARIADB_CONNECTION_TLS_VERSION_ID:
|
case MARIADB_CONNECTION_TLS_VERSION_ID:
|
||||||
#ifdef HAVE_TLS
|
#ifdef HAVE_TLS
|
||||||
if (mysql && mysql->net.pvio && mysql->net.pvio->ctls)
|
if (mysql && mysql->net.pvio && mysql->net.pvio->ctls)
|
||||||
{
|
*((unsigned int *)arg)= ma_pvio_tls_get_protocol_version_id(mysql->net.pvio->ctls);
|
||||||
struct st_ssl_version version;
|
|
||||||
if (!ma_pvio_tls_get_protocol_version(mysql->net.pvio->ctls, &version))
|
|
||||||
*((unsigned int *)arg)= version.iversion;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
goto error;
|
goto error;
|
||||||
|
@@ -1006,17 +1006,46 @@ void ma_tls_end()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ma_gnutls_set_ciphers(gnutls_session_t ssl, char *cipher_str)
|
static size_t ma_gnutls_get_protocol_version(const char *tls_version_option,
|
||||||
|
char *priority_string,
|
||||||
|
size_t prio_len)
|
||||||
|
{
|
||||||
|
char tls_versions[128];
|
||||||
|
|
||||||
|
tls_versions[0]= 0;
|
||||||
|
if (!tls_version_option || !tls_version_option[0])
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
|
||||||
|
if (strstr(tls_version_option, "TLSv1.0"))
|
||||||
|
strcat(tls_versions, ":+VERS-TLS1.0");
|
||||||
|
if (strstr(tls_version_option, "TLSv1.1"))
|
||||||
|
strcat(tls_versions, ":+VERS-TLS1.1");
|
||||||
|
if (strstr(tls_version_option, "TLSv1.2"))
|
||||||
|
strcat(tls_versions, ":+VERS-TLS1.2");
|
||||||
|
end:
|
||||||
|
if (tls_versions[0])
|
||||||
|
snprintf(priority_string, prio_len - 1, "NORMAL:-VERS-TLS-ALL%s", tls_versions);
|
||||||
|
else
|
||||||
|
strncpy(priority_string, "NORMAL", prio_len - 1);
|
||||||
|
return strlen(priority_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ma_gnutls_set_ciphers(gnutls_session_t ssl,
|
||||||
|
const char *cipher_str,
|
||||||
|
const char *tls_version)
|
||||||
{
|
{
|
||||||
const char *err;
|
const char *err;
|
||||||
char *token;
|
char *token;
|
||||||
#define PRIO_SIZE 1024
|
#define PRIO_SIZE 1024
|
||||||
char prio[PRIO_SIZE];
|
char prio[PRIO_SIZE];
|
||||||
|
|
||||||
if (!cipher_str)
|
ma_gnutls_get_protocol_version(tls_version, prio, PRIO_SIZE);
|
||||||
return gnutls_priority_set_direct(ssl, "NORMAL", &err);
|
|
||||||
|
|
||||||
token= strtok(cipher_str, ":");
|
if (!cipher_str)
|
||||||
|
return gnutls_priority_set_direct(ssl, prio, &err);
|
||||||
|
|
||||||
|
token= strtok((char *)cipher_str, ":");
|
||||||
|
|
||||||
strcpy(prio, "NONE:+VERS-TLS-ALL:+SIGN-ALL:+COMP-NULL");
|
strcpy(prio, "NONE:+VERS-TLS-ALL:+SIGN-ALL:+COMP-NULL");
|
||||||
|
|
||||||
@@ -1180,7 +1209,7 @@ void *ma_tls_init(MYSQL *mysql)
|
|||||||
/*
|
/*
|
||||||
gnutls_certificate_set_retrieve_function2(GNUTLS_xcred, client_cert_callback);
|
gnutls_certificate_set_retrieve_function2(GNUTLS_xcred, client_cert_callback);
|
||||||
*/
|
*/
|
||||||
ssl_error= ma_gnutls_set_ciphers(ssl, mysql->options.ssl_cipher);
|
ssl_error= ma_gnutls_set_ciphers(ssl, mysql->options.ssl_cipher, mysql->options.extension ? mysql->options.extension->tls_version : NULL);
|
||||||
if (ssl_error < 0)
|
if (ssl_error < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@@ -1427,19 +1456,17 @@ unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, char *fp, unsigned int l
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||||
ER(CR_SSL_CONNECTION_ERROR),
|
ER(CR_SSL_CONNECTION_ERROR),
|
||||||
"Finger print buffer too small");
|
"Finger print buffer too small");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my_bool ma_tls_get_protocol_version(MARIADB_TLS *ctls, struct st_ssl_version *version)
|
int ma_tls_get_protocol_version(MARIADB_TLS *ctls)
|
||||||
{
|
{
|
||||||
if (!ctls || !ctls->ssl)
|
if (!ctls || !ctls->ssl)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
version->iversion= gnutls_protocol_get_version(ctls->ssl);
|
return gnutls_protocol_get_version(ctls->ssl) - 1;
|
||||||
version->cversion= (char *)gnutls_protocol_get_name(version->iversion);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif /* HAVE_GNUTLS */
|
#endif /* HAVE_GNUTLS */
|
||||||
|
@@ -851,7 +851,7 @@ my_bool ma_schannel_verify_certs(MARIADB_TLS *ctls)
|
|||||||
|
|
||||||
if (crl_file && !(crl_ctx= (CRL_CONTEXT *)ma_schannel_create_crl_context(pvio, mysql->options.extension->ssl_crl)))
|
if (crl_file && !(crl_ctx= (CRL_CONTEXT *)ma_schannel_create_crl_context(pvio, mysql->options.extension->ssl_crl)))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if ((sRet= QueryContextAttributes(&sctx->ctxt, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pServerCert)) != SEC_E_OK)
|
if ((sRet= QueryContextAttributes(&sctx->ctxt, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pServerCert)) != SEC_E_OK)
|
||||||
{
|
{
|
||||||
ma_schannel_set_sec_error(pvio, sRet);
|
ma_schannel_set_sec_error(pvio, sRet);
|
||||||
@@ -978,8 +978,8 @@ ssize_t ma_schannel_write_encrypt(MARIADB_PVIO *pvio,
|
|||||||
|
|
||||||
extern char *ssl_protocol_version[5];
|
extern char *ssl_protocol_version[5];
|
||||||
|
|
||||||
/* {{{ ma_tls_get_protocol_version(MARIADB_TLS *ctls, struct st_ssl_version *version) */
|
/* {{{ ma_tls_get_protocol_version(MARIADB_TLS *ctls) */
|
||||||
my_bool ma_tls_get_protocol_version(MARIADB_TLS *ctls, struct st_ssl_version *version)
|
int ma_tls_get_protocol_version(MARIADB_TLS *ctls)
|
||||||
{
|
{
|
||||||
SC_CTX *sctx;
|
SC_CTX *sctx;
|
||||||
SecPkgContext_ConnectionInfo ConnectionInfo;
|
SecPkgContext_ConnectionInfo ConnectionInfo;
|
||||||
@@ -989,27 +989,20 @@ my_bool ma_tls_get_protocol_version(MARIADB_TLS *ctls, struct st_ssl_version *ve
|
|||||||
sctx= (SC_CTX *)ctls->ssl;
|
sctx= (SC_CTX *)ctls->ssl;
|
||||||
|
|
||||||
if (QueryContextAttributes(&sctx->ctxt, SECPKG_ATTR_CONNECTION_INFO, &ConnectionInfo) != SEC_E_OK)
|
if (QueryContextAttributes(&sctx->ctxt, SECPKG_ATTR_CONNECTION_INFO, &ConnectionInfo) != SEC_E_OK)
|
||||||
return 1;
|
return -1;
|
||||||
|
|
||||||
switch(ConnectionInfo.dwProtocol)
|
switch(ConnectionInfo.dwProtocol)
|
||||||
{
|
{
|
||||||
case SP_PROT_SSL3_CLIENT:
|
case SP_PROT_SSL3_CLIENT:
|
||||||
version->iversion= 1;
|
return PROTOCOL_SSLV3;
|
||||||
break;
|
|
||||||
case SP_PROT_TLS1_CLIENT:
|
case SP_PROT_TLS1_CLIENT:
|
||||||
version->iversion= 2;
|
return PROTOCOL_TLS_1_0;
|
||||||
break;
|
|
||||||
case SP_PROT_TLS1_1_CLIENT:
|
case SP_PROT_TLS1_1_CLIENT:
|
||||||
version->iversion= 3;
|
return PROTOCOL_TLS_1_1;
|
||||||
break;
|
|
||||||
case SP_PROT_TLS1_2_CLIENT:
|
case SP_PROT_TLS1_2_CLIENT:
|
||||||
version->iversion= 4;
|
return PROTOCOL_TLS_1_2;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
version->iversion= 0;
|
return -1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
version->cversion= ssl_protocol_version[version->iversion];
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
@@ -72,6 +72,30 @@ static int ma_bio_write(BIO *h, const char *buf, int size);
|
|||||||
static BIO_METHOD ma_BIO_method;
|
static BIO_METHOD ma_BIO_method;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static long ma_tls_version_options(const char *version)
|
||||||
|
{
|
||||||
|
long protocol_options,
|
||||||
|
disable_all_protocols;
|
||||||
|
|
||||||
|
protocol_options= disable_all_protocols=
|
||||||
|
SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
|
||||||
|
|
||||||
|
if (!version)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (strstr(version, "TLSv1.0"))
|
||||||
|
protocol_options&= ~SSL_OP_NO_TLSv1;
|
||||||
|
if (strstr(version, "TLSv1.1"))
|
||||||
|
protocol_options&= ~SSL_OP_NO_TLSv1_1;
|
||||||
|
if (strstr(version, "TLSv1.2"))
|
||||||
|
protocol_options&= ~SSL_OP_NO_TLSv1_2;
|
||||||
|
|
||||||
|
if (protocol_options != disable_all_protocols)
|
||||||
|
return protocol_options;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void ma_tls_set_error(MYSQL *mysql)
|
static void ma_tls_set_error(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
ulong ssl_errno= ERR_get_error();
|
ulong ssl_errno= ERR_get_error();
|
||||||
@@ -488,6 +512,7 @@ void *ma_tls_init(MYSQL *mysql)
|
|||||||
{
|
{
|
||||||
SSL *ssl= NULL;
|
SSL *ssl= NULL;
|
||||||
SSL_CTX *ctx= NULL;
|
SSL_CTX *ctx= NULL;
|
||||||
|
long options= SSL_OP_ALL;
|
||||||
#ifdef HAVE_TLS_SESSION_CACHE
|
#ifdef HAVE_TLS_SESSION_CACHE
|
||||||
MA_SSL_SESSION *session= ma_tls_get_session(mysql);
|
MA_SSL_SESSION *session= ma_tls_get_session(mysql);
|
||||||
#endif
|
#endif
|
||||||
@@ -499,7 +524,9 @@ void *ma_tls_init(MYSQL *mysql)
|
|||||||
if (!(ctx= SSL_CTX_new(SSLv23_client_method())))
|
if (!(ctx= SSL_CTX_new(SSLv23_client_method())))
|
||||||
#endif
|
#endif
|
||||||
goto error;
|
goto error;
|
||||||
SSL_CTX_set_options(ctx, SSL_OP_ALL);
|
if (mysql->options.extension)
|
||||||
|
options|= ma_tls_version_options(mysql->options.extension->tls_version);
|
||||||
|
SSL_CTX_set_options(ctx, options);
|
||||||
#ifdef HAVE_TLS_SESSION_CACHE
|
#ifdef HAVE_TLS_SESSION_CACHE
|
||||||
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT);
|
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT);
|
||||||
ma_tls_sessions= (MA_SSL_SESSION *)calloc(1, sizeof(struct st_ma_tls_session) * ma_tls_session_cache_size);
|
ma_tls_sessions= (MA_SSL_SESSION *)calloc(1, sizeof(struct st_ma_tls_session) * ma_tls_session_cache_size);
|
||||||
@@ -762,18 +789,11 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern char *ssl_protocol_version[5];
|
int ma_tls_get_protocol_version(MARIADB_TLS *ctls)
|
||||||
|
|
||||||
my_bool ma_tls_get_protocol_version(MARIADB_TLS *ctls, struct st_ssl_version *version)
|
|
||||||
{
|
{
|
||||||
SSL *ssl;
|
|
||||||
|
|
||||||
if (!ctls || !ctls->ssl)
|
if (!ctls || !ctls->ssl)
|
||||||
return 1;
|
return -1;
|
||||||
|
|
||||||
ssl = (SSL *)ctls->ssl;
|
return SSL_version(ctls->ssl) & 0xFF;
|
||||||
version->iversion= SSL_version(ssl) - TLS1_VERSION;
|
|
||||||
version->cversion= ssl_protocol_version[version->iversion];
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -372,11 +372,11 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
|||||||
}
|
}
|
||||||
if (mysql->options.extension && mysql->options.extension->tls_version)
|
if (mysql->options.extension && mysql->options.extension->tls_version)
|
||||||
{
|
{
|
||||||
if (strstr("TLSv1.0", mysql->options.extension->tls_version))
|
if (strstr(mysql->options.extension->tls_version, "TLSv1.0"))
|
||||||
Cred.grbitEnabledProtocols|= SP_PROT_TLS1_0_CLIENT;
|
Cred.grbitEnabledProtocols|= SP_PROT_TLS1_0_CLIENT;
|
||||||
if (strstr("TLSv1.1", mysql->options.extension->tls_version))
|
if (strstr(mysql->options.extension->tls_version, "TLSv1.1"))
|
||||||
Cred.grbitEnabledProtocols|= SP_PROT_TLS1_1_CLIENT;
|
Cred.grbitEnabledProtocols|= SP_PROT_TLS1_1_CLIENT;
|
||||||
if (strstr("TLSv1.2", mysql->options.extension->tls_version))
|
if (strstr(mysql->options.extension->tls_version, "TLSv1.2"))
|
||||||
Cred.grbitEnabledProtocols|= SP_PROT_TLS1_2_CLIENT;
|
Cred.grbitEnabledProtocols|= SP_PROT_TLS1_2_CLIENT;
|
||||||
}
|
}
|
||||||
if (!Cred.grbitEnabledProtocols)
|
if (!Cred.grbitEnabledProtocols)
|
||||||
|
@@ -41,6 +41,9 @@ IF(WITH_SSL)
|
|||||||
FILE(READ ${CERT_PATH}/server-cert.sha1 CERT_FINGER_PRINT)
|
FILE(READ ${CERT_PATH}/server-cert.sha1 CERT_FINGER_PRINT)
|
||||||
STRING(REPLACE "\n" "" CERT_FINGER_PRINT "${CERT_FINGER_PRINT}")
|
STRING(REPLACE "\n" "" CERT_FINGER_PRINT "${CERT_FINGER_PRINT}")
|
||||||
SET(API_TESTS ${API_TESTS} "ssl")
|
SET(API_TESTS ${API_TESTS} "ssl")
|
||||||
|
IF(WIN32)
|
||||||
|
STRING(REPLACE "\\" "\\\\" CERT_PATH ${CERT_PATH})
|
||||||
|
ENDIF()
|
||||||
CONFIGURE_FILE(${CC_SOURCE_DIR}/unittest/libmariadb/ssl.c.in
|
CONFIGURE_FILE(${CC_SOURCE_DIR}/unittest/libmariadb/ssl.c.in
|
||||||
${CC_BINARY_DIR}/unittest/libmariadb/ssl.c)
|
${CC_BINARY_DIR}/unittest/libmariadb/ssl.c)
|
||||||
ADD_EXECUTABLE(ssl ${CC_BINARY_DIR}/unittest/libmariadb/ssl.c)
|
ADD_EXECUTABLE(ssl ${CC_BINARY_DIR}/unittest/libmariadb/ssl.c)
|
||||||
|
@@ -112,7 +112,7 @@ static int test_ssl(MYSQL *mysql)
|
|||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
char *tls_library;
|
char *tls_library;
|
||||||
|
|
||||||
rc= mysql_query(mysql, "SELECT @@have_ssl UNION SELECT @@have_openssl");
|
rc= mysql_query(mysql, "SELECT @@have_ssl, @@have_openssl");
|
||||||
check_mysql_rc(rc, mysql);
|
check_mysql_rc(rc, mysql);
|
||||||
|
|
||||||
res= mysql_store_result(mysql);
|
res= mysql_store_result(mysql);
|
||||||
@@ -422,7 +422,7 @@ static int test_conc50(MYSQL *unused __attribute__((unused)))
|
|||||||
mysql= mysql_init(NULL);
|
mysql= mysql_init(NULL);
|
||||||
FAIL_IF(!mysql, "Can't allocate memory");
|
FAIL_IF(!mysql, "Can't allocate memory");
|
||||||
|
|
||||||
mysql_ssl_set(mysql, NULL, NULL, "/home/georg/work/mariadb/bb-10.2-georg/unittest/libmariadb/certs/my_cert.pem", NULL, NULL);
|
mysql_ssl_set(mysql, NULL, NULL, "./non_exisiting_cert.pem", NULL, NULL);
|
||||||
|
|
||||||
mysql_real_connect(mysql, hostname, ssluser, sslpw, schema,
|
mysql_real_connect(mysql, hostname, ssluser, sslpw, schema,
|
||||||
port, socketname, 0);
|
port, socketname, 0);
|
||||||
@@ -471,7 +471,7 @@ static int test_conc50_2(MYSQL *unused __attribute__((unused)))
|
|||||||
mysql= mysql_init(NULL);
|
mysql= mysql_init(NULL);
|
||||||
FAIL_IF(!mysql, "Can't allocate memory");
|
FAIL_IF(!mysql, "Can't allocate memory");
|
||||||
|
|
||||||
mysql_ssl_set(mysql, NULL, NULL, "/home/georg/work/mariadb/bb-10.2-georg/unittest/libmariadb/certs/not-found.pem", NULL, NULL);
|
mysql_ssl_set(mysql, NULL, NULL, "./non_exisiting_cert.pem", NULL, NULL);
|
||||||
|
|
||||||
mysql_real_connect(mysql, hostname, ssluser, sslpw, schema,
|
mysql_real_connect(mysql, hostname, ssluser, sslpw, schema,
|
||||||
port, socketname, 0);
|
port, socketname, 0);
|
||||||
@@ -494,7 +494,7 @@ static int test_conc127(MYSQL *unused __attribute__((unused)))
|
|||||||
mysql= mysql_init(NULL);
|
mysql= mysql_init(NULL);
|
||||||
FAIL_IF(!mysql, "Can't allocate memory");
|
FAIL_IF(!mysql, "Can't allocate memory");
|
||||||
|
|
||||||
mysql_ssl_set(mysql, NULL, NULL, "/home/georg/work/mariadb/bb-10.2-georg/unittest/libmariadb/certs/dummy.pem", NULL, NULL);
|
mysql_ssl_set(mysql, NULL, NULL, "./non_exisiting.pem", NULL, NULL);
|
||||||
|
|
||||||
mysql_real_connect(mysql, hostname, ssluser, sslpw, schema,
|
mysql_real_connect(mysql, hostname, ssluser, sslpw, schema,
|
||||||
port, socketname, 0);
|
port, socketname, 0);
|
||||||
@@ -649,9 +649,9 @@ DWORD WINAPI thread_conc102(void)
|
|||||||
mysql_thread_init();
|
mysql_thread_init();
|
||||||
mysql= mysql_init(NULL);
|
mysql= mysql_init(NULL);
|
||||||
|
|
||||||
mysql_ssl_set(mysql, "/home/georg/work/mariadb/bb-10.2-georg/unitt/libmariadb/certs/client-key.pem",
|
mysql_ssl_set(mysql, sslkey,
|
||||||
sslcert,
|
sslcert,
|
||||||
sslca,
|
sslca,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
mysql_ssl_set(mysql,0, 0, sslca, 0, 0);
|
mysql_ssl_set(mysql,0, 0, sslca, 0, 0);
|
||||||
|
|
||||||
@@ -975,7 +975,6 @@ static int test_openssl_1(MYSQL *mysql)
|
|||||||
|
|
||||||
my= mysql_init(NULL);
|
my= mysql_init(NULL);
|
||||||
mysql_options(my, MYSQL_OPT_SSL_ENFORCE, &val);
|
mysql_options(my, MYSQL_OPT_SSL_ENFORCE, &val);
|
||||||
my->options.use_ssl= 1;
|
|
||||||
FAIL_IF(!mysql_real_connect(my, hostname, "ssluser1", NULL, schema,
|
FAIL_IF(!mysql_real_connect(my, hostname, "ssluser1", NULL, schema,
|
||||||
port, socketname, 0), mysql_error(my));
|
port, socketname, 0), mysql_error(my));
|
||||||
FAIL_IF(!mysql_get_ssl_cipher(my), "No TLS connection");
|
FAIL_IF(!mysql_get_ssl_cipher(my), "No TLS connection");
|
||||||
@@ -985,11 +984,18 @@ static int test_openssl_1(MYSQL *mysql)
|
|||||||
rc= mysql_query(mysql, query);
|
rc= mysql_query(mysql, query);
|
||||||
check_mysql_rc(rc, mysql);
|
check_mysql_rc(rc, mysql);
|
||||||
|
|
||||||
/* ssl_user1: connect with enforce should work */
|
|
||||||
|
/* ssl_user2: connect with enforce should work */
|
||||||
my= mysql_init(NULL);
|
my= mysql_init(NULL);
|
||||||
mysql_options(my, MYSQL_OPT_SSL_ENFORCE, &val);
|
mysql_options(my, MYSQL_OPT_SSL_ENFORCE, &val);
|
||||||
FAIL_IF(mysql_real_connect(my, hostname, "ssluser2", NULL, schema,
|
mysql_real_connect(my, hostname, "ssluser2", NULL, schema,
|
||||||
port, socketname, 0), "Error expected");
|
port, socketname, 0);
|
||||||
|
if (!mysql_error(my) &&
|
||||||
|
strcmp(mysql_get_ssl_cipher(my), "AES256-SHA"))
|
||||||
|
{
|
||||||
|
diag("Expected error or correct cipher");
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
mysql_close(my);
|
mysql_close(my);
|
||||||
|
|
||||||
/* ssl_user2: connect with cipher should work */
|
/* ssl_user2: connect with cipher should work */
|
||||||
@@ -1158,8 +1164,57 @@ static int test_mdev14027(MYSQL *mysql __attribute__((unused)))
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_mdev14101(MYSQL *my __attribute__((unused)))
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
bool do_yassl;
|
||||||
|
const char *opt_tls_version;
|
||||||
|
const char *expected;
|
||||||
|
} combinations[]= {
|
||||||
|
{1, "TLSv1.0", "TLSv1.0"},
|
||||||
|
{1, "TLSv1.1", "TLSv1.1"},
|
||||||
|
{1, "TLSv1,TLSv1.1", "TLSv1.1"},
|
||||||
|
{0, "TLSv1.2", "TLSv1.2"},
|
||||||
|
{0, NULL, "TLSv1.2"},
|
||||||
|
{0, "TLSv1.0,TLSv1.1,TLSv1.2", "TLSv1.2"},
|
||||||
|
{1, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
int i;
|
||||||
|
#ifdef HAVE_SCHANNEL
|
||||||
|
bool skip_tlsv12= 1;
|
||||||
|
#else
|
||||||
|
bool skip_tlsv12= !have_openssl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diag("%d %d", skip_tlsv12, have_openssl);
|
||||||
|
|
||||||
|
for (i=0; combinations[i].expected; i++)
|
||||||
|
{
|
||||||
|
MYSQL *mysql;
|
||||||
|
bool val=1;
|
||||||
|
char *tls_version;
|
||||||
|
|
||||||
|
if (!combinations[i].do_yassl && skip_tlsv12)
|
||||||
|
break;
|
||||||
|
|
||||||
|
mysql= mysql_init(NULL);
|
||||||
|
mysql_options(mysql, MYSQL_OPT_SSL_ENFORCE, &val);
|
||||||
|
mysql_options(mysql, MARIADB_OPT_TLS_VERSION, combinations[i].opt_tls_version);
|
||||||
|
FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema,
|
||||||
|
port, socketname, 0), mysql_error(mysql));
|
||||||
|
mariadb_get_infov(mysql, MARIADB_CONNECTION_TLS_VERSION, &tls_version);
|
||||||
|
diag("options: %s", combinations[i].opt_tls_version);
|
||||||
|
diag("protocol: %s", tls_version);
|
||||||
|
FAIL_IF(strcmp(combinations[i].expected, tls_version), "Wrong tls_version");
|
||||||
|
mysql_close(mysql);
|
||||||
|
}
|
||||||
|
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_mdev14101", test_mdev14101, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_mdev14027", test_mdev14027, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_mdev14027", test_mdev14027, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_conc286", test_conc286, 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},
|
||||||
|
Reference in New Issue
Block a user