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
Merge commit 'b0411b731f5d61df38fe3f783437df13526774f2' into 3.1
This commit is contained in:
@@ -133,11 +133,11 @@ void ma_schannel_set_win_error(MARIADB_PVIO *pvio)
|
|||||||
*/
|
*/
|
||||||
static LPBYTE ma_schannel_load_pem(MARIADB_PVIO *pvio, const char *PemFileName, DWORD *buffer_len)
|
static LPBYTE ma_schannel_load_pem(MARIADB_PVIO *pvio, const char *PemFileName, DWORD *buffer_len)
|
||||||
{
|
{
|
||||||
HANDLE hfile;
|
HANDLE hfile= 0;
|
||||||
char *buffer= NULL;
|
char *buffer= NULL;
|
||||||
DWORD dwBytesRead= 0;
|
DWORD dwBytesRead= 0;
|
||||||
LPBYTE der_buffer= NULL;
|
LPBYTE der_buffer= NULL;
|
||||||
DWORD der_buffer_length;
|
DWORD der_buffer_length= 0;
|
||||||
|
|
||||||
if (buffer_len == NULL)
|
if (buffer_len == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -156,7 +156,7 @@ static LPBYTE ma_schannel_load_pem(MARIADB_PVIO *pvio, const char *PemFileName,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(buffer= LocalAlloc(0, *buffer_len + 1)))
|
if (!(buffer= malloc((size_t)(*buffer_len + 1))))
|
||||||
{
|
{
|
||||||
pvio->set_error(pvio->mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, NULL);
|
pvio->set_error(pvio->mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, NULL);
|
||||||
goto end;
|
goto end;
|
||||||
@@ -192,7 +192,7 @@ static LPBYTE ma_schannel_load_pem(MARIADB_PVIO *pvio, const char *PemFileName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*buffer_len= der_buffer_length;
|
*buffer_len= der_buffer_length;
|
||||||
LocalFree(buffer);
|
free(buffer);
|
||||||
|
|
||||||
return der_buffer;
|
return der_buffer;
|
||||||
|
|
||||||
@@ -208,6 +208,196 @@ end:
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
static LPBYTE ma_schannel_read(MARIADB_PVIO* pvio, const char* PemFile, DWORD* buffer_len)
|
||||||
|
{
|
||||||
|
HANDLE hfile = NULL;
|
||||||
|
char* buffer = NULL;
|
||||||
|
DWORD dwBytesRead = 0;
|
||||||
|
|
||||||
|
if ((hfile = CreateFile(PemFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
ma_schannel_set_win_error(pvio);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(*buffer_len = GetFileSize(hfile, NULL)))
|
||||||
|
{
|
||||||
|
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Invalid pem format");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(buffer = malloc((size_t)* buffer_len + 1)))
|
||||||
|
{
|
||||||
|
pvio->set_error(pvio->mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, NULL);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ReadFile(hfile, buffer, *buffer_len, &dwBytesRead, NULL))
|
||||||
|
{
|
||||||
|
ma_schannel_set_win_error(pvio);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[*buffer_len] = 0;
|
||||||
|
|
||||||
|
CloseHandle(hfile);
|
||||||
|
return buffer;
|
||||||
|
end:
|
||||||
|
if (hfile != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(hfile);
|
||||||
|
if (buffer)
|
||||||
|
free(buffer);
|
||||||
|
*buffer_len = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPBYTE ma_schannel_convert_base64(MARIADB_PVIO* pvio, char* buffer, DWORD buffer_len, DWORD* der_len)
|
||||||
|
{
|
||||||
|
LPBYTE der_buffer = NULL;
|
||||||
|
|
||||||
|
*der_len = 0;
|
||||||
|
|
||||||
|
/* calculate the length of DER binary */
|
||||||
|
if (!CryptStringToBinaryA(buffer, buffer_len, CRYPT_STRING_BASE64HEADER,
|
||||||
|
NULL, der_len, NULL, NULL))
|
||||||
|
{
|
||||||
|
ma_schannel_set_win_error(pvio);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
/* allocate DER binary buffer */
|
||||||
|
if (!(der_buffer = (LPBYTE)malloc(*der_len)))
|
||||||
|
{
|
||||||
|
pvio->set_error(pvio->mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, NULL);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
/* convert to DER binary */
|
||||||
|
if (!CryptStringToBinaryA(buffer, buffer_len, CRYPT_STRING_BASE64HEADER,
|
||||||
|
der_buffer, der_len, NULL, NULL))
|
||||||
|
{
|
||||||
|
ma_schannel_set_win_error(pvio);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
return der_buffer;
|
||||||
|
end:
|
||||||
|
if (der_buffer)
|
||||||
|
free(der_buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWORD ma_schannel_load_certs_and_keys(MARIADB_PVIO* pvio, const char* PemFileName, SC_CTX* ctx)
|
||||||
|
{
|
||||||
|
char* buffer = NULL;
|
||||||
|
char* p, * type;
|
||||||
|
DWORD buffer_len = 0;
|
||||||
|
LPBYTE der_buffer = NULL;
|
||||||
|
DWORD der_buffer_length = 0;
|
||||||
|
|
||||||
|
/* check if cert and key was already loaded */
|
||||||
|
if (ctx->client_cert_ctx && ctx->der_key)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(buffer = ma_schannel_read(pvio, PemFileName, &buffer_len)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
p = buffer;
|
||||||
|
|
||||||
|
while ((p = strstr(p, "-----BEGIN")))
|
||||||
|
{
|
||||||
|
my_bool is_cert = 0;
|
||||||
|
char* cert_end = strstr(p, "-----END");
|
||||||
|
|
||||||
|
if (!cert_end)
|
||||||
|
{
|
||||||
|
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Unknown or unsupported X509 PEM type"); goto error;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(cert_end = strchr(cert_end, '\n')))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if ((type = strstr(p, "CERTIFICATE")) && type < cert_end)
|
||||||
|
{
|
||||||
|
is_cert = 1;
|
||||||
|
/* We only read first certificate, further certificates will be ignored */
|
||||||
|
if (ctx->client_cert_ctx)
|
||||||
|
{
|
||||||
|
p = cert_end;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((type = strstr(p, "PRIVATE KEY")) && type < cert_end)
|
||||||
|
{
|
||||||
|
/* We only read the first key, further keys will be ignored */
|
||||||
|
if (ctx->der_key)
|
||||||
|
{
|
||||||
|
p = cert_end;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Unknown or unsupported X509 PEM type");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(der_buffer = ma_schannel_convert_base64(pvio, p, (DWORD)(cert_end - p), &der_buffer_length)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (is_cert)
|
||||||
|
{
|
||||||
|
if (!(ctx->client_cert_ctx = (CERT_CONTEXT*)CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||||
|
der_buffer, der_buffer_length)))
|
||||||
|
{
|
||||||
|
ma_schannel_set_win_error(pvio);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(ctx->der_key= (struct st_DER *)malloc(sizeof(struct st_DER))))
|
||||||
|
{
|
||||||
|
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Not enough memory");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->der_key->der_buffer = der_buffer;
|
||||||
|
ctx->der_key->der_length = der_buffer_length;
|
||||||
|
|
||||||
|
der_buffer = 0;
|
||||||
|
der_buffer_length = 0;
|
||||||
|
p = cert_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(der_buffer);
|
||||||
|
der_buffer = 0;
|
||||||
|
der_buffer_length = 0;
|
||||||
|
p = cert_end;
|
||||||
|
|
||||||
|
if (ctx->client_cert_ctx && ctx->der_key)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(buffer);
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
if (buffer)
|
||||||
|
free(buffer);
|
||||||
|
if (der_buffer)
|
||||||
|
free(der_buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ma_delete_key_buffer(SC_CTX* ctx)
|
||||||
|
{
|
||||||
|
if (!ctx->der_key)
|
||||||
|
return;
|
||||||
|
free(ctx->der_key->der_buffer);
|
||||||
|
free(ctx->der_key);
|
||||||
|
ctx->der_key = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* {{{ 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) */
|
||||||
/*
|
/*
|
||||||
Create a certification context from ca or cert file
|
Create a certification context from ca or cert file
|
||||||
@@ -281,7 +471,7 @@ PCCRL_CONTEXT ma_schannel_create_crl_context(MARIADB_PVIO *pvio, const char *pem
|
|||||||
ma_schannel_set_win_error(pvio);
|
ma_schannel_set_win_error(pvio);
|
||||||
end:
|
end:
|
||||||
if (der_buffer)
|
if (der_buffer)
|
||||||
LocalFree(der_buffer);
|
free(der_buffer);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -306,10 +496,8 @@ end:
|
|||||||
PCCRL_CONTEXT A pointer to a certification context structure
|
PCCRL_CONTEXT A pointer to a certification context structure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool ma_schannel_load_private_key(MARIADB_PVIO *pvio, const CERT_CONTEXT *ctx, char *key_file)
|
my_bool ma_schannel_load_private_key(MARIADB_PVIO *pvio, SC_CTX *ctx)
|
||||||
{
|
{
|
||||||
DWORD der_buffer_len= 0;
|
|
||||||
LPBYTE der_buffer= NULL;
|
|
||||||
DWORD priv_key_len= 0;
|
DWORD priv_key_len= 0;
|
||||||
LPBYTE priv_key= NULL;
|
LPBYTE priv_key= NULL;
|
||||||
HCRYPTPROV crypt_prov= 0;
|
HCRYPTPROV crypt_prov= 0;
|
||||||
@@ -317,14 +505,16 @@ my_bool ma_schannel_load_private_key(MARIADB_PVIO *pvio, const CERT_CONTEXT *ctx
|
|||||||
CERT_KEY_CONTEXT kpi={ 0 };
|
CERT_KEY_CONTEXT kpi={ 0 };
|
||||||
my_bool rc= 0;
|
my_bool rc= 0;
|
||||||
|
|
||||||
/* load private key into der binary object */
|
if (!ctx->der_key || !ctx->client_cert_ctx)
|
||||||
if (!(der_buffer= ma_schannel_load_pem(pvio, key_file, &der_buffer_len)))
|
{
|
||||||
return 0;
|
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Invalid certificate or key");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
/* determine required buffer size for decoded private key */
|
/* determine required buffer size for decoded private key */
|
||||||
if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||||
PKCS_RSA_PRIVATE_KEY,
|
PKCS_RSA_PRIVATE_KEY,
|
||||||
der_buffer, der_buffer_len,
|
ctx->der_key->der_buffer, ctx->der_key->der_length,
|
||||||
0, NULL,
|
0, NULL,
|
||||||
NULL, &priv_key_len))
|
NULL, &priv_key_len))
|
||||||
{
|
{
|
||||||
@@ -333,18 +523,17 @@ my_bool ma_schannel_load_private_key(MARIADB_PVIO *pvio, const CERT_CONTEXT *ctx
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* allocate buffer for decoded private key */
|
/* allocate buffer for decoded private key */
|
||||||
if (!(priv_key= LocalAlloc(0, priv_key_len)))
|
if (!(priv_key= malloc(priv_key_len)))
|
||||||
{
|
{
|
||||||
pvio->set_error(pvio->mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, NULL);
|
pvio->set_error(pvio->mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, NULL);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decode */
|
|
||||||
if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||||
PKCS_RSA_PRIVATE_KEY,
|
PKCS_RSA_PRIVATE_KEY,
|
||||||
der_buffer, der_buffer_len,
|
ctx->der_key->der_buffer, ctx->der_key->der_length,
|
||||||
0, NULL,
|
0, NULL,
|
||||||
priv_key, &priv_key_len))
|
priv_key, &priv_key_len))
|
||||||
{
|
{
|
||||||
ma_schannel_set_win_error(pvio);
|
ma_schannel_set_win_error(pvio);
|
||||||
goto end;
|
goto end;
|
||||||
@@ -368,19 +557,23 @@ my_bool ma_schannel_load_private_key(MARIADB_PVIO *pvio, const CERT_CONTEXT *ctx
|
|||||||
kpi.cbSize= sizeof(kpi);
|
kpi.cbSize= sizeof(kpi);
|
||||||
|
|
||||||
/* assign private key to certificate context */
|
/* assign private key to certificate context */
|
||||||
if (CertSetCertificateContextProperty(ctx, CERT_KEY_CONTEXT_PROP_ID, 0, &kpi))
|
if (CertSetCertificateContextProperty(ctx->client_cert_ctx, CERT_KEY_CONTEXT_PROP_ID, 0, &kpi))
|
||||||
rc= 1;
|
rc= 1;
|
||||||
else
|
else
|
||||||
ma_schannel_set_win_error(pvio);
|
ma_schannel_set_win_error(pvio);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (der_buffer)
|
if (ctx->der_key)
|
||||||
LocalFree(der_buffer);
|
{
|
||||||
|
free(ctx->der_key->der_buffer);
|
||||||
|
free(ctx->der_key);
|
||||||
|
ctx->der_key = 0;
|
||||||
|
}
|
||||||
if (priv_key)
|
if (priv_key)
|
||||||
{
|
{
|
||||||
if (crypt_key)
|
if (crypt_key)
|
||||||
CryptDestroyKey(crypt_key);
|
CryptDestroyKey(crypt_key);
|
||||||
LocalFree(priv_key);
|
free(priv_key);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
if (crypt_prov)
|
if (crypt_prov)
|
||||||
CryptReleaseContext(crypt_prov, 0);
|
CryptReleaseContext(crypt_prov, 0);
|
||||||
|
@@ -46,9 +46,15 @@
|
|||||||
|
|
||||||
#include <ma_pthread.h>
|
#include <ma_pthread.h>
|
||||||
|
|
||||||
|
struct st_DER {
|
||||||
|
char* der_buffer;
|
||||||
|
DWORD der_length;
|
||||||
|
};
|
||||||
|
|
||||||
struct st_schannel {
|
struct st_schannel {
|
||||||
HCERTSTORE cert_store;
|
HCERTSTORE cert_store;
|
||||||
const CERT_CONTEXT *client_cert_ctx;
|
const CERT_CONTEXT *client_cert_ctx;
|
||||||
|
struct st_DER *der_key;
|
||||||
CredHandle CredHdl;
|
CredHandle CredHdl;
|
||||||
my_bool FreeCredHdl;
|
my_bool FreeCredHdl;
|
||||||
PUCHAR IoBuffer;
|
PUCHAR IoBuffer;
|
||||||
@@ -70,8 +76,9 @@ 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_TLS *ctls);
|
SECURITY_STATUS ma_schannel_client_handshake(MARIADB_TLS *ctls);
|
||||||
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);
|
||||||
my_bool ma_schannel_load_private_key(MARIADB_PVIO *pvio, const CERT_CONTEXT *ctx, char *key_file);
|
my_bool ma_schannel_load_private_key(MARIADB_PVIO *pvio, SC_CTX *ctx);
|
||||||
PCCRL_CONTEXT ma_schannel_create_crl_context(MARIADB_PVIO *pvio, const char *pem_file);
|
PCCRL_CONTEXT ma_schannel_create_crl_context(MARIADB_PVIO *pvio, const char *pem_file);
|
||||||
|
void ma_delete_key_buffer(SC_CTX* ctx);
|
||||||
my_bool ma_schannel_verify_certs(MARIADB_TLS *ctls);
|
my_bool ma_schannel_verify_certs(MARIADB_TLS *ctls);
|
||||||
ssize_t ma_schannel_write_encrypt(MARIADB_PVIO *pvio,
|
ssize_t ma_schannel_write_encrypt(MARIADB_PVIO *pvio,
|
||||||
uchar *WriteBuffer,
|
uchar *WriteBuffer,
|
||||||
|
@@ -154,7 +154,6 @@ cipher_map[] =
|
|||||||
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "DHE-RSA-AES256-GCM-SHA384",
|
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "DHE-RSA-AES256-GCM-SHA384",
|
||||||
{ CALG_DH_EPHEM, CALG_AES_256, CALG_SHA_384, CALG_RSA_SIGN }
|
{ CALG_DH_EPHEM, CALG_AES_256, CALG_SHA_384, CALG_RSA_SIGN }
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_ALG_ID 50
|
#define MAX_ALG_ID 50
|
||||||
@@ -206,6 +205,7 @@ static int ma_tls_set_client_certs(MARIADB_TLS *ctls)
|
|||||||
MARIADB_PVIO *pvio= ctls->pvio;
|
MARIADB_PVIO *pvio= ctls->pvio;
|
||||||
|
|
||||||
sctx->client_cert_ctx= NULL;
|
sctx->client_cert_ctx= NULL;
|
||||||
|
sctx->der_key = NULL;
|
||||||
|
|
||||||
if (!certfile && keyfile)
|
if (!certfile && keyfile)
|
||||||
certfile= keyfile;
|
certfile= keyfile;
|
||||||
@@ -215,15 +215,26 @@ static int ma_tls_set_client_certs(MARIADB_TLS *ctls)
|
|||||||
if (!certfile)
|
if (!certfile)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!(sctx->client_cert_ctx = ma_schannel_create_cert_context(ctls->pvio, certfile)))
|
if (certfile && ma_schannel_load_certs_and_keys(pvio, certfile, sctx))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!ma_schannel_load_private_key(pvio, sctx->client_cert_ctx, keyfile))
|
if (keyfile && ma_schannel_load_certs_and_keys(pvio, keyfile, sctx))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (sctx->client_cert_ctx)
|
||||||
{
|
{
|
||||||
CertFreeCertificateContext(sctx->client_cert_ctx);
|
if (!ma_schannel_load_private_key(pvio, sctx))
|
||||||
sctx->client_cert_ctx= NULL;
|
return 1;
|
||||||
|
}
|
||||||
|
else if (sctx->der_key)
|
||||||
|
{
|
||||||
|
free(sctx->der_key->der_buffer);
|
||||||
|
free(sctx->der_key);
|
||||||
|
sctx->der_key = 0;
|
||||||
|
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Cert not found");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -293,6 +304,9 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
|||||||
SC_CTX *sctx;
|
SC_CTX *sctx;
|
||||||
SECURITY_STATUS sRet;
|
SECURITY_STATUS sRet;
|
||||||
ALG_ID AlgId[MAX_ALG_ID];
|
ALG_ID AlgId[MAX_ALG_ID];
|
||||||
|
size_t i;
|
||||||
|
DWORD protocol = 0;
|
||||||
|
|
||||||
|
|
||||||
if (!ctls || !ctls->pvio)
|
if (!ctls || !ctls->pvio)
|
||||||
return 1;;
|
return 1;;
|
||||||
@@ -310,10 +324,8 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
|||||||
/* Set cipher */
|
/* Set cipher */
|
||||||
if (mysql->options.ssl_cipher)
|
if (mysql->options.ssl_cipher)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
DWORD protocol = 0;
|
|
||||||
|
|
||||||
/* check if a protocol was specified as a cipher:
|
/* check if a protocol was specified as a cipher:
|
||||||
* In this case don't allow cipher suites which belong to newer protocols
|
* In this case don't allow cipher suites which belong to newer protocols
|
||||||
* Please note: There are no cipher suites for TLS1.1
|
* Please note: There are no cipher suites for TLS1.1
|
||||||
*/
|
*/
|
||||||
@@ -533,13 +545,15 @@ const char *ma_tls_get_cipher(MARIADB_TLS *ctls)
|
|||||||
SecPkgContext_CipherInfo CipherInfo = { SECPKGCONTEXT_CIPHERINFO_V1 };
|
SecPkgContext_CipherInfo CipherInfo = { SECPKGCONTEXT_CIPHERINFO_V1 };
|
||||||
SECURITY_STATUS sRet;
|
SECURITY_STATUS sRet;
|
||||||
SC_CTX *sctx;
|
SC_CTX *sctx;
|
||||||
|
SecPkgContext_ConnectionInfo ci;
|
||||||
|
|
||||||
if (!ctls || !ctls->ssl)
|
if (!ctls || !ctls->ssl)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
sctx= (SC_CTX *)ctls->ssl;
|
sctx= (SC_CTX *)ctls->ssl;
|
||||||
|
sRet = QueryContextAttributesA(&sctx->ctxt, SECPKG_ATTR_CONNECTION_INFO, (PVOID)&ci);
|
||||||
|
sRet= QueryContextAttributesA(&sctx->ctxt, SECPKG_ATTR_CIPHER_INFO, (PVOID)&CipherInfo);
|
||||||
|
|
||||||
sRet= QueryContextAttributes(&sctx->ctxt, SECPKG_ATTR_CIPHER_INFO, (PVOID)&CipherInfo);
|
|
||||||
if (sRet != SEC_E_OK)
|
if (sRet != SEC_E_OK)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@@ -16,6 +16,11 @@
|
|||||||
or write to the Free Software Foundation, Inc.,
|
or write to the Free Software Foundation, Inc.,
|
||||||
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
||||||
*************************************************************************************/
|
*************************************************************************************/
|
||||||
|
#if defined(WIN32) && defined(HEAP_CHECK)
|
||||||
|
#define _CRTDBG_MAP_ALLOC
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <crtdbg.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "my_test.h"
|
#include "my_test.h"
|
||||||
#include <ma_pthread.h>
|
#include <ma_pthread.h>
|
||||||
@@ -34,6 +39,7 @@ const char *ssluser= "ssluser";
|
|||||||
const char *sslpw= "sslpw";
|
const char *sslpw= "sslpw";
|
||||||
char sslhost[128];
|
char sslhost[128];
|
||||||
char sslcert[FNLEN];
|
char sslcert[FNLEN];
|
||||||
|
char sslcombined[FNLEN];
|
||||||
char sslkey[FNLEN];
|
char sslkey[FNLEN];
|
||||||
char sslkey_enc[FNLEN];
|
char sslkey_enc[FNLEN];
|
||||||
char sslca[FNLEN];
|
char sslca[FNLEN];
|
||||||
@@ -63,6 +69,7 @@ int check_skip_ssl()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf(sslcert, FNLEN - 1, "%s/%s", ssldir, "client-cert.pem");
|
snprintf(sslcert, FNLEN - 1, "%s/%s", ssldir, "client-cert.pem");
|
||||||
|
snprintf(sslcombined, FNLEN - 1, "%s/%s", ssldir, "client-certkey.pem");
|
||||||
snprintf(sslkey, FNLEN - 1, "%s/%s", ssldir, "client-key.pem");
|
snprintf(sslkey, FNLEN - 1, "%s/%s", ssldir, "client-key.pem");
|
||||||
snprintf(sslkey_enc, FNLEN - 1, "%s/%s", ssldir, "client-key-enc.pem");
|
snprintf(sslkey_enc, FNLEN - 1, "%s/%s", ssldir, "client-key-enc.pem");
|
||||||
snprintf(sslca, FNLEN - 1, "%s/%s", ssldir, "cacert.pem");
|
snprintf(sslca, FNLEN - 1, "%s/%s", ssldir, "cacert.pem");
|
||||||
@@ -1287,6 +1294,33 @@ static int test_mdev14101(MYSQL *my __attribute__((unused)))
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_conc386(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
if (_access(sslcombined, 0) == -1)
|
||||||
|
#else
|
||||||
|
if (access(sslcombined, R_OK) != 0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
diag("combined cert/key file not found");
|
||||||
|
return SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql= mysql_init(NULL);
|
||||||
|
mysql_ssl_set(mysql,
|
||||||
|
sslcombined,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema,
|
||||||
|
port, socketname, 0), mysql_error(mysql));
|
||||||
|
FAIL_IF(check_cipher(mysql) != 0, "Invalid cipher");
|
||||||
|
mysql_close(mysql);
|
||||||
|
unlink(sslcombined);
|
||||||
|
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_mdev14101", test_mdev14101, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
@@ -1323,6 +1357,8 @@ struct my_tests_st my_tests[] = {
|
|||||||
#else
|
#else
|
||||||
{"test_schannel_cipher", test_schannel_cipher, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_schannel_cipher", test_schannel_cipher, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{"test_conc386", test_conc386, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"drop_ssl_user", drop_ssl_user, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"drop_ssl_user", drop_ssl_user, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{NULL, NULL, 0, 0, NULL, NULL}
|
{NULL, NULL, 0, 0, NULL, NULL}
|
||||||
};
|
};
|
||||||
@@ -1330,6 +1366,15 @@ struct my_tests_st my_tests[] = {
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
#if defined(WIN32) && defined(HEAP_CHECK)
|
||||||
|
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
|
||||||
|
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
|
||||||
|
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
|
||||||
|
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
|
||||||
|
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
|
||||||
|
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
|
||||||
|
#endif
|
||||||
|
|
||||||
get_envvars();
|
get_envvars();
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
@@ -1337,6 +1382,9 @@ int main(int argc, char **argv)
|
|||||||
run_tests(my_tests);
|
run_tests(my_tests);
|
||||||
|
|
||||||
mysql_server_end();
|
mysql_server_end();
|
||||||
|
#if defined(WIN32) && defined(HEAP_CHECK)
|
||||||
|
_CrtDumpMemoryLeaks();
|
||||||
|
#endif
|
||||||
return(exit_status());
|
return(exit_status());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user