Add support for system CA certificate store on Windows
This commit is contained in:
parent
2a5a57b90a
commit
6693863f4c
@ -56,7 +56,9 @@ typedef enum {
|
|||||||
REDIS_SSL_CTX_CERT_KEY_REQUIRED, /* Client cert and key must both be specified or skipped */
|
REDIS_SSL_CTX_CERT_KEY_REQUIRED, /* Client cert and key must both be specified or skipped */
|
||||||
REDIS_SSL_CTX_CA_CERT_LOAD_FAILED, /* Failed to load CA Certificate or CA Path */
|
REDIS_SSL_CTX_CA_CERT_LOAD_FAILED, /* Failed to load CA Certificate or CA Path */
|
||||||
REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED, /* Failed to load client certificate */
|
REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED, /* Failed to load client certificate */
|
||||||
REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED /* Failed to load private key */
|
REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED, /* Failed to load private key */
|
||||||
|
REDIS_SSL_CTX_OS_CERTSTORE_OPEN_FAILED, /* Failed to open system certifcate store */
|
||||||
|
REDIS_SSL_CTX_OS_CERT_ADD_FAILED /* Failed to add CA certificates obtained from system to the SSL context */
|
||||||
} redisSSLContextError;
|
} redisSSLContextError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
43
ssl.c
43
ssl.c
@ -38,6 +38,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <wincrypt.h>
|
||||||
#else
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
@ -182,6 +183,10 @@ const char *redisSSLContextGetError(redisSSLContextError error)
|
|||||||
return "Failed to load client certificate";
|
return "Failed to load client certificate";
|
||||||
case REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED:
|
case REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED:
|
||||||
return "Failed to load private key";
|
return "Failed to load private key";
|
||||||
|
case REDIS_SSL_CTX_OS_CERTSTORE_OPEN_FAILED:
|
||||||
|
return "Failed to open system certifcate store";
|
||||||
|
case REDIS_SSL_CTX_OS_CERT_ADD_FAILED:
|
||||||
|
return "Failed to add CA certificates obtained from system to the SSL context";
|
||||||
default:
|
default:
|
||||||
return "Unknown error code";
|
return "Unknown error code";
|
||||||
}
|
}
|
||||||
@ -214,6 +219,11 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
|
|||||||
const char *cert_filename, const char *private_key_filename,
|
const char *cert_filename, const char *private_key_filename,
|
||||||
const char *server_name, redisSSLContextError *error)
|
const char *server_name, redisSSLContextError *error)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
HCERTSTORE win_store = NULL;
|
||||||
|
PCCERT_CONTEXT win_ctx = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
redisSSLContext *ctx = hi_calloc(1, sizeof(redisSSLContext));
|
redisSSLContext *ctx = hi_calloc(1, sizeof(redisSSLContext));
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
@ -234,6 +244,35 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (capath || cacert_filename) {
|
if (capath || cacert_filename) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (0 == strcmp(cacert_filename, "wincert"))
|
||||||
|
{
|
||||||
|
win_store = CertOpenSystemStore(NULL, "Root");
|
||||||
|
if (!win_store)
|
||||||
|
{
|
||||||
|
if (error) *error = REDIS_SSL_CTX_OS_CERTSTORE_OPEN_FAILED;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
X509_STORE* store = SSL_CTX_get_cert_store(ctx->ssl_ctx);
|
||||||
|
while (win_ctx = CertEnumCertificatesInStore(win_store, win_ctx))
|
||||||
|
{
|
||||||
|
X509* x509 = NULL;
|
||||||
|
x509 = d2i_X509(NULL, (const unsigned char**)&win_ctx->pbCertEncoded, win_ctx->cbCertEncoded);
|
||||||
|
if (x509)
|
||||||
|
{
|
||||||
|
if ((1 != X509_STORE_add_cert(store, x509)) || (1 != SSL_CTX_add_client_CA(ctx->ssl_ctx, x509)))
|
||||||
|
{
|
||||||
|
if (error) *error = REDIS_SSL_CTX_OS_CERT_ADD_FAILED;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
X509_free(x509);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CertFreeCertificateContext(win_ctx);
|
||||||
|
CertCloseStore(win_store, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if (!SSL_CTX_load_verify_locations(ctx->ssl_ctx, cacert_filename, capath)) {
|
if (!SSL_CTX_load_verify_locations(ctx->ssl_ctx, cacert_filename, capath)) {
|
||||||
if (error) *error = REDIS_SSL_CTX_CA_CERT_LOAD_FAILED;
|
if (error) *error = REDIS_SSL_CTX_CA_CERT_LOAD_FAILED;
|
||||||
goto error;
|
goto error;
|
||||||
@ -257,6 +296,10 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
|
|||||||
return ctx;
|
return ctx;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
#ifdef _WIN32
|
||||||
|
CertFreeCertificateContext(win_ctx);
|
||||||
|
CertCloseStore(win_store, 0);
|
||||||
|
#endif
|
||||||
redisFreeSSLContext(ctx);
|
redisFreeSSLContext(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user