Skip to content

Commit

Permalink
Make it possible to set SSL verify mode
Browse files Browse the repository at this point in the history
If no SSL certificates are provided, many Redis clients default to
disabling SSL peer verification. Previously it was a bit cumbersome to
configure this because the client would either have to reimplement
`redisCreateSSLContext()` or reach into the internals to set the
OpenSSL verify mode.

We can improve the SSL API by introducing a
`redisCreateSSLContextWithOptions()` call that takes into structured
parameters for SSL initialization. This structure contains a verify
mode that is used to set the OpenSSL verify mode.

Relates to #646
  • Loading branch information
stanhu committed Aug 15, 2022
1 parent 0865c11 commit 71119a7
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
33 changes: 33 additions & 0 deletions hiredis_ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@ typedef enum {
REDIS_SSL_CTX_OS_CERT_ADD_FAILED /* Failed to add CA certificates obtained from system to the SSL context */
} redisSSLContextError;

/* Constants that mirror OpenSSL's verify modes. By default,
* REDIS_SSL_VERIFY_PEER is used with redisCreateSSLContext().
* Some Redis clients disable peer verification if there are no
* certificates specified.
*/
#define REDIS_SSL_VERIFY_NONE 0x00
#define REDIS_SSL_VERIFY_PEER 0x01
#define REDIS_SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
#define REDIS_SSL_VERIFY_CLIENT_ONCE 0x04
#define REDIS_SSL_VERIFY_POST_HANDSHAKE 0x08

/* Options to create an OpenSSL context. */
typedef struct {
const char *cacert_filename;
const char *capath;
const char *cert_filename;
const char *private_key_filename;
const char *server_name;
int verify_mode;
} redisSSLOptions;

/**
* Return the error message corresponding with the specified error code.
*/
Expand Down Expand Up @@ -101,6 +122,18 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
const char *cert_filename, const char *private_key_filename,
const char *server_name, redisSSLContextError *error);

/**
* Helper function to initialize an OpenSSL context that can be used
* to initiate SSL connections. This is a more extensible version of redisCreateSSLContext().
*
* options contains a structure of SSL options to use.
*
* If error is non-null, it will be populated in case the context creation fails
* (returning a NULL).
*/
redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options,
redisSSLContextError *error);

/**
* Free a previously created OpenSSL context.
*/
Expand Down
21 changes: 20 additions & 1 deletion ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,25 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
const char *cert_filename, const char *private_key_filename,
const char *server_name, redisSSLContextError *error)
{
redisSSLOptions options = {
.cacert_filename = cacert_filename,
.capath = capath,
.cert_filename = cert_filename,
.private_key_filename = private_key_filename,
.server_name = server_name,
.verify_mode = REDIS_SSL_VERIFY_PEER,
};

return redisCreateSSLContextWithOptions(&options, error);
}

redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, redisSSLContextError *error) {
const char *cacert_filename = options->cacert_filename;
const char *capath = options->capath;
const char *cert_filename = options->cert_filename;
const char *private_key_filename = options->private_key_filename;
const char *server_name = options->server_name;

#ifdef _WIN32
HCERTSTORE win_store = NULL;
PCCERT_CONTEXT win_ctx = NULL;
Expand All @@ -235,7 +254,7 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
}

SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_verify(ctx->ssl_ctx, options->verify_mode, NULL);

if ((cert_filename != NULL && private_key_filename == NULL) ||
(private_key_filename != NULL && cert_filename == NULL)) {
Expand Down

0 comments on commit 71119a7

Please sign in to comment.