Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
c4ef1efd
Unverified
Commit
c4ef1efd
authored
Mar 22, 2021
by
Yossi Gottlieb
Committed by
GitHub
Mar 22, 2021
Browse files
Add support for reading encrypted keyfiles. (#8644)
parent
c3df27d1
Changes
5
Hide whitespace changes
Inline
Side-by-side
redis.conf
View file @
c4ef1efd
...
@@ -150,6 +150,11 @@ tcp-keepalive 300
...
@@ -150,6 +150,11 @@ tcp-keepalive 300
#
#
# tls-cert-file redis.crt
# tls-cert-file redis.crt
# tls-key-file redis.key
# tls-key-file redis.key
#
# If the key file is encrypted using a passphrase, it can be included here
# as well.
#
# tls-key-file-pass secret
# Normally Redis uses the same certificate for both server functions (accepting
# Normally Redis uses the same certificate for both server functions (accepting
# connections) and client functions (replicating from a master, establishing
# connections) and client functions (replicating from a master, establishing
...
@@ -162,6 +167,11 @@ tcp-keepalive 300
...
@@ -162,6 +167,11 @@ tcp-keepalive 300
#
#
# tls-client-cert-file client.crt
# tls-client-cert-file client.crt
# tls-client-key-file client.key
# tls-client-key-file client.key
#
# If the key file is encrypted using a passphrase, it can be included here
# as well.
#
# tls-client-key-file-pass secret
# Configure a DH parameters file to enable Diffie-Hellman (DH) key exchange:
# Configure a DH parameters file to enable Diffie-Hellman (DH) key exchange:
#
#
...
...
src/config.c
View file @
c4ef1efd
...
@@ -2543,8 +2543,10 @@ standardConfig configs[] = {
...
@@ -2543,8 +2543,10 @@ standardConfig configs[] = {
createBoolConfig
(
"tls-session-caching"
,
NULL
,
MODIFIABLE_CONFIG
,
server
.
tls_ctx_config
.
session_caching
,
1
,
NULL
,
updateTlsCfgBool
),
createBoolConfig
(
"tls-session-caching"
,
NULL
,
MODIFIABLE_CONFIG
,
server
.
tls_ctx_config
.
session_caching
,
1
,
NULL
,
updateTlsCfgBool
),
createStringConfig
(
"tls-cert-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
cert_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-cert-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
cert_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-key-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
key_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-key-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
key_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-key-file-pass"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
key_file_pass
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-client-cert-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
client_cert_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-client-cert-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
client_cert_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-client-key-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
client_key_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-client-key-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
client_key_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-client-key-file-pass"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
client_key_file_pass
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-dh-params-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
dh_params_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-dh-params-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
dh_params_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-ca-cert-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
ca_cert_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-ca-cert-file"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
ca_cert_file
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-ca-cert-dir"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
ca_cert_dir
,
NULL
,
NULL
,
updateTlsCfg
),
createStringConfig
(
"tls-ca-cert-dir"
,
NULL
,
MODIFIABLE_CONFIG
,
EMPTY_STRING_IS_NULL
,
server
.
tls_ctx_config
.
ca_cert_dir
,
NULL
,
NULL
,
updateTlsCfg
),
...
...
src/server.h
View file @
c4ef1efd
...
@@ -1119,8 +1119,10 @@ typedef struct socketFds {
...
@@ -1119,8 +1119,10 @@ typedef struct socketFds {
typedef
struct
redisTLSContextConfig
{
typedef
struct
redisTLSContextConfig
{
char
*
cert_file
;
/* Server side and optionally client side cert file name */
char
*
cert_file
;
/* Server side and optionally client side cert file name */
char
*
key_file
;
/* Private key filename for cert_file */
char
*
key_file
;
/* Private key filename for cert_file */
char
*
key_file_pass
;
/* Optional password for key_file */
char
*
client_cert_file
;
/* Certificate to use as a client; if none, use cert_file */
char
*
client_cert_file
;
/* Certificate to use as a client; if none, use cert_file */
char
*
client_key_file
;
/* Private key filename for client_cert_file */
char
*
client_key_file
;
/* Private key filename for client_cert_file */
char
*
client_key_file_pass
;
/* Optional password for client_key_file */
char
*
dh_params_file
;
char
*
dh_params_file
;
char
*
ca_cert_file
;
char
*
ca_cert_file
;
char
*
ca_cert_dir
;
char
*
ca_cert_dir
;
...
...
src/tls.c
View file @
c4ef1efd
...
@@ -179,11 +179,28 @@ void tlsCleanup(void) {
...
@@ -179,11 +179,28 @@ void tlsCleanup(void) {
#endif
#endif
}
}
/* Callback for passing a keyfile password stored as an sds to OpenSSL */
static
int
tlsPasswordCallback
(
char
*
buf
,
int
size
,
int
rwflag
,
void
*
u
)
{
UNUSED
(
rwflag
);
const
char
*
pass
=
u
;
size_t
pass_len
;
if
(
!
pass
)
return
-
1
;
pass_len
=
strlen
(
pass
);
if
(
pass_len
>
(
size_t
)
size
)
return
-
1
;
memcpy
(
buf
,
pass
,
pass_len
);
return
(
int
)
pass_len
;
}
/* Create a *base* SSL_CTX using the SSL configuration provided. The base context
/* Create a *base* SSL_CTX using the SSL configuration provided. The base context
* includes everything that's common for both client-side and server-side connections.
* includes everything that's common for both client-side and server-side connections.
*/
*/
static
SSL_CTX
*
createSSLContext
(
redisTLSContextConfig
*
ctx_config
,
int
protocols
,
static
SSL_CTX
*
createSSLContext
(
redisTLSContextConfig
*
ctx_config
,
int
protocols
,
int
client
)
{
const
char
*
cert_file
,
const
char
*
key_file
)
{
const
char
*
cert_file
=
client
?
ctx_config
->
client_cert_file
:
ctx_config
->
cert_file
;
const
char
*
key_file
=
client
?
ctx_config
->
client_key_file
:
ctx_config
->
key_file
;
const
char
*
key_file_pass
=
client
?
ctx_config
->
client_key_file_pass
:
ctx_config
->
key_file_pass
;
char
errbuf
[
256
];
char
errbuf
[
256
];
SSL_CTX
*
ctx
=
NULL
;
SSL_CTX
*
ctx
=
NULL
;
...
@@ -215,6 +232,9 @@ static SSL_CTX *createSSLContext(redisTLSContextConfig *ctx_config, int protocol
...
@@ -215,6 +232,9 @@ static SSL_CTX *createSSLContext(redisTLSContextConfig *ctx_config, int protocol
SSL_CTX_set_mode
(
ctx
,
SSL_MODE_ENABLE_PARTIAL_WRITE
|
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
);
SSL_CTX_set_mode
(
ctx
,
SSL_MODE_ENABLE_PARTIAL_WRITE
|
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
);
SSL_CTX_set_verify
(
ctx
,
SSL_VERIFY_PEER
|
SSL_VERIFY_FAIL_IF_NO_PEER_CERT
,
NULL
);
SSL_CTX_set_verify
(
ctx
,
SSL_VERIFY_PEER
|
SSL_VERIFY_FAIL_IF_NO_PEER_CERT
,
NULL
);
SSL_CTX_set_default_passwd_cb
(
ctx
,
tlsPasswordCallback
);
SSL_CTX_set_default_passwd_cb_userdata
(
ctx
,
(
void
*
)
key_file_pass
);
if
(
SSL_CTX_use_certificate_chain_file
(
ctx
,
cert_file
)
<=
0
)
{
if
(
SSL_CTX_use_certificate_chain_file
(
ctx
,
cert_file
)
<=
0
)
{
ERR_error_string_n
(
ERR_get_error
(),
errbuf
,
sizeof
(
errbuf
));
ERR_error_string_n
(
ERR_get_error
(),
errbuf
,
sizeof
(
errbuf
));
serverLog
(
LL_WARNING
,
"Failed to load certificate: %s: %s"
,
cert_file
,
errbuf
);
serverLog
(
LL_WARNING
,
"Failed to load certificate: %s: %s"
,
cert_file
,
errbuf
);
...
@@ -281,7 +301,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
...
@@ -281,7 +301,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
if
(
protocols
==
-
1
)
goto
error
;
if
(
protocols
==
-
1
)
goto
error
;
/* Create server side/generla context */
/* Create server side/generla context */
ctx
=
createSSLContext
(
ctx_config
,
protocols
,
ctx_config
->
cert_file
,
ctx_config
->
key_file
);
ctx
=
createSSLContext
(
ctx_config
,
protocols
,
0
);
if
(
!
ctx
)
goto
error
;
if
(
!
ctx
)
goto
error
;
if
(
ctx_config
->
session_caching
)
{
if
(
ctx_config
->
session_caching
)
{
...
@@ -332,7 +352,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
...
@@ -332,7 +352,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
/* If a client-side certificate is configured, create an explicit client context */
/* If a client-side certificate is configured, create an explicit client context */
if
(
ctx_config
->
client_cert_file
&&
ctx_config
->
client_key_file
)
{
if
(
ctx_config
->
client_cert_file
&&
ctx_config
->
client_key_file
)
{
client_ctx
=
createSSLContext
(
ctx_config
,
protocols
,
ctx_config
->
client_cert_file
,
ctx_config
->
client_key_file
);
client_ctx
=
createSSLContext
(
ctx_config
,
protocols
,
1
);
if
(
!
client_ctx
)
goto
error
;
if
(
!
client_ctx
)
goto
error
;
}
}
...
...
tests/unit/tls.tcl
View file @
c4ef1efd
...
@@ -139,5 +139,20 @@ start_server {tags {"tls"}} {
...
@@ -139,5 +139,20 @@ start_server {tags {"tls"}} {
$rd PING
$rd PING
$rd close
$rd close
}
}
test
{
TLS: Working with an encrypted keyfile
}
{
# Create an encrypted version
set keyfile
[
lindex
[
r config get tls-key-file
]
1
]
set keyfile_encrypted
"
$keyfile.encrypted
"
exec -ignorestderr openssl rsa -in $keyfile -out $keyfile_encrypted -aes256 -passout pass:1234 2>/dev/null
# Using it without a password fails
catch
{
r config set tls-key-file $keyfile_encrypted
}
e
assert_match
{
*Unable to update TLS*
}
$e
# Now use a password
r config set tls-key-file-pass 1234
r config set tls-key-file $keyfile_encrypted
}
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment