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-698: certificate info is read on every connect
Part 1: Fix for OpenSSL and Schannel
This commit is contained in:
@@ -150,6 +150,7 @@ unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, uint hash_type, char *fp
|
|||||||
int ma_tls_get_protocol_version(MARIADB_TLS *ctls);
|
int ma_tls_get_protocol_version(MARIADB_TLS *ctls);
|
||||||
const char *ma_pvio_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);
|
int ma_pvio_tls_get_protocol_version_id(MARIADB_TLS *ctls);
|
||||||
|
unsigned int ma_tls_get_peer_cert_info(MARIADB_TLS *ctls);
|
||||||
void ma_tls_set_connection(MYSQL *mysql);
|
void ma_tls_set_connection(MYSQL *mysql);
|
||||||
|
|
||||||
/* Function prototypes */
|
/* Function prototypes */
|
||||||
@@ -164,5 +165,6 @@ my_bool ma_pvio_tls_check_fp(MARIADB_TLS *ctls, const char *fp, const char *fp_l
|
|||||||
my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio);
|
my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio);
|
||||||
void ma_pvio_tls_set_connection(MYSQL *mysql);
|
void ma_pvio_tls_set_connection(MYSQL *mysql);
|
||||||
void ma_pvio_tls_end();
|
void ma_pvio_tls_end();
|
||||||
|
unsigned int ma_pvio_tls_get_peer_cert_info(MARIADB_TLS *ctls);
|
||||||
|
|
||||||
#endif /* _ma_tls_h_ */
|
#endif /* _ma_tls_h_ */
|
||||||
|
@@ -269,4 +269,9 @@ void ma_pvio_tls_set_connection(MYSQL *mysql)
|
|||||||
{
|
{
|
||||||
ma_tls_set_connection(mysql);
|
ma_tls_set_connection(mysql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ma_pvio_tls_get_peer_cert_info(MARIADB_TLS *ctls)
|
||||||
|
{
|
||||||
|
return ma_tls_get_peer_cert_info(ctls);
|
||||||
|
}
|
||||||
#endif /* HAVE_TLS */
|
#endif /* HAVE_TLS */
|
||||||
|
@@ -4537,7 +4537,13 @@ my_bool mariadb_get_infov(MYSQL *mysql, enum mariadb_value value, void *arg, ...
|
|||||||
switch(value) {
|
switch(value) {
|
||||||
#ifdef HAVE_TLS
|
#ifdef HAVE_TLS
|
||||||
case MARIADB_TLS_PEER_CERT_INFO:
|
case MARIADB_TLS_PEER_CERT_INFO:
|
||||||
*((MARIADB_X509_INFO **)arg)= mysql->net.pvio->ctls ? (MARIADB_X509_INFO *)&mysql->net.pvio->ctls->cert_info : NULL;
|
if (mysql->net.pvio->ctls)
|
||||||
|
{
|
||||||
|
if (!ma_pvio_tls_get_peer_cert_info(mysql->net.pvio->ctls))
|
||||||
|
*((MARIADB_X509_INFO **)arg)= (MARIADB_X509_INFO *)&mysql->net.pvio->ctls->cert_info;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*((MARIADB_X509_INFO **)arg)= NULL;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case MARIADB_MAX_ALLOWED_PACKET:
|
case MARIADB_MAX_ALLOWED_PACKET:
|
||||||
|
@@ -459,6 +459,57 @@ error:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ma_tls_get_peer_cert_info(MARIADB_TLS *ctls)
|
||||||
|
{
|
||||||
|
X509 *cert;
|
||||||
|
SSL *ssl;
|
||||||
|
|
||||||
|
if (!ctls || !ctls->ssl)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Did we already read peer cert information ? */
|
||||||
|
if (ctls->cert_info.version)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ssl= (SSL *)ctls->ssl;
|
||||||
|
|
||||||
|
/* Store peer certificate information */
|
||||||
|
if ((cert= SSL_get_peer_certificate(ssl)))
|
||||||
|
{
|
||||||
|
char fp[33];
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
|
||||||
|
const ASN1_TIME *not_before= X509_get0_notBefore(cert),
|
||||||
|
*not_after= X509_get0_notAfter(cert);
|
||||||
|
ASN1_TIME_to_tm(not_before, (struct tm *)&ctls->cert_info.not_before);
|
||||||
|
ASN1_TIME_to_tm(not_after, (struct tm *)&ctls->cert_info.not_after);
|
||||||
|
#else
|
||||||
|
const ASN1_TIME *not_before= X509_get_notBefore(cert),
|
||||||
|
*not_after= X509_get_notAfter(cert);
|
||||||
|
time_t now, from, to;
|
||||||
|
int pday, psec;
|
||||||
|
/* ANS1_TIME_diff returns days and seconds between now and the
|
||||||
|
specified ASN1_TIME */
|
||||||
|
time(&now);
|
||||||
|
ASN1_TIME_diff(&pday, &psec, not_before, NULL);
|
||||||
|
from= now - (pday * 86400 + psec);
|
||||||
|
gmtime_r(&from, &ctls->cert_info.not_before);
|
||||||
|
ASN1_TIME_diff(&pday, &psec, NULL, not_after);
|
||||||
|
to= now + (pday * 86400 + psec);
|
||||||
|
gmtime_r(&to, &ctls->cert_info.not_after);
|
||||||
|
#endif
|
||||||
|
ctls->cert_info.subject= X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
|
||||||
|
ctls->cert_info.issuer= X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
|
||||||
|
ctls->cert_info.version= X509_get_version(cert) + 1;
|
||||||
|
|
||||||
|
ma_tls_get_finger_print(ctls, MA_HASH_SHA256, fp, 33);
|
||||||
|
mysql_hex_string(ctls->cert_info.fingerprint, fp, 32);
|
||||||
|
|
||||||
|
X509_free(cert);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
||||||
{
|
{
|
||||||
SSL *ssl = (SSL *)ctls->ssl;
|
SSL *ssl = (SSL *)ctls->ssl;
|
||||||
@@ -466,7 +517,6 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
|||||||
MYSQL *mysql;
|
MYSQL *mysql;
|
||||||
MARIADB_PVIO *pvio;
|
MARIADB_PVIO *pvio;
|
||||||
int rc;
|
int rc;
|
||||||
X509 *cert;
|
|
||||||
#ifdef OPENSSL_USE_BIOMETHOD
|
#ifdef OPENSSL_USE_BIOMETHOD
|
||||||
BIO_METHOD *bio_method= NULL;
|
BIO_METHOD *bio_method= NULL;
|
||||||
BIO *bio;
|
BIO *bio;
|
||||||
@@ -533,40 +583,6 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
|||||||
}
|
}
|
||||||
pvio->ctls->ssl= ctls->ssl= (void *)ssl;
|
pvio->ctls->ssl= ctls->ssl= (void *)ssl;
|
||||||
|
|
||||||
/* Store peer certificate information */
|
|
||||||
if ((cert= SSL_get_peer_certificate(ssl)))
|
|
||||||
{
|
|
||||||
char fp[33];
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
|
|
||||||
const ASN1_TIME *not_before= X509_get0_notBefore(cert),
|
|
||||||
*not_after= X509_get0_notAfter(cert);
|
|
||||||
ASN1_TIME_to_tm(not_before, (struct tm *)&ctls->cert_info.not_before);
|
|
||||||
ASN1_TIME_to_tm(not_after, (struct tm *)&ctls->cert_info.not_after);
|
|
||||||
#else
|
|
||||||
const ASN1_TIME *not_before= X509_get_notBefore(cert),
|
|
||||||
*not_after= X509_get_notAfter(cert);
|
|
||||||
time_t now, from, to;
|
|
||||||
int pday, psec;
|
|
||||||
/* ANS1_TIME_diff returns days and seconds between now and the
|
|
||||||
specified ASN1_TIME */
|
|
||||||
time(&now);
|
|
||||||
ASN1_TIME_diff(&pday, &psec, not_before, NULL);
|
|
||||||
from= now - (pday * 86400 + psec);
|
|
||||||
gmtime_r(&from, &ctls->cert_info.not_before);
|
|
||||||
ASN1_TIME_diff(&pday, &psec, NULL, not_after);
|
|
||||||
to= now + (pday * 86400 + psec);
|
|
||||||
gmtime_r(&to, &ctls->cert_info.not_after);
|
|
||||||
#endif
|
|
||||||
ctls->cert_info.subject= X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
|
|
||||||
ctls->cert_info.issuer= X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
|
|
||||||
ctls->cert_info.version= X509_get_version(cert) + 1;
|
|
||||||
|
|
||||||
ma_tls_get_finger_print(ctls, MA_HASH_SHA256, fp, 33);
|
|
||||||
mysql_hex_string(ctls->cert_info.fingerprint, fp, 32);
|
|
||||||
|
|
||||||
X509_free(cert);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,8 +32,6 @@ char tls_library_version[] = "Schannel";
|
|||||||
#define PROT_TLS1_2 4
|
#define PROT_TLS1_2 4
|
||||||
#define PROT_TLS1_3 8
|
#define PROT_TLS1_3 8
|
||||||
|
|
||||||
unsigned int ma_set_tls_x509_info(MARIADB_TLS *ctls);
|
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
DWORD cipher_id;
|
DWORD cipher_id;
|
||||||
@@ -450,7 +448,7 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
|||||||
if (ma_schannel_client_handshake(ctls) != SEC_E_OK)
|
if (ma_schannel_client_handshake(ctls) != SEC_E_OK)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
verify_certs = mysql->options.ssl_ca || mysql->options.ssl_capath ||
|
verify_certs = mysql->options.ssl_ca || mysql->options.ssl_capath ||
|
||||||
!mysql->options.extension->tls_allow_invalid_server_cert;
|
!mysql->options.extension->tls_allow_invalid_server_cert;
|
||||||
|
|
||||||
if (verify_certs)
|
if (verify_certs)
|
||||||
@@ -458,8 +456,6 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
|||||||
if (!ma_schannel_verify_certs(ctls, !mysql->options.extension->tls_allow_invalid_server_cert))
|
if (!ma_schannel_verify_certs(ctls, !mysql->options.extension->tls_allow_invalid_server_cert))
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
ma_set_tls_x509_info(ctls);
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
@@ -580,7 +576,7 @@ static void ma_systime_to_tm(SYSTEMTIME sys_tm, struct tm *tm)
|
|||||||
tm->tm_min = sys_tm.wMinute;
|
tm->tm_min = sys_tm.wMinute;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ma_set_tls_x509_info(MARIADB_TLS *ctls)
|
unsigned int ma_tls_get_peer_cert_info(MARIADB_TLS *ctls)
|
||||||
{
|
{
|
||||||
PCCERT_CONTEXT pCertCtx= NULL;
|
PCCERT_CONTEXT pCertCtx= NULL;
|
||||||
SC_CTX *sctx= (SC_CTX *)ctls->ssl;
|
SC_CTX *sctx= (SC_CTX *)ctls->ssl;
|
||||||
@@ -589,6 +585,13 @@ unsigned int ma_set_tls_x509_info(MARIADB_TLS *ctls)
|
|||||||
SYSTEMTIME tm;
|
SYSTEMTIME tm;
|
||||||
char fp[33];
|
char fp[33];
|
||||||
|
|
||||||
|
if (!ctls || !sctx)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Did we already read peer cert information ? */
|
||||||
|
if (ctls->cert_info.version)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (QueryContextAttributes(&sctx->hCtxt, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pCertCtx) != SEC_E_OK)
|
if (QueryContextAttributes(&sctx->hCtxt, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pCertCtx) != SEC_E_OK)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user