Skip to content

Commit 71119a7

Browse files
committed
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 #646
1 parent 0865c11 commit 71119a7

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

hiredis_ssl.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,27 @@ typedef enum {
6161
REDIS_SSL_CTX_OS_CERT_ADD_FAILED /* Failed to add CA certificates obtained from system to the SSL context */
6262
} redisSSLContextError;
6363

64+
/* Constants that mirror OpenSSL's verify modes. By default,
65+
* REDIS_SSL_VERIFY_PEER is used with redisCreateSSLContext().
66+
* Some Redis clients disable peer verification if there are no
67+
* certificates specified.
68+
*/
69+
#define REDIS_SSL_VERIFY_NONE 0x00
70+
#define REDIS_SSL_VERIFY_PEER 0x01
71+
#define REDIS_SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
72+
#define REDIS_SSL_VERIFY_CLIENT_ONCE 0x04
73+
#define REDIS_SSL_VERIFY_POST_HANDSHAKE 0x08
74+
75+
/* Options to create an OpenSSL context. */
76+
typedef struct {
77+
const char *cacert_filename;
78+
const char *capath;
79+
const char *cert_filename;
80+
const char *private_key_filename;
81+
const char *server_name;
82+
int verify_mode;
83+
} redisSSLOptions;
84+
6485
/**
6586
* Return the error message corresponding with the specified error code.
6687
*/
@@ -101,6 +122,18 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
101122
const char *cert_filename, const char *private_key_filename,
102123
const char *server_name, redisSSLContextError *error);
103124

125+
/**
126+
* Helper function to initialize an OpenSSL context that can be used
127+
* to initiate SSL connections. This is a more extensible version of redisCreateSSLContext().
128+
*
129+
* options contains a structure of SSL options to use.
130+
*
131+
* If error is non-null, it will be populated in case the context creation fails
132+
* (returning a NULL).
133+
*/
134+
redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options,
135+
redisSSLContextError *error);
136+
104137
/**
105138
* Free a previously created OpenSSL context.
106139
*/

ssl.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,25 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
219219
const char *cert_filename, const char *private_key_filename,
220220
const char *server_name, redisSSLContextError *error)
221221
{
222+
redisSSLOptions options = {
223+
.cacert_filename = cacert_filename,
224+
.capath = capath,
225+
.cert_filename = cert_filename,
226+
.private_key_filename = private_key_filename,
227+
.server_name = server_name,
228+
.verify_mode = REDIS_SSL_VERIFY_PEER,
229+
};
230+
231+
return redisCreateSSLContextWithOptions(&options, error);
232+
}
233+
234+
redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, redisSSLContextError *error) {
235+
const char *cacert_filename = options->cacert_filename;
236+
const char *capath = options->capath;
237+
const char *cert_filename = options->cert_filename;
238+
const char *private_key_filename = options->private_key_filename;
239+
const char *server_name = options->server_name;
240+
222241
#ifdef _WIN32
223242
HCERTSTORE win_store = NULL;
224243
PCCERT_CONTEXT win_ctx = NULL;
@@ -235,7 +254,7 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
235254
}
236255

237256
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
238-
SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, NULL);
257+
SSL_CTX_set_verify(ctx->ssl_ctx, options->verify_mode, NULL);
239258

240259
if ((cert_filename != NULL && private_key_filename == NULL) ||
241260
(private_key_filename != NULL && cert_filename == NULL)) {

0 commit comments

Comments
 (0)