Skip to content

Commit 8c291b9

Browse files
authoredDec 11, 2020
TLS: Add different client cert support. (redis#8076)
This adds a new `tls-client-cert-file` and `tls-client-key-file` configuration directives which make it possible to use different certificates for the TLS-server and TLS-client functions of Redis. This is an optional directive. If it is not specified the `tls-cert-file` and `tls-key-file` directives are used for TLS client functions as well. Also, `utils/gen-test-certs.sh` now creates additional server-only and client-only certs and will skip intensive operations if target files already exist.
1 parent 4e064fb commit 8c291b9

14 files changed

+220
-94
lines changed
 

‎redis.conf

+12
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,18 @@ tcp-keepalive 300
151151
# tls-cert-file redis.crt
152152
# tls-key-file redis.key
153153

154+
# Normally Redis uses the same certificate for both server functions (accepting
155+
# connections) and client functions (replicating from a master, establishing
156+
# cluster bus connections, etc.).
157+
#
158+
# Sometimes certificates are issued with attributes that designate them as
159+
# client-only or server-only certificates. In that case it may be desired to use
160+
# different certificates for incoming (server) and outgoing (client)
161+
# connections. To do that, use the following directives:
162+
#
163+
# tls-client-cert-file client.crt
164+
# tls-client-key-file client.key
165+
154166
# Configure a DH parameters file to enable Diffie-Hellman (DH) key exchange:
155167
#
156168
# tls-dh-params-file redis.dh

‎src/config.c

+2
Original file line numberDiff line numberDiff line change
@@ -2450,6 +2450,8 @@ standardConfig configs[] = {
24502450
createBoolConfig("tls-session-caching", NULL, MODIFIABLE_CONFIG, server.tls_ctx_config.session_caching, 1, NULL, updateTlsCfgBool),
24512451
createStringConfig("tls-cert-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.cert_file, NULL, NULL, updateTlsCfg),
24522452
createStringConfig("tls-key-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.key_file, NULL, NULL, updateTlsCfg),
2453+
createStringConfig("tls-client-cert-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.client_cert_file, NULL, NULL, updateTlsCfg),
2454+
createStringConfig("tls-client-key-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.client_key_file, NULL, NULL, updateTlsCfg),
24532455
createStringConfig("tls-dh-params-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.dh_params_file, NULL, NULL, updateTlsCfg),
24542456
createStringConfig("tls-ca-cert-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.ca_cert_file, NULL, NULL, updateTlsCfg),
24552457
createStringConfig("tls-ca-cert-dir", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.ca_cert_dir, NULL, NULL, updateTlsCfg),

‎src/sentinel.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ extern char **environ;
4646

4747
#ifdef USE_OPENSSL
4848
extern SSL_CTX *redis_tls_ctx;
49+
extern SSL_CTX *redis_tls_client_ctx;
4950
#endif
5051

5152
#define REDIS_SENTINEL_PORT 26379
@@ -2077,7 +2078,7 @@ static int instanceLinkNegotiateTLS(redisAsyncContext *context) {
20772078
(void) context;
20782079
#else
20792080
if (!redis_tls_ctx) return C_ERR;
2080-
SSL *ssl = SSL_new(redis_tls_ctx);
2081+
SSL *ssl = SSL_new(redis_tls_client_ctx ? redis_tls_client_ctx : redis_tls_ctx);
20812082
if (!ssl) return C_ERR;
20822083

20832084
if (redisInitiateSSL(&context->c, ssl) == REDIS_ERR) return C_ERR;

‎src/server.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -1068,8 +1068,10 @@ struct malloc_stats {
10681068
*----------------------------------------------------------------------------*/
10691069

10701070
typedef struct redisTLSContextConfig {
1071-
char *cert_file;
1072-
char *key_file;
1071+
char *cert_file; /* Server side and optionally client side cert file name */
1072+
char *key_file; /* Private key filename for cert_file */
1073+
char *client_cert_file; /* Certificate to use as a client; if none, use cert_file */
1074+
char *client_key_file; /* Private key filename for client_cert_file */
10731075
char *dh_params_file;
10741076
char *ca_cert_file;
10751077
char *ca_cert_dir;

‎src/tls.c

+100-62
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454

5555
extern ConnectionType CT_Socket;
5656

57-
SSL_CTX *redis_tls_ctx;
57+
SSL_CTX *redis_tls_ctx = NULL;
58+
SSL_CTX *redis_tls_client_ctx = NULL;
5859

5960
static int parseProtocolsConfig(const char *str) {
6061
int i, count = 0;
@@ -163,50 +164,22 @@ void tlsInit(void) {
163164
pending_list = listCreate();
164165
}
165166

166-
/* Attempt to configure/reconfigure TLS. This operation is atomic and will
167-
* leave the SSL_CTX unchanged if fails.
167+
/* Create a *base* SSL_CTX using the SSL configuration provided. The base context
168+
* includes everything that's common for both client-side and server-side connections.
168169
*/
169-
int tlsConfigure(redisTLSContextConfig *ctx_config) {
170+
static SSL_CTX *createSSLContext(redisTLSContextConfig *ctx_config, int protocols,
171+
const char *cert_file, const char *key_file) {
170172
char errbuf[256];
171173
SSL_CTX *ctx = NULL;
172174

173-
if (!ctx_config->cert_file) {
174-
serverLog(LL_WARNING, "No tls-cert-file configured!");
175-
goto error;
176-
}
177-
178-
if (!ctx_config->key_file) {
179-
serverLog(LL_WARNING, "No tls-key-file configured!");
180-
goto error;
181-
}
182-
183-
if (((server.tls_auth_clients != TLS_CLIENT_AUTH_NO) || server.tls_cluster || server.tls_replication) &&
184-
!ctx_config->ca_cert_file && !ctx_config->ca_cert_dir) {
185-
serverLog(LL_WARNING, "Either tls-ca-cert-file or tls-ca-cert-dir must be specified when tls-cluster, tls-replication or tls-auth-clients are enabled!");
186-
goto error;
187-
}
188-
189175
ctx = SSL_CTX_new(SSLv23_method());
190176

191177
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
192-
SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
193178

194179
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
195180
SSL_CTX_set_options(ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
196181
#endif
197182

198-
if (ctx_config->session_caching) {
199-
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);
200-
SSL_CTX_sess_set_cache_size(ctx, ctx_config->session_cache_size);
201-
SSL_CTX_set_timeout(ctx, ctx_config->session_cache_timeout);
202-
SSL_CTX_set_session_id_context(ctx, (void *) "redis", 5);
203-
} else {
204-
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
205-
}
206-
207-
int protocols = parseProtocolsConfig(ctx_config->protocols);
208-
if (protocols == -1) goto error;
209-
210183
if (!(protocols & REDIS_TLS_PROTO_TLSv1))
211184
SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
212185
if (!(protocols & REDIS_TLS_PROTO_TLSv1_1))
@@ -224,38 +197,99 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
224197
SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
225198
#endif
226199

227-
#ifdef SSL_OP_NO_CLIENT_RENEGOTIATION
228-
SSL_CTX_set_options(ctx, SSL_OP_NO_CLIENT_RENEGOTIATION);
229-
#endif
230-
231-
if (ctx_config->prefer_server_ciphers)
232-
SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
233-
234200
SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
235201
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
236-
#if defined(SSL_CTX_set_ecdh_auto)
237-
SSL_CTX_set_ecdh_auto(ctx, 1);
238-
#endif
239202

240-
if (SSL_CTX_use_certificate_chain_file(ctx, ctx_config->cert_file) <= 0) {
203+
if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) {
241204
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
242-
serverLog(LL_WARNING, "Failed to load certificate: %s: %s", ctx_config->cert_file, errbuf);
205+
serverLog(LL_WARNING, "Failed to load certificate: %s: %s", cert_file, errbuf);
243206
goto error;
244207
}
245-
246-
if (SSL_CTX_use_PrivateKey_file(ctx, ctx_config->key_file, SSL_FILETYPE_PEM) <= 0) {
208+
209+
if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) {
247210
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
248-
serverLog(LL_WARNING, "Failed to load private key: %s: %s", ctx_config->key_file, errbuf);
211+
serverLog(LL_WARNING, "Failed to load private key: %s: %s", key_file, errbuf);
249212
goto error;
250213
}
251-
214+
252215
if ((ctx_config->ca_cert_file || ctx_config->ca_cert_dir) &&
253216
SSL_CTX_load_verify_locations(ctx, ctx_config->ca_cert_file, ctx_config->ca_cert_dir) <= 0) {
254217
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
255218
serverLog(LL_WARNING, "Failed to configure CA certificate(s) file/directory: %s", errbuf);
256219
goto error;
257220
}
258221

222+
if (ctx_config->ciphers && !SSL_CTX_set_cipher_list(ctx, ctx_config->ciphers)) {
223+
serverLog(LL_WARNING, "Failed to configure ciphers: %s", ctx_config->ciphers);
224+
goto error;
225+
}
226+
227+
#ifdef TLS1_3_VERSION
228+
if (ctx_config->ciphersuites && !SSL_CTX_set_ciphersuites(ctx, ctx_config->ciphersuites)) {
229+
serverLog(LL_WARNING, "Failed to configure ciphersuites: %s", ctx_config->ciphersuites);
230+
goto error;
231+
}
232+
#endif
233+
234+
return ctx;
235+
236+
error:
237+
if (ctx) SSL_CTX_free(ctx);
238+
return NULL;
239+
}
240+
241+
/* Attempt to configure/reconfigure TLS. This operation is atomic and will
242+
* leave the SSL_CTX unchanged if fails.
243+
*/
244+
int tlsConfigure(redisTLSContextConfig *ctx_config) {
245+
char errbuf[256];
246+
SSL_CTX *ctx = NULL;
247+
SSL_CTX *client_ctx = NULL;
248+
249+
if (!ctx_config->cert_file) {
250+
serverLog(LL_WARNING, "No tls-cert-file configured!");
251+
goto error;
252+
}
253+
254+
if (!ctx_config->key_file) {
255+
serverLog(LL_WARNING, "No tls-key-file configured!");
256+
goto error;
257+
}
258+
259+
if (((server.tls_auth_clients != TLS_CLIENT_AUTH_NO) || server.tls_cluster || server.tls_replication) &&
260+
!ctx_config->ca_cert_file && !ctx_config->ca_cert_dir) {
261+
serverLog(LL_WARNING, "Either tls-ca-cert-file or tls-ca-cert-dir must be specified when tls-cluster, tls-replication or tls-auth-clients are enabled!");
262+
goto error;
263+
}
264+
265+
int protocols = parseProtocolsConfig(ctx_config->protocols);
266+
if (protocols == -1) goto error;
267+
268+
/* Create server side/generla context */
269+
ctx = createSSLContext(ctx_config, protocols, ctx_config->cert_file, ctx_config->key_file);
270+
if (!ctx) goto error;
271+
272+
if (ctx_config->session_caching) {
273+
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);
274+
SSL_CTX_sess_set_cache_size(ctx, ctx_config->session_cache_size);
275+
SSL_CTX_set_timeout(ctx, ctx_config->session_cache_timeout);
276+
SSL_CTX_set_session_id_context(ctx, (void *) "redis", 5);
277+
} else {
278+
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
279+
}
280+
281+
#ifdef SSL_OP_NO_CLIENT_RENEGOTIATION
282+
SSL_CTX_set_options(ctx, SSL_OP_NO_CLIENT_RENEGOTIATION);
283+
#endif
284+
285+
if (ctx_config->prefer_server_ciphers)
286+
SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
287+
288+
#if defined(SSL_CTX_set_ecdh_auto)
289+
SSL_CTX_set_ecdh_auto(ctx, 1);
290+
#endif
291+
SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
292+
259293
if (ctx_config->dh_params_file) {
260294
FILE *dhfile = fopen(ctx_config->dh_params_file, "r");
261295
DH *dh = NULL;
@@ -281,25 +315,22 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
281315
DH_free(dh);
282316
}
283317

284-
if (ctx_config->ciphers && !SSL_CTX_set_cipher_list(ctx, ctx_config->ciphers)) {
285-
serverLog(LL_WARNING, "Failed to configure ciphers: %s", ctx_config->ciphers);
286-
goto error;
318+
/* If a client-side certificate is configured, create an explicit client context */
319+
if (ctx_config->client_cert_file && ctx_config->client_key_file) {
320+
client_ctx = createSSLContext(ctx_config, protocols, ctx_config->client_cert_file, ctx_config->client_key_file);
321+
if (!client_ctx) goto error;
287322
}
288323

289-
#ifdef TLS1_3_VERSION
290-
if (ctx_config->ciphersuites && !SSL_CTX_set_ciphersuites(ctx, ctx_config->ciphersuites)) {
291-
serverLog(LL_WARNING, "Failed to configure ciphersuites: %s", ctx_config->ciphersuites);
292-
goto error;
293-
}
294-
#endif
295-
296324
SSL_CTX_free(redis_tls_ctx);
325+
SSL_CTX_free(redis_tls_client_ctx);
297326
redis_tls_ctx = ctx;
327+
redis_tls_client_ctx = client_ctx;
298328

299329
return C_OK;
300330

301331
error:
302332
if (ctx) SSL_CTX_free(ctx);
333+
if (client_ctx) SSL_CTX_free(client_ctx);
303334
return C_ERR;
304335
}
305336

@@ -344,14 +375,21 @@ typedef struct tls_connection {
344375
listNode *pending_list_node;
345376
} tls_connection;
346377

347-
connection *connCreateTLS(void) {
378+
static connection *createTLSConnection(bool client_side) {
379+
SSL_CTX *ctx = redis_tls_ctx;
380+
if (client_side && redis_tls_client_ctx)
381+
ctx = redis_tls_client_ctx;
348382
tls_connection *conn = zcalloc(sizeof(tls_connection));
349383
conn->c.type = &CT_TLS;
350384
conn->c.fd = -1;
351-
conn->ssl = SSL_new(redis_tls_ctx);
385+
conn->ssl = SSL_new(ctx);
352386
return (connection *) conn;
353387
}
354388

389+
connection *connCreateTLS(void) {
390+
return createTLSConnection(true);
391+
}
392+
355393
/* Fetch the latest OpenSSL error and store it in the connection */
356394
static void updateTLSError(tls_connection *conn) {
357395
conn->c.last_errno = 0;
@@ -370,7 +408,7 @@ static void updateTLSError(tls_connection *conn) {
370408
* is not in an error state.
371409
*/
372410
connection *connCreateAcceptedTLS(int fd, int require_auth) {
373-
tls_connection *conn = (tls_connection *) connCreateTLS();
411+
tls_connection *conn = (tls_connection *) createTLSConnection(false);
374412
conn->c.fd = fd;
375413
conn->c.state = CONN_STATE_ACCEPTING;
376414

‎tests/instances.tcl

+6-4
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,10 @@ proc spawn_instance {type base_port count {conf {}}} {
7676
puts $cfg "tls-replication yes"
7777
puts $cfg "tls-cluster yes"
7878
puts $cfg "port 0"
79-
puts $cfg [format "tls-cert-file %s/../../tls/redis.crt" [pwd]]
80-
puts $cfg [format "tls-key-file %s/../../tls/redis.key" [pwd]]
79+
puts $cfg [format "tls-cert-file %s/../../tls/server.crt" [pwd]]
80+
puts $cfg [format "tls-key-file %s/../../tls/server.key" [pwd]]
81+
puts $cfg [format "tls-client-cert-file %s/../../tls/client.crt" [pwd]]
82+
puts $cfg [format "tls-client-key-file %s/../../tls/client.key" [pwd]]
8183
puts $cfg [format "tls-dh-params-file %s/../../tls/redis.dh" [pwd]]
8284
puts $cfg [format "tls-ca-cert-file %s/../../tls/ca.crt" [pwd]]
8385
puts $cfg "loglevel debug"
@@ -234,8 +236,8 @@ proc parse_options {} {
234236
package require tls 1.6
235237
::tls::init \
236238
-cafile "$::tlsdir/ca.crt" \
237-
-certfile "$::tlsdir/redis.crt" \
238-
-keyfile "$::tlsdir/redis.key"
239+
-certfile "$::tlsdir/client.crt" \
240+
-keyfile "$::tlsdir/client.key"
239241
set ::tls 1
240242
} elseif {$opt eq "--help"} {
241243
puts "--single <pattern> Only runs tests specified by pattern."

‎tests/support/benchmark.tcl

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
proc redisbenchmark_tls_config {testsdir} {
22
set tlsdir [file join $testsdir tls]
3-
set cert [file join $tlsdir redis.crt]
4-
set key [file join $tlsdir redis.key]
3+
set cert [file join $tlsdir client.crt]
4+
set key [file join $tlsdir client.key]
55
set cacert [file join $tlsdir ca.crt]
66

77
if {$::tls} {

‎tests/support/cli.tcl

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
proc rediscli_tls_config {testsdir} {
22
set tlsdir [file join $testsdir tls]
3-
set cert [file join $tlsdir redis.crt]
4-
set key [file join $tlsdir redis.key]
3+
set cert [file join $tlsdir client.crt]
4+
set key [file join $tlsdir client.key]
55
set cacert [file join $tlsdir ca.crt]
66

77
if {$::tls} {

‎tests/support/redis.tcl

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ proc redis {{server 127.0.0.1} {port 6379} {defer 0} {tls 0} {tlsoptions {}}} {
4444
package require tls
4545
::tls::init \
4646
-cafile "$::tlsdir/ca.crt" \
47-
-certfile "$::tlsdir/redis.crt" \
48-
-keyfile "$::tlsdir/redis.key" \
47+
-certfile "$::tlsdir/client.crt" \
48+
-keyfile "$::tlsdir/client.key" \
4949
{*}$tlsoptions
5050
set fd [::tls::socket $server $port]
5151
} else {

‎tests/support/server.tcl

+13-2
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ proc start_server {options {code undefined}} {
229229
# setup defaults
230230
set baseconfig "default.conf"
231231
set overrides {}
232+
set omit {}
232233
set tags {}
233234
set keep_persistence false
234235

@@ -241,6 +242,9 @@ proc start_server {options {code undefined}} {
241242
"overrides" {
242243
set overrides $value
243244
}
245+
"omit" {
246+
set omit $value
247+
}
244248
"tags" {
245249
# If we 'tags' contain multiple tags, quoted and seperated by spaces,
246250
# we want to get rid of the quotes in order to have a proper list
@@ -306,8 +310,10 @@ proc start_server {options {code undefined}} {
306310
set data [split [exec cat "tests/assets/$baseconfig"] "\n"]
307311
set config {}
308312
if {$::tls} {
309-
dict set config "tls-cert-file" [format "%s/tests/tls/redis.crt" [pwd]]
310-
dict set config "tls-key-file" [format "%s/tests/tls/redis.key" [pwd]]
313+
dict set config "tls-cert-file" [format "%s/tests/tls/server.crt" [pwd]]
314+
dict set config "tls-key-file" [format "%s/tests/tls/server.key" [pwd]]
315+
dict set config "tls-client-cert-file" [format "%s/tests/tls/client.crt" [pwd]]
316+
dict set config "tls-client-key-file" [format "%s/tests/tls/client.key" [pwd]]
311317
dict set config "tls-dh-params-file" [format "%s/tests/tls/redis.dh" [pwd]]
312318
dict set config "tls-ca-cert-file" [format "%s/tests/tls/ca.crt" [pwd]]
313319
dict set config "loglevel" "debug"
@@ -343,6 +349,11 @@ proc start_server {options {code undefined}} {
343349
dict set config $directive $arguments
344350
}
345351

352+
# remove directives that are marked to be omitted
353+
foreach directive $omit {
354+
dict unset config $directive
355+
}
356+
346357
# write new configuration to temporary file
347358
set config_file [tmpfile redis.conf]
348359
create_server_config_file $config_file $config

‎tests/test_helper.tcl

+2-2
Original file line numberDiff line numberDiff line change
@@ -602,8 +602,8 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
602602
set ::tls 1
603603
::tls::init \
604604
-cafile "$::tlsdir/ca.crt" \
605-
-certfile "$::tlsdir/redis.crt" \
606-
-keyfile "$::tlsdir/redis.key"
605+
-certfile "$::tlsdir/client.crt" \
606+
-keyfile "$::tlsdir/client.key"
607607
} elseif {$opt eq {--host}} {
608608
set ::external 1
609609
set ::host $arg

‎tests/unit/introspection.tcl

+2
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ start_server {tags {"introspection"}} {
122122
tls-session-caching
123123
tls-cert-file
124124
tls-key-file
125+
tls-client-cert-file
126+
tls-client-key-file
125127
tls-dh-params-file
126128
tls-ca-cert-file
127129
tls-ca-cert-dir

‎tests/unit/tls.tcl

+21
Original file line numberDiff line numberDiff line change
@@ -93,5 +93,26 @@ start_server {tags {"tls"}} {
9393
r CONFIG SET tls-protocols ""
9494
r CONFIG SET tls-ciphers "DEFAULT"
9595
}
96+
97+
test {TLS: Verify tls-cert-file is also used as a client cert if none specified} {
98+
set master [srv 0 client]
99+
set master_host [srv 0 host]
100+
set master_port [srv 0 port]
101+
102+
# Use a non-restricted client/server cert for the replica
103+
set redis_crt [format "%s/tests/tls/redis.crt" [pwd]]
104+
set redis_key [format "%s/tests/tls/redis.key" [pwd]]
105+
106+
start_server [list overrides [list tls-cert-file $redis_crt tls-key-file $redis_key] \
107+
omit [list tls-client-cert-file tls-client-key-file]] {
108+
set replica [srv 0 client]
109+
$replica replicaof $master_host $master_port
110+
wait_for_condition 30 100 {
111+
[string match {*master_link_status:up*} [$replica info replication]]
112+
} else {
113+
fail "Can't authenticate to master using just tls-cert-file!"
114+
}
115+
}
116+
}
96117
}
97118
}

‎utils/gen-test-certs.sh

+50-15
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,58 @@
11
#!/bin/bash
2+
3+
# Generate some test certificates which are used by the regression test suite:
4+
#
5+
# tests/tls/ca.{crt,key} Self signed CA certificate.
6+
# tests/tls/redis.{crt,key} A certificate with no key usage/policy restrictions.
7+
# tests/tls/client.{crt,key} A certificate restricted for SSL client usage.
8+
# tests/tls/server.{crt,key} A certificate restricted fro SSL server usage.
9+
# tests/tls/redis.dh DH Params file.
10+
11+
generate_cert() {
12+
local name=$1
13+
local cn="$2"
14+
local opts="$3"
15+
16+
local keyfile=tests/tls/${name}.key
17+
local certfile=tests/tls/${name}.crt
18+
19+
[ -f $keyfile ] || openssl genrsa -out $keyfile 2048
20+
openssl req \
21+
-new -sha256 \
22+
-subj "/O=Redis Test/CN=$cn" \
23+
-key $keyfile | \
24+
openssl x509 \
25+
-req -sha256 \
26+
-CA tests/tls/ca.crt \
27+
-CAkey tests/tls/ca.key \
28+
-CAserial tests/tls/ca.txt \
29+
-CAcreateserial \
30+
-days 365 \
31+
$opts \
32+
-out $certfile
33+
}
34+
235
mkdir -p tests/tls
3-
openssl genrsa -out tests/tls/ca.key 4096
36+
[ -f tests/tls/ca.key ] || openssl genrsa -out tests/tls/ca.key 4096
437
openssl req \
538
-x509 -new -nodes -sha256 \
639
-key tests/tls/ca.key \
740
-days 3650 \
841
-subj '/O=Redis Test/CN=Certificate Authority' \
942
-out tests/tls/ca.crt
10-
openssl genrsa -out tests/tls/redis.key 2048
11-
openssl req \
12-
-new -sha256 \
13-
-key tests/tls/redis.key \
14-
-subj '/O=Redis Test/CN=Server' | \
15-
openssl x509 \
16-
-req -sha256 \
17-
-CA tests/tls/ca.crt \
18-
-CAkey tests/tls/ca.key \
19-
-CAserial tests/tls/ca.txt \
20-
-CAcreateserial \
21-
-days 365 \
22-
-out tests/tls/redis.crt
23-
openssl dhparam -out tests/tls/redis.dh 2048
43+
44+
cat > tests/tls/openssl.cnf <<_END_
45+
[ server_cert ]
46+
keyUsage = digitalSignature, keyEncipherment
47+
nsCertType = server
48+
49+
[ client_cert ]
50+
keyUsage = digitalSignature, keyEncipherment
51+
nsCertType = client
52+
_END_
53+
54+
generate_cert server "Server-only" "-extfile tests/tls/openssl.cnf -extensions server_cert"
55+
generate_cert client "Client-only" "-extfile tests/tls/openssl.cnf -extensions client_cert"
56+
generate_cert redis "Generic-cert"
57+
58+
[ -f tests/tls/redis.dh ] || openssl dhparam -out tests/tls/redis.dh 2048

0 commit comments

Comments
 (0)
Please sign in to comment.