diff options
author | Rich Salz <rsalz@akamai.com> | 2021-05-06 12:56:35 -0400 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-05-17 10:53:30 +0200 |
commit | 55373bfd419ca010a15aac18c88c94827e2f3a92 (patch) | |
tree | 803860f6eae08da5688ae7c4b68e195e52851a23 /ssl | |
parent | d7970dd963134534340ad00fa62cb1180daf5cb0 (diff) |
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 <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15184)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/ssl_conf.c | 5 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 27 | ||||
-rw-r--r-- | ssl/statem/statem_srvr.c | 6 |
3 files changed, 25 insertions, 13 deletions
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)) { |