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. */
| 235 | * includes everything that's common for both client-side and server-side connections. |
| 236 | */ |
| 237 | static SSL_CTX *createSSLContext(redisTLSContextConfig *ctx_config, int protocols, int client) { |
| 238 | const char *cert_file = client ? ctx_config->client_cert_file : ctx_config->cert_file; |
| 239 | const char *key_file = client ? ctx_config->client_key_file : ctx_config->key_file; |
| 240 | const char *key_file_pass = client ? ctx_config->client_key_file_pass : ctx_config->key_file_pass; |
| 241 | char errbuf[256]; |
| 242 | SSL_CTX *ctx = NULL; |
| 243 | |
| 244 | ctx = SSL_CTX_new(SSLv23_method()); |
| 245 | |
| 246 | SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3); |
| 247 | |
| 248 | #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS |
| 249 | SSL_CTX_set_options(ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); |
| 250 | #endif |
| 251 | |
| 252 | if (!(protocols & REDIS_TLS_PROTO_TLSv1)) |
| 253 | SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1); |
| 254 | if (!(protocols & REDIS_TLS_PROTO_TLSv1_1)) |
| 255 | SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1); |
| 256 | #ifdef SSL_OP_NO_TLSv1_2 |
| 257 | if (!(protocols & REDIS_TLS_PROTO_TLSv1_2)) |
| 258 | SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2); |
| 259 | #endif |
| 260 | #ifdef SSL_OP_NO_TLSv1_3 |
| 261 | if (!(protocols & REDIS_TLS_PROTO_TLSv1_3)) |
| 262 | SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3); |
| 263 | #endif |
| 264 | |
| 265 | #ifdef SSL_OP_NO_COMPRESSION |
| 266 | SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); |
| 267 | #endif |
| 268 | |
| 269 | SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); |
| 270 | SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); |
| 271 | |
| 272 | SSL_CTX_set_default_passwd_cb(ctx, tlsPasswordCallback); |
| 273 | SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) key_file_pass); |
| 274 | |
| 275 | if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) { |
| 276 | ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); |
| 277 | serverLog(LL_WARNING, "Failed to load certificate: %s: %s", cert_file, errbuf); |
| 278 | goto error; |
| 279 | } |
| 280 | |
| 281 | if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) { |
| 282 | ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); |
| 283 | serverLog(LL_WARNING, "Failed to load private key: %s: %s", key_file, errbuf); |
| 284 | goto error; |
| 285 | } |
| 286 | |
| 287 | if ((ctx_config->ca_cert_file || ctx_config->ca_cert_dir) && |
| 288 | SSL_CTX_load_verify_locations(ctx, ctx_config->ca_cert_file, ctx_config->ca_cert_dir) <= 0) { |
| 289 | ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); |
| 290 | serverLog(LL_WARNING, "Failed to configure CA certificate(s) file/directory: %s", errbuf); |
| 291 | goto error; |
| 292 | } |
| 293 | |
| 294 | if (ctx_config->ciphers && !SSL_CTX_set_cipher_list(ctx, ctx_config->ciphers)) { |
no test coverage detected