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
SSL fixes:
- added MARIADB_OPT_SSL_CIPHER_STRENGTH (value uint) for Schannel - fixed mutes in all ssl variants
This commit is contained in:
@@ -53,6 +53,7 @@ struct st_mysql_options_extension {
|
|||||||
char *ssl_fp_list; /* white list of finger prints */
|
char *ssl_fp_list; /* white list of finger prints */
|
||||||
char *ssl_pw; /* password for encrypted certificates */
|
char *ssl_pw; /* password for encrypted certificates */
|
||||||
char *url; /* for connection handler we need to save URL for reconnect */
|
char *url; /* for connection handler we need to save URL for reconnect */
|
||||||
|
unsigned int ssl_cipher_strength;
|
||||||
my_bool read_only;
|
my_bool read_only;
|
||||||
char *connection_handler;
|
char *connection_handler;
|
||||||
HASH userdata;
|
HASH userdata;
|
||||||
|
@@ -221,6 +221,7 @@ extern unsigned int mariadb_deinitialize_ssl;
|
|||||||
MARIADB_OPT_CONNECTION_READ_ONLY,
|
MARIADB_OPT_CONNECTION_READ_ONLY,
|
||||||
MYSQL_OPT_CONNECT_ATTRS, /* for mysql_get_optionv */
|
MYSQL_OPT_CONNECT_ATTRS, /* for mysql_get_optionv */
|
||||||
MARIADB_OPT_USERDATA,
|
MARIADB_OPT_USERDATA,
|
||||||
|
MARIADB_OPT_SSL_CIPHER_STRENGTH,
|
||||||
MARIADB_OPT_CONNECTION_HANDLER
|
MARIADB_OPT_CONNECTION_HANDLER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -2930,6 +2930,9 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
my_free(mysql->options.bind_address);
|
my_free(mysql->options.bind_address);
|
||||||
mysql->options.bind_address= my_strdup(arg1, MYF(MY_WME));
|
mysql->options.bind_address= my_strdup(arg1, MYF(MY_WME));
|
||||||
break;
|
break;
|
||||||
|
case MARIADB_OPT_SSL_CIPHER_STRENGTH:
|
||||||
|
OPT_SET_EXTENDED_VALUE_INT(&mysql->options, ssl_cipher_strength, *((unsigned int *)arg1));
|
||||||
|
break;
|
||||||
case MARIADB_OPT_SSL_FP:
|
case MARIADB_OPT_SSL_FP:
|
||||||
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, ssl_fp, (char *)arg1);
|
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, ssl_fp, (char *)arg1);
|
||||||
break;
|
break;
|
||||||
@@ -3108,6 +3111,9 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...)
|
|||||||
case MYSQL_OPT_BIND:
|
case MYSQL_OPT_BIND:
|
||||||
*((char **)arg)= mysql->options.bind_address;
|
*((char **)arg)= mysql->options.bind_address;
|
||||||
break;
|
break;
|
||||||
|
case MARIADB_OPT_SSL_CIPHER_STRENGTH:
|
||||||
|
*((unsigned int *)arg) = mysql->options.extension ? mysql->options.extension->ssl_cipher_strength : 0;
|
||||||
|
break;
|
||||||
case MARIADB_OPT_SSL_FP:
|
case MARIADB_OPT_SSL_FP:
|
||||||
*((char **)arg)= mysql->options.extension ? mysql->options.extension->ssl_fp : NULL;
|
*((char **)arg)= mysql->options.extension ? mysql->options.extension->ssl_fp : NULL;
|
||||||
break;
|
break;
|
||||||
|
@@ -521,7 +521,8 @@ my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (pvio->mysql->options.extension &&
|
if (pvio->mysql->options.extension &&
|
||||||
(pvio->mysql->options.extension->ssl_fp || pvio->mysql->options.extension->ssl_fp_list))
|
(pvio->mysql->options.extension->ssl_fp && pvio->mysql->options.extension->ssl_fp[0]) ||
|
||||||
|
(pvio->mysql->options.extension->ssl_fp_list && pvio->mysql->options.extension->ssl_fp_list[0]))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ma_pvio_ssl_check_fp(pvio->cssl,
|
if (ma_pvio_ssl_check_fp(pvio->cssl,
|
||||||
|
@@ -140,6 +140,7 @@ my_bool ma_pvio_ssl_check_fp(MARIADB_SSL *cssl, const char *fp, const char *fp_l
|
|||||||
unsigned int cert_fp_len= 64;
|
unsigned int cert_fp_len= 64;
|
||||||
unsigned char cert_fp[64];
|
unsigned char cert_fp[64];
|
||||||
my_bool rc=1;
|
my_bool rc=1;
|
||||||
|
MYSQL *mysql= cssl->pvio->mysql;
|
||||||
|
|
||||||
if ((cert_fp_len= ma_ssl_get_finger_print(cssl, cert_fp, cert_fp_len)) < 1)
|
if ((cert_fp_len= ma_ssl_get_finger_print(cssl, cert_fp, cert_fp_len)) < 1)
|
||||||
goto end;
|
goto end;
|
||||||
@@ -147,20 +148,15 @@ my_bool ma_pvio_ssl_check_fp(MARIADB_SSL *cssl, const char *fp, const char *fp_l
|
|||||||
rc= ma_pvio_ssl_compare_fp(cert_fp, cert_fp_len, (char *)fp, (unsigned int)strlen(fp));
|
rc= ma_pvio_ssl_compare_fp(cert_fp, cert_fp_len, (char *)fp, (unsigned int)strlen(fp));
|
||||||
else if (fp_list)
|
else if (fp_list)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
MA_FILE *fp;
|
||||||
char buff[255];
|
char buff[255];
|
||||||
|
|
||||||
if (!(fp = fopen(fp_list, "r")))
|
if (!(fp = ma_open(fp_list, "r", mysql)))
|
||||||
{
|
{
|
||||||
/*
|
return 1;
|
||||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
|
||||||
ER(CR_SSL_CONNECTION_ERROR),
|
|
||||||
"Can't open finger print list");
|
|
||||||
*/
|
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fgets(buff, sizeof(buff)-1, fp))
|
while (ma_gets(buff, sizeof(buff)-1, fp))
|
||||||
{
|
{
|
||||||
/* remove trailing new line character */
|
/* remove trailing new line character */
|
||||||
char *pos= strchr(buff, '\r');
|
char *pos= strchr(buff, '\r');
|
||||||
@@ -172,18 +168,23 @@ my_bool ma_pvio_ssl_check_fp(MARIADB_SSL *cssl, const char *fp, const char *fp_l
|
|||||||
if (!ma_pvio_ssl_compare_fp(cert_fp, cert_fp_len, buff, (unsigned int)strlen(buff)))
|
if (!ma_pvio_ssl_compare_fp(cert_fp, cert_fp_len, buff, (unsigned int)strlen(buff)))
|
||||||
{
|
{
|
||||||
/* finger print is valid: close file and exit */
|
/* finger print is valid: close file and exit */
|
||||||
fclose(fp);
|
ma_close(fp);
|
||||||
rc= 0;
|
rc= 0;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No finger print matched - close file and return error */
|
/* No finger print matched - close file and return error */
|
||||||
fclose(fp);
|
ma_close(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||||
|
ER(CR_SSL_CONNECTION_ERROR),
|
||||||
|
"Fingerprint verification of server certificate failed");
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SSL */
|
#endif /* HAVE_SSL */
|
||||||
|
@@ -97,20 +97,20 @@ int ma_ssl_start(char *errmsg, size_t errmsg_len)
|
|||||||
{
|
{
|
||||||
int rc= 0;
|
int rc= 0;
|
||||||
|
|
||||||
|
if (ma_ssl_initialized)
|
||||||
|
return 0;
|
||||||
|
|
||||||
pthread_mutex_init(&LOCK_gnutls_config,MY_MUTEX_INIT_FAST);
|
pthread_mutex_init(&LOCK_gnutls_config,MY_MUTEX_INIT_FAST);
|
||||||
pthread_mutex_lock(&LOCK_gnutls_config);
|
pthread_mutex_lock(&LOCK_gnutls_config);
|
||||||
|
|
||||||
if (!ma_ssl_initialized)
|
|
||||||
{
|
|
||||||
if ((rc= gnutls_global_init()) != GNUTLS_E_SUCCESS)
|
if ((rc= gnutls_global_init()) != GNUTLS_E_SUCCESS)
|
||||||
{
|
{
|
||||||
ma_ssl_get_error(errmsg, errmsg_len, rc);
|
ma_ssl_get_error(errmsg, errmsg_len, rc);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
ma_ssl_initialized= TRUE;
|
|
||||||
}
|
|
||||||
/* Allocate a global context for credentials */
|
/* Allocate a global context for credentials */
|
||||||
rc= gnutls_certificate_allocate_credentials(&GNUTLS_xcred);
|
rc= gnutls_certificate_allocate_credentials(&GNUTLS_xcred);
|
||||||
|
ma_ssl_initialized= TRUE;
|
||||||
end:
|
end:
|
||||||
pthread_mutex_unlock(&LOCK_gnutls_config);
|
pthread_mutex_unlock(&LOCK_gnutls_config);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -130,9 +130,9 @@ end:
|
|||||||
*/
|
*/
|
||||||
void ma_ssl_end()
|
void ma_ssl_end()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_gnutls_config);
|
|
||||||
if (ma_ssl_initialized)
|
if (ma_ssl_initialized)
|
||||||
{
|
{
|
||||||
|
pthread_mutex_lock(&LOCK_gnutls_config);
|
||||||
gnutls_certificate_free_keys(GNUTLS_xcred);
|
gnutls_certificate_free_keys(GNUTLS_xcred);
|
||||||
gnutls_certificate_free_cas(GNUTLS_xcred);
|
gnutls_certificate_free_cas(GNUTLS_xcred);
|
||||||
gnutls_certificate_free_crls(GNUTLS_xcred);
|
gnutls_certificate_free_crls(GNUTLS_xcred);
|
||||||
@@ -141,9 +141,9 @@ void ma_ssl_end()
|
|||||||
if (mariadb_deinitialize_ssl)
|
if (mariadb_deinitialize_ssl)
|
||||||
gnutls_global_deinit();
|
gnutls_global_deinit();
|
||||||
ma_ssl_initialized= FALSE;
|
ma_ssl_initialized= FALSE;
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&LOCK_gnutls_config);
|
pthread_mutex_unlock(&LOCK_gnutls_config);
|
||||||
pthread_mutex_destroy(&LOCK_gnutls_config);
|
pthread_mutex_destroy(&LOCK_gnutls_config);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -387,7 +387,7 @@ end:
|
|||||||
SECURITY_STATUS ma_schannel_handshake_loop(MARIADB_PVIO *pvio, my_bool InitialRead, SecBuffer *pExtraData)
|
SECURITY_STATUS ma_schannel_handshake_loop(MARIADB_PVIO *pvio, my_bool InitialRead, SecBuffer *pExtraData)
|
||||||
{
|
{
|
||||||
SecBufferDesc OutBuffer, InBuffer;
|
SecBufferDesc OutBuffer, InBuffer;
|
||||||
SecBuffer InBuffers[2], OutBuffers[1];
|
SecBuffer InBuffers[2], OutBuffers;
|
||||||
DWORD dwSSPIFlags, dwSSPIOutFlags, cbData, cbIoBuffer;
|
DWORD dwSSPIFlags, dwSSPIOutFlags, cbData, cbIoBuffer;
|
||||||
TimeStamp tsExpiry;
|
TimeStamp tsExpiry;
|
||||||
SECURITY_STATUS rc;
|
SECURITY_STATUS rc;
|
||||||
@@ -457,12 +457,12 @@ SECURITY_STATUS ma_schannel_handshake_loop(MARIADB_PVIO *pvio, my_bool InitialRe
|
|||||||
|
|
||||||
|
|
||||||
/* output buffer */
|
/* output buffer */
|
||||||
OutBuffers[0].pvBuffer = NULL;
|
OutBuffers.pvBuffer = NULL;
|
||||||
OutBuffers[0].BufferType= SECBUFFER_TOKEN;
|
OutBuffers.BufferType= SECBUFFER_TOKEN;
|
||||||
OutBuffers[0].cbBuffer = 0;
|
OutBuffers.cbBuffer = 0;
|
||||||
|
|
||||||
OutBuffer.cBuffers = 1;
|
OutBuffer.cBuffers = 1;
|
||||||
OutBuffer.pBuffers = OutBuffers;
|
OutBuffer.pBuffers = &OutBuffers;
|
||||||
OutBuffer.ulVersion = SECBUFFER_VERSION;
|
OutBuffer.ulVersion = SECBUFFER_VERSION;
|
||||||
|
|
||||||
|
|
||||||
@@ -484,19 +484,19 @@ SECURITY_STATUS ma_schannel_handshake_loop(MARIADB_PVIO *pvio, my_bool InitialRe
|
|||||||
rc == SEC_I_CONTINUE_NEEDED ||
|
rc == SEC_I_CONTINUE_NEEDED ||
|
||||||
FAILED(rc) && (dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR))
|
FAILED(rc) && (dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR))
|
||||||
{
|
{
|
||||||
if(OutBuffers[0].cbBuffer && OutBuffers[0].pvBuffer)
|
if(OutBuffers.cbBuffer && OutBuffers.pvBuffer)
|
||||||
{
|
{
|
||||||
cbData= (DWORD)pvio->methods->write(pvio, (uchar *)OutBuffers[0].pvBuffer, (size_t)OutBuffers[0].cbBuffer);
|
cbData= (DWORD)pvio->methods->write(pvio, (uchar *)OutBuffers.pvBuffer, (size_t)OutBuffers.cbBuffer);
|
||||||
if(cbData == SOCKET_ERROR || cbData == 0)
|
if(cbData == SOCKET_ERROR || cbData == 0)
|
||||||
{
|
{
|
||||||
FreeContextBuffer(OutBuffers[0].pvBuffer);
|
FreeContextBuffer(OutBuffers.pvBuffer);
|
||||||
DeleteSecurityContext(&sctx->ctxt);
|
DeleteSecurityContext(&sctx->ctxt);
|
||||||
return SEC_E_INTERNAL_ERROR;
|
return SEC_E_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free output context buffer */
|
/* Free output context buffer */
|
||||||
FreeContextBuffer(OutBuffers[0].pvBuffer);
|
FreeContextBuffer(OutBuffers.pvBuffer);
|
||||||
OutBuffers[0].pvBuffer = NULL;
|
OutBuffers.pvBuffer = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,7 +589,7 @@ SECURITY_STATUS ma_schannel_client_handshake(MARIADB_SSL *cssl)
|
|||||||
ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM;
|
ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM;
|
||||||
|
|
||||||
SecBufferDesc BufferOut;
|
SecBufferDesc BufferOut;
|
||||||
SecBuffer BuffersOut[1];
|
SecBuffer BuffersOut;
|
||||||
|
|
||||||
if (!cssl || !cssl->pvio)
|
if (!cssl || !cssl->pvio)
|
||||||
return 1;
|
return 1;
|
||||||
@@ -598,13 +598,13 @@ SECURITY_STATUS ma_schannel_client_handshake(MARIADB_SSL *cssl)
|
|||||||
sctx= (SC_CTX *)cssl->ssl;
|
sctx= (SC_CTX *)cssl->ssl;
|
||||||
|
|
||||||
/* Initialie securifty context */
|
/* Initialie securifty context */
|
||||||
BuffersOut[0].BufferType= SECBUFFER_TOKEN;
|
BuffersOut.BufferType= SECBUFFER_TOKEN;
|
||||||
BuffersOut[0].cbBuffer= 0;
|
BuffersOut.cbBuffer= 0;
|
||||||
BuffersOut[0].pvBuffer= NULL;
|
BuffersOut.pvBuffer= NULL;
|
||||||
|
|
||||||
|
|
||||||
BufferOut.cBuffers= 1;
|
BufferOut.cBuffers= 1;
|
||||||
BufferOut.pBuffers= BuffersOut;
|
BufferOut.pBuffers= &BuffersOut;
|
||||||
BufferOut.ulVersion= SECBUFFER_VERSION;
|
BufferOut.ulVersion= SECBUFFER_VERSION;
|
||||||
|
|
||||||
sRet = InitializeSecurityContext(&sctx->CredHdl,
|
sRet = InitializeSecurityContext(&sctx->CredHdl,
|
||||||
@@ -627,9 +627,9 @@ SECURITY_STATUS ma_schannel_client_handshake(MARIADB_SSL *cssl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* send client hello packaet */
|
/* send client hello packaet */
|
||||||
if(BuffersOut[0].cbBuffer != 0 && BuffersOut[0].pvBuffer != NULL)
|
if(BuffersOut.cbBuffer != 0 && BuffersOut.pvBuffer != NULL)
|
||||||
{
|
{
|
||||||
r= (DWORD)pvio->methods->write(pvio, (uchar *)BuffersOut[0].pvBuffer, (size_t)BuffersOut[0].cbBuffer);
|
r= (DWORD)pvio->methods->write(pvio, (uchar *)BuffersOut.pvBuffer, (size_t)BuffersOut.cbBuffer);
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
{
|
{
|
||||||
sRet= SEC_E_INTERNAL_ERROR;
|
sRet= SEC_E_INTERNAL_ERROR;
|
||||||
@@ -654,7 +654,7 @@ SECURITY_STATUS ma_schannel_client_handshake(MARIADB_SSL *cssl)
|
|||||||
end:
|
end:
|
||||||
LocalFree(sctx->IoBuffer);
|
LocalFree(sctx->IoBuffer);
|
||||||
sctx->IoBufferSize= 0;
|
sctx->IoBufferSize= 0;
|
||||||
FreeContextBuffer(BuffersOut[0].pvBuffer);
|
FreeContextBuffer(BuffersOut.pvBuffer);
|
||||||
DeleteSecurityContext(&sctx->ctxt);
|
DeleteSecurityContext(&sctx->ctxt);
|
||||||
return sRet;
|
return sRet;
|
||||||
}
|
}
|
||||||
@@ -782,6 +782,9 @@ my_bool ma_schannel_verify_certs(SC_CTX *sctx, DWORD dwCertFlags)
|
|||||||
DWORD flags;
|
DWORD flags;
|
||||||
MARIADB_PVIO *pvio= sctx->mysql->net.pvio;
|
MARIADB_PVIO *pvio= sctx->mysql->net.pvio;
|
||||||
PCCERT_CONTEXT pServerCert= NULL;
|
PCCERT_CONTEXT pServerCert= NULL;
|
||||||
|
PCERT_CONTEXT ca_CTX = NULL;
|
||||||
|
PCRL_CONTEXT crl_CTX = NULL;
|
||||||
|
my_bool is_Ok = 0;
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -789,16 +792,22 @@ my_bool ma_schannel_verify_certs(SC_CTX *sctx, DWORD dwCertFlags)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags= CERT_STORE_SIGNATURE_FLAG |
|
if (ca_Check)
|
||||||
|
{
|
||||||
|
flags = CERT_STORE_SIGNATURE_FLAG |
|
||||||
CERT_STORE_TIME_VALIDITY_FLAG;
|
CERT_STORE_TIME_VALIDITY_FLAG;
|
||||||
|
|
||||||
|
while ((ca_CTX = CertFindCertificateInStore(ca_CertStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
|
||||||
|
0, CERT_FIND_ANY, 0, ca_CTX)) && !is_Ok)
|
||||||
if (sctx->client_ca_ctx)
|
|
||||||
{
|
{
|
||||||
if (!(sRet= CertVerifySubjectCertificateContext(pServerCert,
|
if (sRet = CertVerifySubjectCertificateContext(pServerCert, ca_CTX, &flags))
|
||||||
sctx->client_ca_ctx,
|
is_Ok = 1;
|
||||||
&flags)))
|
}
|
||||||
|
|
||||||
|
if (ca_CTX)
|
||||||
|
CertFreeCertificateContext(ca_CTX);
|
||||||
|
|
||||||
|
if (!is_Ok)
|
||||||
{
|
{
|
||||||
ma_schannel_set_win_error(pvio);
|
ma_schannel_set_win_error(pvio);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -819,19 +828,24 @@ my_bool ma_schannel_verify_certs(SC_CTX *sctx, DWORD dwCertFlags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if none of the certificates in the certificate chain have been revoked. */
|
/* Check if none of the certificates in the certificate chain have been revoked. */
|
||||||
if (sctx->client_crl_ctx)
|
if (crl_Check)
|
||||||
|
{
|
||||||
|
while ((crl_CTX = CertEnumCRLsInStore(crl_CertStore, crl_CTX)))
|
||||||
{
|
{
|
||||||
PCRL_INFO Info[1];
|
PCRL_INFO Info[1];
|
||||||
|
|
||||||
Info[0]= sctx->client_crl_ctx->pCrlInfo;
|
Info[0] = crl_CTX->pCrlInfo;
|
||||||
if (!(CertVerifyCRLRevocation(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
if (!(CertVerifyCRLRevocation(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||||
pServerCert->pCertInfo,
|
pServerCert->pCertInfo,
|
||||||
1, Info)) )
|
1, Info)))
|
||||||
{
|
{
|
||||||
|
CertFreeCRLContext(crl_CTX);
|
||||||
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "CRL Revocation failed");
|
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "CRL Revocation failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CertFreeCRLContext(crl_CTX);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,19 +56,10 @@ typedef void VOID;
|
|||||||
struct st_schannel {
|
struct st_schannel {
|
||||||
HCERTSTORE cert_store;
|
HCERTSTORE cert_store;
|
||||||
CERT_CONTEXT *client_cert_ctx;
|
CERT_CONTEXT *client_cert_ctx;
|
||||||
CERT_CONTEXT *client_ca_ctx;
|
|
||||||
CRL_CONTEXT *client_crl_ctx;
|
|
||||||
CredHandle CredHdl;
|
CredHandle CredHdl;
|
||||||
my_bool FreeCredHdl;
|
my_bool FreeCredHdl;
|
||||||
PUCHAR IoBuffer;
|
PUCHAR IoBuffer;
|
||||||
DWORD IoBufferSize;
|
DWORD IoBufferSize;
|
||||||
/* PUCHAR EncryptBuffer;
|
|
||||||
DWORD EncryptBufferSize;
|
|
||||||
DWORD EncryptBufferLength;
|
|
||||||
PUCHAR DecryptBuffer;
|
|
||||||
DWORD DecryptBufferSize;
|
|
||||||
DWORD DecryptBufferLength;
|
|
||||||
uchar thumbprint[21]; */
|
|
||||||
SecPkgContext_StreamSizes Sizes;
|
SecPkgContext_StreamSizes Sizes;
|
||||||
|
|
||||||
CtxtHandle ctxt;
|
CtxtHandle ctxt;
|
||||||
@@ -77,6 +68,9 @@ struct st_schannel {
|
|||||||
|
|
||||||
typedef struct st_schannel SC_CTX;
|
typedef struct st_schannel SC_CTX;
|
||||||
|
|
||||||
|
extern HCERTSTORE ca_CertStore, crl_CertStore;
|
||||||
|
extern my_bool ca_Check, crl_Check;
|
||||||
|
|
||||||
CERT_CONTEXT *ma_schannel_create_cert_context(MARIADB_PVIO *pvio, const char *pem_file);
|
CERT_CONTEXT *ma_schannel_create_cert_context(MARIADB_PVIO *pvio, const char *pem_file);
|
||||||
SECURITY_STATUS ma_schannel_client_handshake(MARIADB_SSL *cssl);
|
SECURITY_STATUS ma_schannel_client_handshake(MARIADB_SSL *cssl);
|
||||||
SECURITY_STATUS ma_schannel_handshake_loop(MARIADB_PVIO *pvio, my_bool InitialRead, SecBuffer *pExtraData);
|
SECURITY_STATUS ma_schannel_handshake_loop(MARIADB_PVIO *pvio, my_bool InitialRead, SecBuffer *pExtraData);
|
||||||
|
@@ -159,11 +159,12 @@ static int ssl_thread_init()
|
|||||||
int ma_ssl_start(char *errmsg, size_t errmsg_len)
|
int ma_ssl_start(char *errmsg, size_t errmsg_len)
|
||||||
{
|
{
|
||||||
int rc= 1;
|
int rc= 1;
|
||||||
|
if (ma_ssl_initialized)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* lock mutex to prevent multiple initialization */
|
/* lock mutex to prevent multiple initialization */
|
||||||
pthread_mutex_init(&LOCK_openssl_config,MY_MUTEX_INIT_FAST);
|
pthread_mutex_init(&LOCK_openssl_config,MY_MUTEX_INIT_FAST);
|
||||||
pthread_mutex_lock(&LOCK_openssl_config);
|
pthread_mutex_lock(&LOCK_openssl_config);
|
||||||
if (!ma_ssl_initialized)
|
|
||||||
{
|
|
||||||
if (ssl_thread_init())
|
if (ssl_thread_init())
|
||||||
{
|
{
|
||||||
strncpy(errmsg, "Not enough memory", errmsg_len);
|
strncpy(errmsg, "Not enough memory", errmsg_len);
|
||||||
@@ -189,7 +190,6 @@ int ma_ssl_start(char *errmsg, size_t errmsg_len)
|
|||||||
}
|
}
|
||||||
rc= 0;
|
rc= 0;
|
||||||
ma_ssl_initialized= TRUE;
|
ma_ssl_initialized= TRUE;
|
||||||
}
|
|
||||||
end:
|
end:
|
||||||
pthread_mutex_unlock(&LOCK_openssl_config);
|
pthread_mutex_unlock(&LOCK_openssl_config);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -209,10 +209,10 @@ end:
|
|||||||
*/
|
*/
|
||||||
void ma_ssl_end()
|
void ma_ssl_end()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_openssl_config);
|
|
||||||
if (ma_ssl_initialized)
|
if (ma_ssl_initialized)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
pthread_mutex_lock(&LOCK_openssl_config);
|
||||||
CRYPTO_set_locking_callback(NULL);
|
CRYPTO_set_locking_callback(NULL);
|
||||||
CRYPTO_set_id_callback(NULL);
|
CRYPTO_set_id_callback(NULL);
|
||||||
|
|
||||||
@@ -238,9 +238,9 @@ void ma_ssl_end()
|
|||||||
sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
|
sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
|
||||||
}
|
}
|
||||||
ma_ssl_initialized= FALSE;
|
ma_ssl_initialized= FALSE;
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&LOCK_openssl_config);
|
pthread_mutex_unlock(&LOCK_openssl_config);
|
||||||
pthread_mutex_destroy(&LOCK_openssl_config);
|
pthread_mutex_destroy(&LOCK_openssl_config);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,61 +34,57 @@ struct st_cipher_suite {
|
|||||||
CHAR *cipher;
|
CHAR *cipher;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct st_cipher_suite valid_ciphers[] =
|
||||||
|
{
|
||||||
|
{ CALG_3DES, "CALG_3DES" },
|
||||||
|
{ CALG_3DES_112, "CALG_3DES_112" },
|
||||||
|
{ CALG_AES, "CALG_AES" },
|
||||||
|
{ CALG_AES_128, "CALG_AES_128" },
|
||||||
|
{ CALG_AES_192, "CALG_AES_192" },
|
||||||
|
{ CALG_AES_256, "CALG_AES_256" },
|
||||||
|
{ CALG_AGREEDKEY_ANY, "CALG_AGREEDKEY_ANY" },
|
||||||
|
{ CALG_CYLINK_MEK, "CALG_CYLINK_MEK" },
|
||||||
|
{ CALG_DES, "CALG_DES" },
|
||||||
|
{ CALG_DESX, "CALG_DESX" },
|
||||||
|
{ CALG_DH_EPHEM, "CALG_DH_EPHEM" },
|
||||||
|
{ CALG_DH_SF, "CALG_DH_SF" },
|
||||||
|
{ CALG_DSS_SIGN, "CALG_DSS_SIGN" },
|
||||||
|
{ CALG_ECDH, "CALG_ECDH" },
|
||||||
|
{ CALG_ECDSA, "CALG_ECDSA" },
|
||||||
|
{ CALG_ECMQV, "CALG_ECMQV" },
|
||||||
|
{ CALG_HASH_REPLACE_OWF, "CALG_HASH_REPLACE_OWF" },
|
||||||
|
{ CALG_HUGHES_MD5, "CALG_HUGHES_MD5" },
|
||||||
|
{ CALG_HMAC, "CALG_HMAC" },
|
||||||
|
{ CALG_KEA_KEYX, "CALG_KEA_KEYX" },
|
||||||
|
{ CALG_MAC, "CALG_MAC" },
|
||||||
|
{ CALG_MD2, "CALG_MD2" },
|
||||||
|
{ CALG_MD4, "CALG_MD4" },
|
||||||
|
{ CALG_MD4, "CALG_MD5" },
|
||||||
|
{ CALG_NO_SIGN, "CALG_NO_SIGN" },
|
||||||
|
{ CALG_OID_INFO_CNG_ONLY, "CALG_OID_INFO_CNG_ONLY" },
|
||||||
|
{ CALG_OID_INFO_PARAMETERS, "CALG_OID_INFO_PARAMETERS" },
|
||||||
|
{ CALG_RC2, "CALG_RC2" },
|
||||||
|
{ CALG_RC4, "CALG_RC4" },
|
||||||
|
{ CALG_RC5, "CALG_RC5" },
|
||||||
|
{ CALG_RSA_KEYX, "CALG_RSA_KEYX" },
|
||||||
|
{ CALG_RSA_SIGN, "CALG_RSA_SIGN" },
|
||||||
|
{ CALG_SHA, "CALG_SHA" },
|
||||||
|
{ CALG_SHA1, "CALG_SHA1" },
|
||||||
|
{ CALG_SHA_256, "CALG_SHA_256" },
|
||||||
|
{ CALG_SHA_384, "CALG_SHA_384" },
|
||||||
|
{ CALG_SHA_512, "CALG_SHA_512" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_ALG_ID 50
|
||||||
|
|
||||||
void ma_schannel_set_sec_error(MARIADB_PVIO *pvio, DWORD ErrorNo);
|
void ma_schannel_set_sec_error(MARIADB_PVIO *pvio, DWORD ErrorNo);
|
||||||
void ma_schannel_set_win_error(MYSQL *mysql);
|
void ma_schannel_set_win_error(MYSQL *mysql);
|
||||||
|
|
||||||
const struct st_cipher_suite sc_ciphers[]=
|
HCERTSTORE ca_CertStore= NULL,
|
||||||
{
|
crl_CertStore= NULL;
|
||||||
{CALG_3DES, "CALG_3DES"},
|
my_bool ca_Check = 0, crl_Check = 0;
|
||||||
{CALG_3DES_112, "CALG_3DES_112"},
|
|
||||||
{CALG_AES, "CALG_AES"},
|
|
||||||
{CALG_AES_128, "CALG_AES_128"},
|
|
||||||
{CALG_AES_192, "CALG_AES_192"},
|
|
||||||
{CALG_AES_256, "CALG_AES_256"},
|
|
||||||
{CALG_AGREEDKEY_ANY, "CALG_AGREEDKEY_ANY"},
|
|
||||||
{CALG_CYLINK_MEK, "CALG_CYLINK_MEK"},
|
|
||||||
{CALG_DES, "CALG_DES"},
|
|
||||||
{CALG_DESX, "CALG_DESX"},
|
|
||||||
{CALG_DH_EPHEM, "CALG_DH_EPHEM"},
|
|
||||||
{CALG_DH_SF, "CALG_DH_SF"},
|
|
||||||
{CALG_DSS_SIGN, "CALG_DSS_SIGN"},
|
|
||||||
{CALG_ECDH, "CALG_ECDH"},
|
|
||||||
{CALG_ECDSA, "CALG_ECDSA"},
|
|
||||||
{CALG_ECMQV, "CALG_ECMQV"},
|
|
||||||
{CALG_HASH_REPLACE_OWF, "CALG_HASH_REPLACE_OWF"},
|
|
||||||
{CALG_HUGHES_MD5, "CALG_HUGHES_MD5"},
|
|
||||||
{CALG_HMAC, "CALG_HMAC"},
|
|
||||||
{CALG_KEA_KEYX, "CALG_KEA_KEYX"},
|
|
||||||
{CALG_MAC, "CALG_MAC"},
|
|
||||||
{CALG_MD2, "CALG_MD2"},
|
|
||||||
{CALG_MD4, "CALG_MD4"},
|
|
||||||
{CALG_MD4, "CALG_MD5"},
|
|
||||||
{CALG_NO_SIGN, "CALG_NO_SIGN"},
|
|
||||||
{CALG_OID_INFO_CNG_ONLY, "CALG_OID_INFO_CNG_ONLY"},
|
|
||||||
{CALG_OID_INFO_PARAMETERS, "CALG_OID_INFO_PARAMETERS"},
|
|
||||||
{CALG_PCT1_MASTER, "CALG_PCT1_MASTER"},
|
|
||||||
{CALG_RC2, "CALG_RC2"},
|
|
||||||
{CALG_RC4, "CALG_RC4"},
|
|
||||||
{CALG_RC5, "CALG_RC5"},
|
|
||||||
{CALG_RSA_KEYX, "CALG_RSA_KEYX"},
|
|
||||||
{CALG_RSA_SIGN, "CALG_RSA_SIGN"},
|
|
||||||
{CALG_SCHANNEL_MAC_KEY, "CALG_SCHANNEL_MAC_KEY"},
|
|
||||||
{CALG_SCHANNEL_MASTER_HASH, "CALG_SCHANNEL_MASTER_HASH"},
|
|
||||||
{CALG_SEAL, "CALG_SEAL"},
|
|
||||||
{CALG_SHA, "CALG_SHA"},
|
|
||||||
{CALG_SHA1, "CALG_SHA1"},
|
|
||||||
{CALG_SHA_256, "CALG_SHA_256"},
|
|
||||||
{CALG_SHA_384, "CALG_SHA_384"},
|
|
||||||
{CALG_SHA_512, "CALG_SHA_512"},
|
|
||||||
{CALG_SKIPJACK, "CALG_SKIPJACK"},
|
|
||||||
{CALG_SSL2_MASTER, "CALG_SSL2_MASTER"},
|
|
||||||
{CALG_SSL3_MASTER, "CALG_SSL3_MASTER"},
|
|
||||||
{CALG_SSL3_SHAMD5, "CALG_SSL3_SHAMD5"},
|
|
||||||
{CALG_TEK, "CALG_TEK"},
|
|
||||||
{CALG_TLS1_MASTER, "CALG_TLS1_MASTER"},
|
|
||||||
{CALG_TLS1PRF, "CALG_TLS1PRF"},
|
|
||||||
{0, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ssl_thread_init()
|
static int ssl_thread_init()
|
||||||
{
|
{
|
||||||
@@ -113,7 +109,17 @@ int ma_ssl_start(char *errmsg, size_t errmsg_len)
|
|||||||
{
|
{
|
||||||
pthread_mutex_init(&LOCK_schannel_config,MY_MUTEX_INIT_FAST);
|
pthread_mutex_init(&LOCK_schannel_config,MY_MUTEX_INIT_FAST);
|
||||||
pthread_mutex_lock(&LOCK_schannel_config);
|
pthread_mutex_lock(&LOCK_schannel_config);
|
||||||
ma_ssl_initialized= TRUE;
|
if (!ca_CertStore)
|
||||||
|
{
|
||||||
|
if (!(ca_CertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 0, NULL)) ||
|
||||||
|
!(crl_CertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 0, NULL)))
|
||||||
|
{
|
||||||
|
snprintf(errmsg, errmsg_len, "Can't open in-memory certstore. Error=%d", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ma_ssl_initialized = TRUE;
|
||||||
pthread_mutex_unlock(&LOCK_schannel_config);
|
pthread_mutex_unlock(&LOCK_schannel_config);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -133,14 +139,23 @@ int ma_ssl_start(char *errmsg, size_t errmsg_len)
|
|||||||
*/
|
*/
|
||||||
void ma_ssl_end()
|
void ma_ssl_end()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_schannel_config);
|
|
||||||
if (ma_ssl_initialized)
|
if (ma_ssl_initialized)
|
||||||
{
|
{
|
||||||
|
pthread_mutex_lock(&LOCK_schannel_config);
|
||||||
ma_ssl_initialized= FALSE;
|
if (ca_CertStore)
|
||||||
|
{
|
||||||
|
CertCloseStore(ca_CertStore, 0);
|
||||||
|
ca_CertStore = 0;
|
||||||
}
|
}
|
||||||
|
if (crl_CertStore)
|
||||||
|
{
|
||||||
|
CertCloseStore(crl_CertStore, 0);
|
||||||
|
crl_CertStore = 0;
|
||||||
|
}
|
||||||
|
ma_ssl_initialized= FALSE;
|
||||||
pthread_mutex_unlock(&LOCK_schannel_config);
|
pthread_mutex_unlock(&LOCK_schannel_config);
|
||||||
pthread_mutex_destroy(&LOCK_schannel_config);
|
pthread_mutex_destroy(&LOCK_schannel_config);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,32 +166,26 @@ static int ma_ssl_set_client_certs(MARIADB_SSL *cssl)
|
|||||||
char *certfile= mysql->options.ssl_cert,
|
char *certfile= mysql->options.ssl_cert,
|
||||||
*keyfile= mysql->options.ssl_key,
|
*keyfile= mysql->options.ssl_key,
|
||||||
*cafile= mysql->options.ssl_ca;
|
*cafile= mysql->options.ssl_ca;
|
||||||
|
PCERT_CONTEXT ca_ctx= NULL;
|
||||||
|
PCRL_CONTEXT crl_ctx = NULL;
|
||||||
|
|
||||||
SC_CTX *sctx= (SC_CTX *)cssl->ssl;
|
SC_CTX *sctx= (SC_CTX *)cssl->ssl;
|
||||||
MARIADB_PVIO *pvio= cssl->pvio;
|
MARIADB_PVIO *pvio= cssl->pvio;
|
||||||
|
|
||||||
if (cafile)
|
if (cafile)
|
||||||
{
|
{
|
||||||
HCERTSTORE myCS= NULL;
|
if (!(ca_ctx = ma_schannel_create_cert_context(pvio, cafile)))
|
||||||
|
|
||||||
if (!(sctx->client_ca_ctx = ma_schannel_create_cert_context(pvio, cafile)))
|
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* For X509 authentication we need to add ca certificate to local MY store.
|
/* Add ca to in-memory certificate store */
|
||||||
Schannel doesn't provide a callback to send ca to server during handshake */
|
if (CertAddCertificateContextToStore(ca_CertStore, ca_ctx, CERT_STORE_ADD_NEWER, NULL) != TRUE &&
|
||||||
if ((myCS= CertOpenStore(CERT_STORE_PROV_SYSTEM,
|
GetLastError() != CRYPT_E_EXISTS)
|
||||||
0, //X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
|
||||||
0,
|
|
||||||
CERT_SYSTEM_STORE_CURRENT_USER,
|
|
||||||
L"CA")))
|
|
||||||
{
|
{
|
||||||
CertAddCertificateContextToStore(myCS, sctx->client_ca_ctx, CERT_STORE_ADD_NEWER, NULL);
|
|
||||||
CertCloseStore(myCS, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ma_schannel_set_win_error(sctx->mysql);
|
ma_schannel_set_win_error(sctx->mysql);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
ca_Check= 0;
|
||||||
|
CertFreeCertificateContext(ca_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!certfile && keyfile)
|
if (!certfile && keyfile)
|
||||||
@@ -194,20 +203,28 @@ static int ma_ssl_set_client_certs(MARIADB_SSL *cssl)
|
|||||||
|
|
||||||
if (mysql->options.extension && mysql->options.extension->ssl_crl)
|
if (mysql->options.extension && mysql->options.extension->ssl_crl)
|
||||||
{
|
{
|
||||||
if (!(sctx->client_crl_ctx= (CRL_CONTEXT *)ma_schannel_create_crl_context(pvio, mysql->options.extension->ssl_crl)))
|
if (!(crl_ctx= (CRL_CONTEXT *)ma_schannel_create_crl_context(pvio, mysql->options.extension->ssl_crl)))
|
||||||
goto end;
|
goto end;
|
||||||
|
/* Add ca to in-memory certificate store */
|
||||||
|
if (CertAddCRLContextToStore(crl_CertStore, crl_ctx, CERT_STORE_ADD_NEWER, NULL) != TRUE &&
|
||||||
|
GetLastError() != CRYPT_E_EXISTS)
|
||||||
|
{
|
||||||
|
ma_schannel_set_win_error(sctx->mysql);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
crl_Check = 1;
|
||||||
|
CertFreeCertificateContext(ca_ctx);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (sctx->client_ca_ctx)
|
if (ca_ctx)
|
||||||
CertFreeCertificateContext(sctx->client_ca_ctx);
|
CertFreeCertificateContext(ca_ctx);
|
||||||
if (sctx->client_cert_ctx)
|
if (sctx->client_cert_ctx)
|
||||||
CertFreeCertificateContext(sctx->client_cert_ctx);
|
CertFreeCertificateContext(sctx->client_cert_ctx);
|
||||||
if (sctx->client_crl_ctx)
|
if (crl_ctx)
|
||||||
CertFreeCRLContext(sctx->client_crl_ctx);
|
CertFreeCRLContext(crl_ctx);
|
||||||
sctx->client_ca_ctx= sctx->client_cert_ctx= NULL;
|
sctx->client_cert_ctx= NULL;
|
||||||
sctx->client_crl_ctx= NULL;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -243,7 +260,7 @@ my_bool ma_ssl_connect(MARIADB_SSL *cssl)
|
|||||||
SECURITY_STATUS sRet;
|
SECURITY_STATUS sRet;
|
||||||
PCCERT_CONTEXT pRemoteCertContext = NULL,
|
PCCERT_CONTEXT pRemoteCertContext = NULL,
|
||||||
pLocalCertContext= NULL;
|
pLocalCertContext= NULL;
|
||||||
ALG_ID AlgId[2]= {0, 0};
|
ALG_ID AlgId[MAX_ALG_ID]= {0};
|
||||||
|
|
||||||
if (!cssl || !cssl->pvio)
|
if (!cssl || !cssl->pvio)
|
||||||
return 1;;
|
return 1;;
|
||||||
@@ -260,23 +277,34 @@ my_bool ma_ssl_connect(MARIADB_SSL *cssl)
|
|||||||
if (ma_ssl_set_client_certs(cssl))
|
if (ma_ssl_set_client_certs(cssl))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
ZeroMemory(&Cred, sizeof(SCHANNEL_CRED));
|
||||||
|
|
||||||
/* Set cipher */
|
/* Set cipher */
|
||||||
if (mysql->options.ssl_cipher)
|
if (mysql->options.ssl_cipher)
|
||||||
{
|
{
|
||||||
DWORD i= 0;
|
WORD validTokens = 0;
|
||||||
while (sc_ciphers[i].cipher) {
|
char *token = strtok(mysql->options.ssl_cipher, ":");
|
||||||
if (!strcmp(sc_ciphers[i].cipher, mysql->options.ssl_cipher))
|
while (token)
|
||||||
{
|
{
|
||||||
AlgId[0]= sc_ciphers[i].aid;
|
struct st_cipher_suite *valid;
|
||||||
|
for (valid = valid_ciphers; valid && valid->aid; valid++)
|
||||||
|
{
|
||||||
|
if (!strcmp(token, valid->cipher))
|
||||||
|
{
|
||||||
|
AlgId[validTokens++] = valid->aid;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Cred.palgSupportedAlgs= (ALG_ID *)&AlgId;
|
token = strtok(NULL, ":");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Cred.palgSupportedAlgs = (ALG_ID *)&AlgId;
|
||||||
|
|
||||||
|
|
||||||
ZeroMemory(&Cred, sizeof(SCHANNEL_CRED));
|
|
||||||
Cred.dwVersion= SCHANNEL_CRED_VERSION;
|
Cred.dwVersion= SCHANNEL_CRED_VERSION;
|
||||||
|
if (mysql->options.extension)
|
||||||
|
Cred.dwMinimumCipherStrength = MAX(128, mysql->options.extension->ssl_cipher_strength);
|
||||||
|
else
|
||||||
|
Cred.dwMinimumCipherStrength = 128;
|
||||||
Cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK | SCH_SEND_ROOT_CERT |
|
Cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK | SCH_SEND_ROOT_CERT |
|
||||||
SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_MANUAL_CRED_VALIDATION;
|
SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_MANUAL_CRED_VALIDATION;
|
||||||
if (sctx->client_cert_ctx)
|
if (sctx->client_cert_ctx)
|
||||||
@@ -284,7 +312,7 @@ my_bool ma_ssl_connect(MARIADB_SSL *cssl)
|
|||||||
Cred.cCreds = 1;
|
Cred.cCreds = 1;
|
||||||
Cred.paCred = &sctx->client_cert_ctx;
|
Cred.paCred = &sctx->client_cert_ctx;
|
||||||
}
|
}
|
||||||
Cred.grbitEnabledProtocols= SP_PROT_TLS1_1PLUS;
|
Cred.grbitEnabledProtocols = SP_PROT_TLS1_0 | SP_PROT_TLS1_1 | SP_PROT_TLS1_2;
|
||||||
|
|
||||||
if ((sRet= AcquireCredentialsHandleA(NULL, UNISP_NAME_A, SECPKG_CRED_OUTBOUND,
|
if ((sRet= AcquireCredentialsHandleA(NULL, UNISP_NAME_A, SECPKG_CRED_OUTBOUND,
|
||||||
NULL, &Cred, NULL, NULL, &sctx->CredHdl, NULL)) != SEC_E_OK)
|
NULL, &Cred, NULL, NULL, &sctx->CredHdl, NULL)) != SEC_E_OK)
|
||||||
@@ -315,15 +343,9 @@ end:
|
|||||||
if (rc && sctx->IoBufferSize)
|
if (rc && sctx->IoBufferSize)
|
||||||
LocalFree(sctx->IoBuffer);
|
LocalFree(sctx->IoBuffer);
|
||||||
sctx->IoBufferSize= 0;
|
sctx->IoBufferSize= 0;
|
||||||
if (sctx->client_ca_ctx)
|
|
||||||
CertFreeCertificateContext(sctx->client_ca_ctx);
|
|
||||||
if (sctx->client_cert_ctx)
|
if (sctx->client_cert_ctx)
|
||||||
CertFreeCertificateContext(sctx->client_cert_ctx);
|
CertFreeCertificateContext(sctx->client_cert_ctx);
|
||||||
if (sctx->client_crl_ctx)
|
|
||||||
CertFreeCRLContext(sctx->client_crl_ctx);
|
|
||||||
sctx->client_ca_ctx= 0;
|
|
||||||
sctx->client_cert_ctx= 0;
|
sctx->client_cert_ctx= 0;
|
||||||
sctx->client_crl_ctx= 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,12 +385,8 @@ my_bool ma_ssl_close(MARIADB_SSL *cssl)
|
|||||||
{
|
{
|
||||||
if (sctx->IoBufferSize)
|
if (sctx->IoBufferSize)
|
||||||
LocalFree(sctx->IoBuffer);
|
LocalFree(sctx->IoBuffer);
|
||||||
if (sctx->client_ca_ctx)
|
|
||||||
CertFreeCertificateContext(sctx->client_ca_ctx);
|
|
||||||
if (sctx->client_cert_ctx)
|
if (sctx->client_cert_ctx)
|
||||||
CertFreeCertificateContext(sctx->client_cert_ctx);
|
CertFreeCertificateContext(sctx->client_cert_ctx);
|
||||||
if (sctx->client_crl_ctx)
|
|
||||||
CertFreeCRLContext(sctx->client_crl_ctx);
|
|
||||||
FreeCredentialHandle(&sctx->CredHdl);
|
FreeCredentialHandle(&sctx->CredHdl);
|
||||||
DeleteSecurityContext(&sctx->ctxt);
|
DeleteSecurityContext(&sctx->ctxt);
|
||||||
}
|
}
|
||||||
@@ -458,10 +476,10 @@ const char *ma_ssl_get_cipher(MARIADB_SSL *cssl)
|
|||||||
if (sRet != SEC_E_OK)
|
if (sRet != SEC_E_OK)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while (sc_ciphers[i].cipher)
|
while (valid_ciphers[i].cipher)
|
||||||
{
|
{
|
||||||
if (sc_ciphers[i].aid == cinfo.aiCipher)
|
if (valid_ciphers[i].aid == cinfo.aiCipher)
|
||||||
return sc_ciphers[i].cipher;
|
return valid_ciphers[i].cipher;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -51,21 +51,21 @@ IF(WITH_SSL AND OPENSSL_FOUND)
|
|||||||
STRING(REPLACE "\n" "" FINGER_PRINT "${FINGER_PRINT}")
|
STRING(REPLACE "\n" "" FINGER_PRINT "${FINGER_PRINT}")
|
||||||
STRING(REPLACE ":" "" SSL_CERT_FINGER_PRINT "${FINGER_PRINT}")
|
STRING(REPLACE ":" "" SSL_CERT_FINGER_PRINT "${FINGER_PRINT}")
|
||||||
|
|
||||||
|
ENDIF()
|
||||||
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/unittest/libmariadb/ssl.c.in
|
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/unittest/libmariadb/ssl.c.in
|
||||||
${CMAKE_SOURCE_DIR}/unittest/libmariadb/ssl.c)
|
${CMAKE_SOURCE_DIR}/unittest/libmariadb/ssl.c)
|
||||||
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/unittest/libmariadb/fingerprint.list.in
|
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/unittest/libmariadb/fingerprint.list.in
|
||||||
${CMAKE_SOURCE_DIR}/unittest/libmariadb/fingerprint.list)
|
${CMAKE_SOURCE_DIR}/unittest/libmariadb/fingerprint.list)
|
||||||
SET(API_TESTS ${API_TESTS} "ssl")
|
SET(API_TESTS ${API_TESTS} "ssl")
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
FOREACH(API_TEST ${API_TESTS})
|
FOREACH(API_TEST ${API_TESTS})
|
||||||
ADD_EXECUTABLE(${API_TEST} ${API_TEST}.c ${CMAKE_SOURCE_DIR}/libmariadb/getopt.c)
|
ADD_EXECUTABLE(${API_TEST} ${API_TEST}.c ${CMAKE_SOURCE_DIR}/libmariadb/getopt.c)
|
||||||
TARGET_LINK_LIBRARIES(${API_TEST} mytap libmariadb)
|
TARGET_LINK_LIBRARIES(${API_TEST} mytap mariadbclient)
|
||||||
ADD_TEST(${API_TEST} ${EXECUTABLE_OUTPUT_PATH}/${API_TEST})
|
ADD_TEST(${API_TEST} ${EXECUTABLE_OUTPUT_PATH}/${API_TEST})
|
||||||
SET_TESTS_PROPERTIES(${API_TEST} PROPERTIES TIMEOUT 120)
|
SET_TESTS_PROPERTIES(${API_TEST} PROPERTIES TIMEOUT 120)
|
||||||
ENDFOREACH(API_TEST)
|
ENDFOREACH(API_TEST)
|
||||||
|
|
||||||
FOREACH(API_TEST ${MANUAL_TESTS})
|
FOREACH(API_TEST ${MANUAL_TESTS})
|
||||||
ADD_EXECUTABLE(${API_TEST} ${API_TEST}.c ${CMAKE_SOURCE_DIR}/libmariadb/getopt.c)
|
ADD_EXECUTABLE(${API_TEST} ${API_TEST}.c ${CMAKE_SOURCE_DIR}/libmariadb/getopt.c)
|
||||||
TARGET_LINK_LIBRARIES(${API_TEST} mytap libmariadb)
|
TARGET_LINK_LIBRARIES(${API_TEST} mytap mariadbclient)
|
||||||
ENDFOREACH()
|
ENDFOREACH()
|
||||||
|
@@ -794,6 +794,33 @@ static int test_ssl_version(MYSQL *mysql)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SCHANNEL
|
||||||
|
static int test_schannel_cipher(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
MYSQL *my;
|
||||||
|
unsigned int cipher_strength= 256;
|
||||||
|
|
||||||
|
if (check_skip_ssl())
|
||||||
|
return SKIP;
|
||||||
|
|
||||||
|
my= mysql_init(NULL);
|
||||||
|
FAIL_IF(!my, "mysql_init() failed");
|
||||||
|
|
||||||
|
mysql_ssl_set(my,0, 0, "@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/ca-cert.pem", 0, 0);
|
||||||
|
mysql_options(my, MARIADB_OPT_SSL_CIPHER_STRENGTH, &cipher_strength);
|
||||||
|
FAIL_IF(!mysql_real_connect(my, hostname, ssluser, sslpw, schema,
|
||||||
|
port, socketname, 0), mysql_error(my));
|
||||||
|
|
||||||
|
diag("cipher: %s", mysql_get_ssl_cipher(my));
|
||||||
|
FAIL_IF(strcmp(mysql_get_ssl_cipher(my), "CALG_AES_256") != 0, "expected cipher with 256bit strength");
|
||||||
|
|
||||||
|
mysql_close(my);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
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},
|
||||||
@@ -816,6 +843,8 @@ struct my_tests_st my_tests[] = {
|
|||||||
{"test_ssl_threads", test_ssl_threads, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_ssl_threads", test_ssl_threads, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
#ifndef HAVE_SCHANNEL
|
#ifndef HAVE_SCHANNEL
|
||||||
{"test_password_protected", test_password_protected, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_password_protected", test_password_protected, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
|
#else
|
||||||
|
{"test_schannel_cipher", test_schannel_cipher, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
#endif
|
#endif
|
||||||
{NULL, NULL, 0, 0, NULL, NULL}
|
{NULL, NULL, 0, 0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user