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. */
| 201 | * includes everything that's common for both client-side and server-side connections. |
| 202 | */ |
| 203 | static SSL_CTX *createSSLContext(redisTLSContextConfig *ctx_config, int protocols, int client) { |
| 204 | const char *cert_file = client ? ctx_config->client_cert_file : ctx_config->cert_file; |
| 205 | const char *key_file = client ? ctx_config->client_key_file : ctx_config->key_file; |
| 206 | const char *key_file_pass = client ? ctx_config->client_key_file_pass : ctx_config->key_file_pass; |
| 207 | char errbuf[256]; |
| 208 | SSL_CTX *ctx = NULL; |
| 209 | |
| 210 | ctx = SSL_CTX_new(SSLv23_method()); |
| 211 | |
| 212 | SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3); |
| 213 | |
| 214 | #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS |
| 215 | SSL_CTX_set_options(ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); |
| 216 | #endif |
| 217 | |
| 218 | if (!(protocols & REDIS_TLS_PROTO_TLSv1)) |
| 219 | SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1); |
| 220 | if (!(protocols & REDIS_TLS_PROTO_TLSv1_1)) |
| 221 | SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1); |
| 222 | #ifdef SSL_OP_NO_TLSv1_2 |
| 223 | if (!(protocols & REDIS_TLS_PROTO_TLSv1_2)) |
| 224 | SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2); |
| 225 | #endif |
| 226 | #ifdef SSL_OP_NO_TLSv1_3 |
| 227 | if (!(protocols & REDIS_TLS_PROTO_TLSv1_3)) |
| 228 | SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3); |
| 229 | #endif |
| 230 | |
| 231 | #ifdef SSL_OP_NO_COMPRESSION |
| 232 | SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); |
| 233 | #endif |
| 234 | |
| 235 | SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); |
| 236 | SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); |
| 237 | |
| 238 | SSL_CTX_set_default_passwd_cb(ctx, tlsPasswordCallback); |
| 239 | SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) key_file_pass); |
| 240 | |
| 241 | if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) { |
| 242 | ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); |
| 243 | serverLog(LL_WARNING, "Failed to load certificate: %s: %s", cert_file, errbuf); |
| 244 | goto error; |
| 245 | } |
| 246 | |
| 247 | if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) { |
| 248 | ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); |
| 249 | serverLog(LL_WARNING, "Failed to load private key: %s: %s", key_file, errbuf); |
| 250 | goto error; |
| 251 | } |
| 252 | |
| 253 | if ((ctx_config->ca_cert_file || ctx_config->ca_cert_dir) && |
| 254 | SSL_CTX_load_verify_locations(ctx, ctx_config->ca_cert_file, ctx_config->ca_cert_dir) <= 0) { |
| 255 | ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); |
| 256 | serverLog(LL_WARNING, "Failed to configure CA certificate(s) file/directory: %s", errbuf); |
| 257 | goto error; |
| 258 | } |
| 259 | |
| 260 | if (ctx_config->ciphers && !SSL_CTX_set_cipher_list(ctx, ctx_config->ciphers)) { |