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);
|
||||
const char *ma_pvio_tls_get_protocol_version(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);
|
||||
|
||||
/* 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);
|
||||
void ma_pvio_tls_set_connection(MYSQL *mysql);
|
||||
void ma_pvio_tls_end();
|
||||
unsigned int ma_pvio_tls_get_peer_cert_info(MARIADB_TLS *ctls);
|
||||
|
||||
#endif /* _ma_tls_h_ */
|
||||
|
@@ -269,4 +269,9 @@ void ma_pvio_tls_set_connection(MYSQL *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 */
|
||||
|
@@ -4537,7 +4537,13 @@ my_bool mariadb_get_infov(MYSQL *mysql, enum mariadb_value value, void *arg, ...
|
||||
switch(value) {
|
||||
#ifdef HAVE_TLS
|
||||
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;
|
||||
#endif
|
||||
case MARIADB_MAX_ALLOWED_PACKET:
|
||||
|
@@ -459,6 +459,57 @@ error:
|
||||
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)
|
||||
{
|
||||
SSL *ssl = (SSL *)ctls->ssl;
|
||||
@@ -466,7 +517,6 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
||||
MYSQL *mysql;
|
||||
MARIADB_PVIO *pvio;
|
||||
int rc;
|
||||
X509 *cert;
|
||||
#ifdef OPENSSL_USE_BIOMETHOD
|
||||
BIO_METHOD *bio_method= NULL;
|
||||
BIO *bio;
|
||||
@@ -533,40 +583,6 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@@ -32,8 +32,6 @@ char tls_library_version[] = "Schannel";
|
||||
#define PROT_TLS1_2 4
|
||||
#define PROT_TLS1_3 8
|
||||
|
||||
unsigned int ma_set_tls_x509_info(MARIADB_TLS *ctls);
|
||||
|
||||
static struct
|
||||
{
|
||||
DWORD cipher_id;
|
||||
@@ -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))
|
||||
goto end;
|
||||
}
|
||||
|
||||
ma_set_tls_x509_info(ctls);
|
||||
rc = 0;
|
||||
|
||||
end:
|
||||
@@ -580,7 +576,7 @@ static void ma_systime_to_tm(SYSTEMTIME sys_tm, struct tm *tm)
|
||||
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;
|
||||
SC_CTX *sctx= (SC_CTX *)ctls->ssl;
|
||||
@@ -589,6 +585,13 @@ unsigned int ma_set_tls_x509_info(MARIADB_TLS *ctls)
|
||||
SYSTEMTIME tm;
|
||||
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)
|
||||
return 1;
|
||||
|
||||
|
Reference in New Issue
Block a user