From: Rich Salz Date: Thu, 6 May 2021 16:56:35 +0000 (-0400) Subject: Add SSL_OP_ALLOW_CLIENT_RENEGOTIATION X-Git-Tag: openssl-3.0.0-alpha17~83 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=55373bfd419ca010a15aac18c88c94827e2f3a92 Add SSL_OP_ALLOW_CLIENT_RENEGOTIATION Add -client_renegotiation flag support. The -client_renegotiation flag is equivalent to SSL_OP_ALLOW_CLIENT_RENEGOTIATION. Add support to the app, the config code, and the documentation. Add SSL_OP_ALLOW_CLIENT_RENEGOTIATION to the SSL tests. We don't need to always enable it, but there are so many tests so this is the easiest thing to do. Add a test where client tries to renegotiate and it fails as expected. Add a test where server tries to renegotiate and it succeeds. The second test is supported by a new flag, -immediate_renegotiation, which is ignored on the client. Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/15184) --- diff --git a/CHANGES.md b/CHANGES.md index eb199fac70..12f4c820d9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -29,6 +29,12 @@ OpenSSL 3.0 * Rich Salz * + * Client-initiated renegotiation is disabled by default. To allow it, use + the -client_renegotiation option, the SSL_OP_ALLOW_CLIENT_RENEGOTIATION + flag, or the "ClientRenegotiation" config parameter as appropriate. + + * Rich Salz * + * Add "abspath" and "includedir" pragma's to config files, to prevent, or modify relative pathname inclusion. diff --git a/apps/include/opt.h b/apps/include/opt.h index c6ec09f882..5d85877301 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -155,13 +155,14 @@ OPT_S__FIRST=3000, \ OPT_S_NOSSL3, OPT_S_NOTLS1, OPT_S_NOTLS1_1, OPT_S_NOTLS1_2, \ OPT_S_NOTLS1_3, OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \ - OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_LEGACYCONN, \ + OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_CLIENTRENEG, \ + OPT_S_LEGACYCONN, \ OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_ALLOW_NO_DHE_KEX, \ OPT_S_PRIORITIZE_CHACHA, \ OPT_S_STRICT, OPT_S_SIGALGS, OPT_S_CLIENTSIGALGS, OPT_S_GROUPS, \ OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, OPT_S_CIPHERSUITES, \ OPT_S_RECORD_PADDING, OPT_S_DEBUGBROKE, OPT_S_COMP, \ - OPT_S_MINPROTO, OPT_S_MAXPROTO, \ + OPT_S_MINPROTO, OPT_S_MAXPROTO, OPT_S_IMMEDIATE_RENEG, \ OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S__LAST # define OPT_S_OPTIONS \ @@ -179,6 +180,8 @@ {"serverpref", OPT_S_SERVERPREF, '-', "Use server's cipher preferences"}, \ {"legacy_renegotiation", OPT_S_LEGACYRENEG, '-', \ "Enable use of legacy renegotiation (dangerous)"}, \ + {"client_renegotiation", OPT_S_CLIENTRENEG, '-', \ + "Allow client-initiated renegotiation" }, \ {"no_renegotiation", OPT_S_NO_RENEGOTIATION, '-', \ "Disable all renegotiation."}, \ {"legacy_server_connect", OPT_S_LEGACYCONN, '-', \ @@ -208,6 +211,8 @@ {"ciphersuites", OPT_S_CIPHERSUITES, 's', "Specify TLSv1.3 ciphersuites to be used"}, \ {"min_protocol", OPT_S_MINPROTO, 's', "Specify the minimum protocol version to be used"}, \ {"max_protocol", OPT_S_MAXPROTO, 's', "Specify the maximum protocol version to be used"}, \ + {"immediate_renegotiation", OPT_S_IMMEDIATE_RENEG, '-', \ + "Immediately attempt renegotiation"}, \ {"record_padding", OPT_S_RECORD_PADDING, 's', \ "Block size to pad TLS 1.3 records to."}, \ {"debug_broken_protocol", OPT_S_DEBUGBROKE, '-', \ @@ -228,6 +233,7 @@ case OPT_S_NOTICKET: \ case OPT_S_SERVERPREF: \ case OPT_S_LEGACYRENEG: \ + case OPT_S_CLIENTRENEG: \ case OPT_S_LEGACYCONN: \ case OPT_S_ONRESUMP: \ case OPT_S_NOLEGACYCONN: \ diff --git a/apps/lib/s_cb.c b/apps/lib/s_cb.c index bdd5051ee6..e3d9ec1916 100644 --- a/apps/lib/s_cb.c +++ b/apps/lib/s_cb.c @@ -1233,12 +1233,10 @@ int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, for (i = 0; i < sk_OPENSSL_STRING_num(str); i += 2) { const char *flag = sk_OPENSSL_STRING_value(str, i); const char *arg = sk_OPENSSL_STRING_value(str, i + 1); + if (SSL_CONF_cmd(cctx, flag, arg) <= 0) { - if (arg != NULL) - BIO_printf(bio_err, "Error with command: \"%s %s\"\n", - flag, arg); - else - BIO_printf(bio_err, "Error with command: \"%s\"\n", flag); + BIO_printf(bio_err, "Call to SSL_CONF_cmd(%s, %s) failed\n", + flag, arg == NULL ? "" : arg); ERR_print_errors(bio_err); return 0; } diff --git a/apps/s_client.c b/apps/s_client.c index 1aa7a3b7de..1754d3e1a4 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -1047,6 +1047,9 @@ int s_client_main(int argc, char **argv) case OPT_BRIEF: c_brief = verify_args.quiet = c_quiet = 1; break; + case OPT_S_IMMEDIATE_RENEG: + /* Option ignored on client. */ + break; case OPT_S_CASES: if (ssl_args == NULL) ssl_args = sk_OPENSSL_STRING_new_null(); @@ -2673,7 +2676,6 @@ int s_client_main(int argc, char **argv) tty_on = 1; if (in_init) { in_init = 0; - if (c_brief) { BIO_puts(bio_err, "CONNECTION ESTABLISHED\n"); print_ssl_summary(con); diff --git a/apps/s_server.c b/apps/s_server.c index 5d9e8cd568..51b5c9d381 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -78,6 +78,7 @@ static int accept_socket = -1; static int s_nbio = 0; static int s_nbio_test = 0; static int s_crlf = 0; +static int immediate_reneg = 0; static SSL_CTX *ctx = NULL; static SSL_CTX *ctx2 = NULL; static int www = 0; @@ -1258,6 +1259,9 @@ int s_server_main(int argc, char *argv[]) if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format)) goto opthelp; break; + case OPT_S_IMMEDIATE_RENEG: + immediate_reneg = 1; + break; case OPT_S_CASES: case OPT_S_NUM_TICKETS: case OPT_ANTI_REPLAY: @@ -2784,6 +2788,8 @@ static int init_ssl_connection(SSL *con) } else { do { i = SSL_accept(con); + if (immediate_reneg) + SSL_renegotiate(con); if (i <= 0) retry = is_retryable(con, i); diff --git a/doc/man3/SSL_CONF_cmd.pod b/doc/man3/SSL_CONF_cmd.pod index 8da8f7f060..bbd622a687 100644 --- a/doc/man3/SSL_CONF_cmd.pod +++ b/doc/man3/SSL_CONF_cmd.pod @@ -58,9 +58,15 @@ Use server and not client preference order when determining which cipher suite, signature algorithm or elliptic curve to use for an incoming connection. Equivalent to B. Only used by servers. +=item B<-client_renegotiation> + +Allows servers to accept client-initiated renegotiation. Equivalent to +setting B. +Only used by servers. + =item B<-legacyrenegotiation> -permits the use of unsafe legacy renegotiation. Equivalent to setting +Permits the use of unsafe legacy renegotiation. Equivalent to setting B. =item B<-no_renegotiation> @@ -70,13 +76,19 @@ B. =item B<-no_resumption_on_reneg> -set SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION flag. Only used by servers. +Sets B. Only used by servers. =item B<-legacy_server_connect>, B<-no_legacy_server_connect> -permits or prohibits the use of unsafe legacy renegotiation for OpenSSL +Permits or prohibits the use of unsafe legacy renegotiation for OpenSSL clients only. Equivalent to setting or clearing B. +=item B<-immediate_renegotiation> + +Try to do a renegotiation immediately after the handshake. +This is for debugging and has no option equivalent. +Ignored by the B command. + =item B<-prioritize_chacha> Prioritize ChaCha ciphers when the client has a ChaCha20 cipher at the top of @@ -91,7 +103,7 @@ that there will be no forward secrecy for the resumed session. =item B<-strict> -enables strict mode protocol handling. Equivalent to setting +Enables strict mode protocol handling. Equivalent to setting B. =item B<-sigalgs> I diff --git a/doc/perlvars.pm b/doc/perlvars.pm index 91dd5d8284..ab52a086ee 100644 --- a/doc/perlvars.pm +++ b/doc/perlvars.pm @@ -179,9 +179,11 @@ $OpenSSL::safe::opt_s_synopsis = "" . "[B<-comp>]\n" . "[B<-no_ticket>]\n" . "[B<-serverpref>]\n" +. "[B<-client_renegotiation>]\n" . "[B<-legacy_renegotiation>]\n" . "[B<-no_renegotiation>]\n" . "[B<-no_resumption_on_reneg>]\n" +. "[B<-immediate_renegotiation>]\n" . "[B<-legacy_server_connect>]\n" . "[B<-no_legacy_server_connect>]\n" . "[B<-allow_no_dhe_kex>]\n" @@ -201,6 +203,7 @@ $OpenSSL::safe::opt_s_synopsis = "" . "[B<-no_middlebox>]"; $OpenSSL::safe::opt_s_item = "" . "=item B<-bugs>, B<-comp>, B<-no_comp>, B<-no_ticket>, B<-serverpref>,\n" +. "B<-client_renegotiation>, B<_immediate_renegotiation>\n" . "B<-legacy_renegotiation>, B<-no_renegotiation>, B<-no_resumption_on_reneg>,\n" . "B<-legacy_server_connect>, B<-no_legacy_server_connect>,\n" . "B<-allow_no_dhe_kex>, B<-prioritize_chacha>, B<-strict>, B<-sigalgs>\n" diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index 8d1663c0cc..b15c847176 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -383,6 +383,8 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE), SSL_FLAG_TBL("UnsafeLegacyRenegotiation", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), + SSL_FLAG_TBL("ClientRenegotiation", + SSL_OP_ALLOW_CLIENT_RENEGOTIATION), SSL_FLAG_TBL_INV("EncryptThenMac", SSL_OP_NO_ENCRYPT_THEN_MAC), SSL_FLAG_TBL("NoRenegotiation", SSL_OP_NO_RENEGOTIATION), SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX), @@ -688,6 +690,7 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { SSL_CONF_CMD_SWITCH("no_ticket", 0), SSL_CONF_CMD_SWITCH("serverpref", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("legacy_renegotiation", 0), + SSL_CONF_CMD_SWITCH("client_renegotiation", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("legacy_server_connect", SSL_CONF_FLAG_CLIENT), SSL_CONF_CMD_SWITCH("no_renegotiation", 0), SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER), @@ -766,6 +769,8 @@ static const ssl_switch_tbl ssl_cmd_switches[] = { {SSL_OP_CIPHER_SERVER_PREFERENCE, 0}, /* serverpref */ /* legacy_renegotiation */ {SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, 0}, + /* Allow client renegotiation */ + {SSL_OP_ALLOW_CLIENT_RENEGOTIATION, 0}, /* legacy_server_connect */ {SSL_OP_LEGACY_SERVER_CONNECT, 0}, /* no_renegotiation */ diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 047fa1a07d..ff13442e3b 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2277,39 +2277,42 @@ int SSL_get_key_update_type(const SSL *s) return s->key_update; } -int SSL_renegotiate(SSL *s) +/* + * Can we accept a renegotiation request? If yes, set the flag and + * return 1 if yes. If not, raise error and return 0. + */ +static int can_renegotiate(const SSL *s) { if (SSL_IS_TLS13(s)) { ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); return 0; } - if ((s->options & SSL_OP_NO_RENEGOTIATION)) { + if ((s->options & SSL_OP_NO_RENEGOTIATION) != 0) { ERR_raise(ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION); return 0; } + return 1; +} + +int SSL_renegotiate(SSL *s) +{ + if (!can_renegotiate(s)) + return 0; + s->renegotiate = 1; s->new_session = 1; - return s->method->ssl_renegotiate(s); } int SSL_renegotiate_abbreviated(SSL *s) { - if (SSL_IS_TLS13(s)) { - ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); + if (!can_renegotiate(s)) return 0; - } - - if ((s->options & SSL_OP_NO_RENEGOTIATION)) { - ERR_raise(ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION); - return 0; - } s->renegotiate = 1; s->new_session = 0; - return s->method->ssl_renegotiate(s); } diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 768e1110e6..386bd983fc 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -1368,6 +1368,10 @@ static void ssl_check_for_safari(SSL *s, const CLIENTHELLO_MSG *hello) ext_len); } +#define RENEG_OPTIONS_OK(options) \ + ((options & SSL_OP_NO_RENEGOTIATION) == 0 \ + && (options & SSL_OP_ALLOW_CLIENT_RENEGOTIATION) != 0) + MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) { /* |cookie| will only be initialized for DTLS. */ @@ -1381,7 +1385,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - if ((s->options & SSL_OP_NO_RENEGOTIATION) != 0 + if (!RENEG_OPTIONS_OK(s->options) || (!s->s3.send_connection_binding && (s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) == 0)) { diff --git a/test/helpers/ssltestlib.c b/test/helpers/ssltestlib.c index 693084e739..daa0416be6 100644 --- a/test/helpers/ssltestlib.c +++ b/test/helpers/ssltestlib.c @@ -695,7 +695,9 @@ int create_ssl_ctx_pair(OSSL_LIB_CTX *libctx, const SSL_METHOD *sm, if (sctx != NULL) { if (*sctx != NULL) serverctx = *sctx; - else if (!TEST_ptr(serverctx = SSL_CTX_new_ex(libctx, NULL, sm))) + else if (!TEST_ptr(serverctx = SSL_CTX_new_ex(libctx, NULL, sm)) + || !TEST_true(SSL_CTX_set_options(serverctx, + SSL_OP_ALLOW_CLIENT_RENEGOTIATION))) goto err; } diff --git a/test/recipes/70-test_renegotiation.t b/test/recipes/70-test_renegotiation.t index 256964266c..0dc0594775 100644 --- a/test/recipes/70-test_renegotiation.t +++ b/test/recipes/70-test_renegotiation.t @@ -26,6 +26,8 @@ plan skip_all => "$test_name needs the sock feature enabled" plan skip_all => "$test_name needs TLS <= 1.2 enabled" if alldisabled(("ssl3", "tls1", "tls1_1", "tls1_2")); +plan tests => 6; + $ENV{OPENSSL_ia32cap} = '~0x200000200000000'; my $proxy = TLSProxy::Proxy->new( undef, @@ -36,15 +38,16 @@ my $proxy = TLSProxy::Proxy->new( #Test 1: A basic renegotiation test $proxy->clientflags("-no_tls1_3"); +$proxy->serverflags("-client_renegotiation"); $proxy->reneg(1); $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 4; ok(TLSProxy::Message->success(), "Basic renegotiation"); #Test 2: Client does not send the Reneg SCSV. Reneg should fail $proxy->clear(); $proxy->filter(\&reneg_filter); $proxy->clientflags("-no_tls1_3"); +$proxy->serverflags("-client_renegotiation"); $proxy->reneg(1); $proxy->start(); ok(TLSProxy::Message->fail(), "No client SCSV"); @@ -58,7 +61,7 @@ SKIP: { $proxy->filter(undef); $proxy->ciphers("DEFAULT:\@SECLEVEL=0"); $proxy->clientflags("-no_tls1_3 -cipher AES128-SHA:\@SECLEVEL=0"); - $proxy->serverflags("-no_tls1_3 -no_tls1_2"); + $proxy->serverflags("-no_tls1_3 -no_tls1_2 -client_renegotiation"); $proxy->reneg(1); $proxy->start(); my $chversion; @@ -87,11 +90,39 @@ SKIP: { $proxy->clear(); $proxy->filter(\&sigalgs_filter); $proxy->clientflags("-tls1_2"); + $proxy->serverflags("-client_renegotiation"); $proxy->reneg(1); $proxy->start(); ok(TLSProxy::Message->fail(), "client_sig_algs instead of sig_algs"); } +SKIP: { + skip "TLSv1.2 and TLSv1.1 disabled", 1 + if disabled("tls1_2") && disabled("tls1_1"); + #Test 5: Client fails to do renegotiation + $proxy->clear(); + $proxy->filter(undef); + $proxy->serverflags("-no_tls1_3"); + $proxy->clientflags("-no_tls1_3"); + $proxy->reneg(1); + $proxy->start(); + ok(TLSProxy::Message->fail(), + "Check client renegotiation failed"); +} + +SKIP: { + skip "TLSv1.2 and TLSv1.1 disabled", 1 + if disabled("tls1_2") && disabled("tls1_1"); + #Test 6: Server can do renegotiation + $proxy->clear(); + $proxy->filter(undef); + $proxy->serverflags("-no_tls1_3 -immediate_renegotiation"); + $proxy->clientflags("-no_tls1_3"); + $proxy->start(); + ok(TLSProxy::Message->success(), + "Check server renegotiation succeeded"); +} + sub reneg_filter { my $proxy = shift; diff --git a/test/recipes/70-test_sslmessages.t b/test/recipes/70-test_sslmessages.t index 3f57af62d5..befc4c7e9e 100644 --- a/test/recipes/70-test_sslmessages.t +++ b/test/recipes/70-test_sslmessages.t @@ -239,6 +239,7 @@ checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE, #Test 7: A handshake with a renegotiation $proxy->clear(); $proxy->clientflags("-no_tls1_3"); +$proxy->serverflags("-client_renegotiation"); $proxy->reneg(1); $proxy->start(); checkhandshake($proxy, checkhandshake::RENEG_HANDSHAKE, diff --git a/test/ssl_test.c b/test/ssl_test.c index 9ff766a268..4c2553ce27 100644 --- a/test/ssl_test.c +++ b/test/ssl_test.c @@ -409,12 +409,16 @@ static int test_handshake(int idx) #ifndef OPENSSL_NO_DTLS if (test_ctx->method == SSL_TEST_METHOD_DTLS) { server_ctx = SSL_CTX_new_ex(libctx, NULL, DTLS_server_method()); - if (!TEST_true(SSL_CTX_set_max_proto_version(server_ctx, 0))) + if (!TEST_true(SSL_CTX_set_options(server_ctx, + SSL_OP_ALLOW_CLIENT_RENEGOTIATION)) + || !TEST_true(SSL_CTX_set_max_proto_version(server_ctx, 0))) goto err; if (test_ctx->extra.server.servername_callback != SSL_TEST_SERVERNAME_CB_NONE) { if (!TEST_ptr(server2_ctx = - SSL_CTX_new_ex(libctx, NULL, DTLS_server_method()))) + SSL_CTX_new_ex(libctx, NULL, DTLS_server_method())) + || !TEST_true(SSL_CTX_set_options(server2_ctx, + SSL_OP_ALLOW_CLIENT_RENEGOTIATION))) goto err; } client_ctx = SSL_CTX_new_ex(libctx, NULL, DTLS_client_method()); @@ -423,7 +427,9 @@ static int test_handshake(int idx) if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) { resume_server_ctx = SSL_CTX_new_ex(libctx, NULL, DTLS_server_method()); - if (!TEST_true(SSL_CTX_set_max_proto_version(resume_server_ctx, 0))) + if (!TEST_true(SSL_CTX_set_max_proto_version(resume_server_ctx, 0)) + || !TEST_true(SSL_CTX_set_options(resume_server_ctx, + SSL_OP_ALLOW_CLIENT_RENEGOTIATION))) goto err; resume_client_ctx = SSL_CTX_new_ex(libctx, NULL, DTLS_client_method()); @@ -446,13 +452,17 @@ static int test_handshake(int idx) #endif server_ctx = SSL_CTX_new_ex(libctx, NULL, TLS_server_method()); - if (!TEST_true(SSL_CTX_set_max_proto_version(server_ctx, maxversion))) + if (!TEST_true(SSL_CTX_set_max_proto_version(server_ctx, maxversion)) + || !TEST_true(SSL_CTX_set_options(server_ctx, + SSL_OP_ALLOW_CLIENT_RENEGOTIATION))) goto err; /* SNI on resumption isn't supported/tested yet. */ if (test_ctx->extra.server.servername_callback != SSL_TEST_SERVERNAME_CB_NONE) { if (!TEST_ptr(server2_ctx = - SSL_CTX_new_ex(libctx, NULL, TLS_server_method()))) + SSL_CTX_new_ex(libctx, NULL, TLS_server_method())) + || !TEST_true(SSL_CTX_set_options(server2_ctx, + SSL_OP_ALLOW_CLIENT_RENEGOTIATION))) goto err; if (!TEST_true(SSL_CTX_set_max_proto_version(server2_ctx, maxversion))) @@ -466,7 +476,9 @@ static int test_handshake(int idx) resume_server_ctx = SSL_CTX_new_ex(libctx, NULL, TLS_server_method()); if (!TEST_true(SSL_CTX_set_max_proto_version(resume_server_ctx, - maxversion))) + maxversion)) + || !TEST_true(SSL_CTX_set_options(resume_server_ctx, + SSL_OP_ALLOW_CLIENT_RENEGOTIATION))) goto err; resume_client_ctx = SSL_CTX_new_ex(libctx, NULL, TLS_client_method());