3939#include < openssl/ssl.h>
4040#include < openssl/err.h>
4141#include < openssl/rand.h>
42+
43+ #define REDIS_TLS_PROTO_TLSv1 (1 <<0 )
44+ #define REDIS_TLS_PROTO_TLSv1_1 (1 <<1 )
45+ #define REDIS_TLS_PROTO_TLSv1_2 (1 <<2 )
46+ #define REDIS_TLS_PROTO_TLSv1_3 (1 <<3 )
47+
48+ /* Use safe defaults */
49+ #ifdef TLS1_3_VERSION
50+ #define REDIS_TLS_PROTO_DEFAULT (REDIS_TLS_PROTO_TLSv1_2|REDIS_TLS_PROTO_TLSv1_3)
51+ #else
52+ #define REDIS_TLS_PROTO_DEFAULT (REDIS_TLS_PROTO_TLSv1_2)
53+ #endif
54+
4255#endif
4356
4457#include < stdexcept>
@@ -296,6 +309,8 @@ static void config_init_defaults(struct benchmark_config *cfg)
296309 cfg->hdr_prefix = " " ;
297310 if (!cfg->print_percentiles .is_defined ())
298311 cfg->print_percentiles = config_quantiles (" 50,99,99.9" );
312+ if (!cfg->tls_protocols )
313+ cfg->tls_protocols = REDIS_TLS_PROTO_DEFAULT;
299314}
300315
301316static int generate_random_seed ()
@@ -404,6 +419,7 @@ static int config_parse_args(int argc, char *argv[], struct benchmark_config *cf
404419 o_tls_cacert,
405420 o_tls_skip_verify,
406421 o_tls_sni,
422+ o_tls_protocols,
407423 o_hdr_file_prefix,
408424 o_help
409425 };
@@ -423,6 +439,7 @@ static int config_parse_args(int argc, char *argv[], struct benchmark_config *cf
423439 { " cacert" , 1 , 0 , o_tls_cacert },
424440 { " tls-skip-verify" , 0 , 0 , o_tls_skip_verify },
425441 { " sni" , 1 , 0 , o_tls_sni },
442+ { " tls-protocols" , 1 , 0 , o_tls_protocols },
426443#endif
427444 { " out-file" , 1 , 0 , ' o' },
428445 { " hdr-file-prefix" , 1 , 0 , o_hdr_file_prefix },
@@ -863,6 +880,34 @@ static int config_parse_args(int argc, char *argv[], struct benchmark_config *cf
863880 case o_tls_sni:
864881 cfg->tls_sni = optarg;
865882 break ;
883+ case o_tls_protocols:
884+ {
885+ const char tls_delimiter = ' ,' ;
886+ char * tls_token = strtok (optarg, &tls_delimiter);
887+ while (tls_token != nullptr ) {
888+ if (!strcasecmp (tls_token, " tlsv1" ))
889+ cfg->tls_protocols |= REDIS_TLS_PROTO_TLSv1;
890+ else if (!strcasecmp (tls_token, " tlsv1.1" ))
891+ cfg->tls_protocols |= REDIS_TLS_PROTO_TLSv1_1;
892+ else if (!strcasecmp (tls_token, " tlsv1.2" ))
893+ cfg->tls_protocols |= REDIS_TLS_PROTO_TLSv1_2;
894+ else if (!strcasecmp (tls_token, " tlsv1.3" )) {
895+ #ifdef TLS1_3_VERSION
896+ cfg->tls_protocols |= REDIS_TLS_PROTO_TLSv1_3;
897+ #else
898+ fprintf (stderr, " TLSv1.3 is specified in tls-protocols but not supported by OpenSSL." );
899+ return -1 ;
900+ #endif
901+ } else {
902+ fprintf (stderr, " Invalid tls-protocols specified. "
903+ " Use a combination of 'TLSv1', 'TLSv1.1', 'TLSv1.2' and 'TLSv1.3'." );
904+ return -1 ;
905+ break ;
906+ }
907+ tls_token = strtok (nullptr , &tls_delimiter);
908+ }
909+ break ;
910+ }
866911#endif
867912 default :
868913 return -1 ;
@@ -903,6 +948,7 @@ void usage() {
903948 " --key=FILE Use specified private key for TLS\n "
904949 " --cacert=FILE Use specified CA certs bundle for TLS\n "
905950 " --tls-skip-verify Skip verification of server certificate\n "
951+ " --tls-protocols Specify the tls protocol version to use, comma delemited. Use a combination of 'TLSv1', 'TLSv1.1', 'TLSv1.2' and 'TLSv1.3'"
906952 " --sni=STRING Add an SNI header\n "
907953#endif
908954 " -x, --run-count=NUMBER Number of full-test iterations to perform\n "
@@ -1311,6 +1357,15 @@ int main(int argc, char *argv[])
13111357 cfg.openssl_ctx = SSL_CTX_new (SSLv23_client_method ());
13121358 SSL_CTX_set_options (cfg.openssl_ctx , SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
13131359
1360+ if (!(cfg.tls_protocols & REDIS_TLS_PROTO_TLSv1))
1361+ SSL_CTX_set_options (cfg.openssl_ctx , SSL_OP_NO_TLSv1);
1362+ if (!(cfg.tls_protocols & REDIS_TLS_PROTO_TLSv1_1))
1363+ SSL_CTX_set_options (cfg.openssl_ctx , SSL_OP_NO_TLSv1_1);
1364+ if (!(cfg.tls_protocols & REDIS_TLS_PROTO_TLSv1_2))
1365+ SSL_CTX_set_options (cfg.openssl_ctx , SSL_OP_NO_TLSv1_2);
1366+ if (!(cfg.tls_protocols & REDIS_TLS_PROTO_TLSv1_3))
1367+ SSL_CTX_set_options (cfg.openssl_ctx , SSL_OP_NO_TLSv1_3);
1368+
13141369 if (cfg.tls_cert ) {
13151370 if (!SSL_CTX_use_certificate_chain_file (cfg.openssl_ctx , cfg.tls_cert )) {
13161371 ERR_print_errors_fp (stderr);
0 commit comments