From cc5a28ea6d2a0de9bcd56f07684bdc53cdfd10af Mon Sep 17 00:00:00 2001 From: jsing <> Date: Wed, 12 Mar 2025 14:03:55 +0000 Subject: Provide SSL_OP_NO_RENEGOTIATION and SSL_OP_ALLOW_CLIENT_RENEGOTIATION. In January 2017 we added SSL_OP_NO_CLIENT_RENEGOTIATION, which results in a SSL_AD_NO_RENEGOTIATION fatal alert if a ClientHello message is seen on an active connection (client initiated renegotation). Then in May 2017 OpenSSL added SSL_OP_NO_RENEGOTIATION, which results in a SSL_AD_NO_RENEGOTIATION warning alert if a server receives a ClientHello on an active connection (client initiated renegotation), or a client receives a HelloRequest (server requested renegotation). This option also causes calls to SSL_renegotiate() and SSL_renegotiate_abbreviated() to fail. Then in 2021, OpenSSL also added SSL_OP_ALLOW_CLIENT_RENEGOTIATION, which trumps SSL_OP_NO_RENEGOTIATION but only for incoming ClientHello messages (apparently unsetting SSL_OP_NO_RENEGOTIATION is too hard). Provide SSL_OP_NO_RENEGOTIATION and SSL_OP_ALLOW_CLIENT_RENEGOTIATION, primarily to make life easier for ports. If SSL_OP_NO_CLIENT_RENEGOTIATION is set it will take precedence and render SSL_OP_ALLOW_CLIENT_RENEGOTIATION ineffective. The rest of the behaviour should match OpenSSL, with the exception of ClientHellos triggering fatal alerts instead of warnings. ok tb@ --- src/lib/libssl/d1_pkt.c | 12 ++++++++++-- src/lib/libssl/ssl.h | 6 +++++- src/lib/libssl/ssl_lib.c | 12 +++++++++++- src/lib/libssl/ssl_pkt.c | 12 ++++++++++-- 4 files changed, 36 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c index cf32ca8cd6..8ba0bb0bcf 100644 --- a/src/lib/libssl/d1_pkt.c +++ b/src/lib/libssl/d1_pkt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: d1_pkt.c,v 1.129 2024/07/20 04:04:23 jsing Exp $ */ +/* $OpenBSD: d1_pkt.c,v 1.130 2025/03/12 14:03:55 jsing Exp $ */ /* * DTLS implementation written by Nagendra Modadugu * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. @@ -592,6 +592,12 @@ dtls1_read_handshake_unexpected(SSL *s) tls_content_clear(s->s3->rcontent); s->s3->rrec.length = 0; + if ((s->options & SSL_OP_NO_RENEGOTIATION) != 0) { + ssl3_send_alert(s, SSL3_AL_WARNING, + SSL_AD_NO_RENEGOTIATION); + return 1; + } + /* * It should be impossible to hit this, but keep the safety * harness for now... @@ -644,7 +650,9 @@ dtls1_read_handshake_unexpected(SSL *s) return -1; } - if ((s->options & SSL_OP_NO_CLIENT_RENEGOTIATION) != 0) { + if ((s->options & SSL_OP_NO_CLIENT_RENEGOTIATION) != 0 || + ((s->options & SSL_OP_NO_RENEGOTIATION) != 0 && + (s->options & SSL_OP_ALLOW_CLIENT_RENEGOTIATION) == 0)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); return -1; diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h index 062c6dcbb9..a1ed22b778 100644 --- a/src/lib/libssl/ssl.h +++ b/src/lib/libssl/ssl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl.h,v 1.246 2025/03/09 15:53:36 tb Exp $ */ +/* $OpenBSD: ssl.h,v 1.247 2025/03/12 14:03:55 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -389,6 +389,10 @@ typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, #define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L /* Disallow client initiated renegotiation. */ #define SSL_OP_NO_CLIENT_RENEGOTIATION 0x00020000L +/* Disallow client and server initiated renegotiation. */ +#define SSL_OP_NO_RENEGOTIATION 0x00040000L +/* Allow client initiated renegotiation. */ +#define SSL_OP_ALLOW_CLIENT_RENEGOTIATION 0x00080000L /* If set, always create a new key when using tmp_dh parameters */ #define SSL_OP_SINGLE_DH_USE 0x00100000L /* Set on servers to choose the cipher according to the server's diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index 63d72baf8e..ce68981493 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_lib.c,v 1.330 2024/09/22 14:59:48 tb Exp $ */ +/* $OpenBSD: ssl_lib.c,v 1.331 2025/03/12 14:03:55 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1308,6 +1308,11 @@ LSSL_ALIAS(SSL_shutdown); int SSL_renegotiate(SSL *s) { + if ((s->options & SSL_OP_NO_RENEGOTIATION) != 0) { + SSLerror(s, SSL_R_NO_RENEGOTIATION); + return 0; + } + if (s->renegotiate == 0) s->renegotiate = 1; @@ -1320,6 +1325,11 @@ LSSL_ALIAS(SSL_renegotiate); int SSL_renegotiate_abbreviated(SSL *s) { + if ((s->options & SSL_OP_NO_RENEGOTIATION) != 0) { + SSLerror(s, SSL_R_NO_RENEGOTIATION); + return 0; + } + if (s->renegotiate == 0) s->renegotiate = 1; diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c index 740fe97192..7032175aac 100644 --- a/src/lib/libssl/ssl_pkt.c +++ b/src/lib/libssl/ssl_pkt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_pkt.c,v 1.68 2024/07/22 14:47:15 jsing Exp $ */ +/* $OpenBSD: ssl_pkt.c,v 1.69 2025/03/12 14:03:55 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -900,6 +900,12 @@ ssl3_read_handshake_unexpected(SSL *s) tls_buffer_free(s->s3->handshake_fragment); s->s3->handshake_fragment = NULL; + if ((s->options & SSL_OP_NO_RENEGOTIATION) != 0) { + ssl3_send_alert(s, SSL3_AL_WARNING, + SSL_AD_NO_RENEGOTIATION); + return 1; + } + /* * It should be impossible to hit this, but keep the safety * harness for now... @@ -947,7 +953,9 @@ ssl3_read_handshake_unexpected(SSL *s) return -1; } - if ((s->options & SSL_OP_NO_CLIENT_RENEGOTIATION) != 0) { + if ((s->options & SSL_OP_NO_CLIENT_RENEGOTIATION) != 0 || + ((s->options & SSL_OP_NO_RENEGOTIATION) != 0 && + (s->options & SSL_OP_ALLOW_CLIENT_RENEGOTIATION) == 0)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); return -1; -- cgit v1.2.3-55-g6feb