diff options
| author | Stan Hu <stanhu@gmail.com> | 2022-08-10 09:30:24 -0700 | 
|---|---|---|
| committer | Stan Hu <stanhu@gmail.com> | 2022-08-15 11:21:44 -0700 | 
| commit | 71119a71d71d3c07bb9223de1ac5b4f97db3de0f (patch) | |
| tree | 01d2b34e59a13e373619babe94bf320408e1ecea | |
| parent | 0865c115ba963167214d33541870c6a6318897fb (diff) | |
| download | hiredict-71119a71d71d3c07bb9223de1ac5b4f97db3de0f.tar.xz | |
Make it possible to set SSL verify mode
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 https://github.com/redis/hiredis/issues/646
| -rw-r--r-- | hiredis_ssl.h | 33 | ||||
| -rw-r--r-- | ssl.c | 21 | 
2 files changed, 53 insertions, 1 deletions
| diff --git a/hiredis_ssl.h b/hiredis_ssl.h index e3d3e1c..26bc9e9 100644 --- a/hiredis_ssl.h +++ b/hiredis_ssl.h @@ -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.   */ @@ -102,6 +123,18 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *          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.   */  void redisFreeSSLContext(redisSSLContext *redis_ssl_ctx); @@ -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; @@ -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)) { | 
