summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorRich Salz <rsalz@akamai.com>2021-05-06 12:56:35 -0400
committerTomas Mraz <tomas@openssl.org>2021-05-17 10:53:30 +0200
commit55373bfd419ca010a15aac18c88c94827e2f3a92 (patch)
tree803860f6eae08da5688ae7c4b68e195e52851a23 /ssl
parentd7970dd963134534340ad00fa62cb1180daf5cb0 (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.c5
-rw-r--r--ssl/ssl_lib.c27
-rw-r--r--ssl/statem/statem_srvr.c6
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)) {