diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2017-02-02 08:24:17 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2017-02-02 08:24:17 +0000 |
commit | 98c67536e24c2a04a43e20aa44a686c667b0b2b7 (patch) | |
tree | 622d3294162b015a6ee8380e57c060262540ae90 /usr.sbin | |
parent | d70dbd1ed85d76a7cc2945bab79b5d8b3c4f9efb (diff) |
Disable client-initiated TLS renegotiation by default.
It is rarely needed and imposes a light DoS risk. LibreSSL's libssl
allows to turn it off with a simple SSL_OP_NO_CLIENT_RENEGOTIATION
option instead of the complicated implementation that was used before.
It now turns it off completely instead of allowing one initial
client-initiated renegotiation.
It can still be enabled with "tls client-renegotiation".
ok benno@ beck@ jsing@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/relayd/relay.c | 66 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.conf.5 | 13 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.h | 12 |
3 files changed, 14 insertions, 77 deletions
diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c index 116a01d61cb..3ed127553b9 100644 --- a/usr.sbin/relayd/relay.c +++ b/usr.sbin/relayd/relay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay.c,v 1.218 2017/01/09 14:49:21 reyk Exp $ */ +/* $OpenBSD: relay.c,v 1.219 2017/02/02 08:24:16 reyk Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org> @@ -74,7 +74,6 @@ void relay_input(struct rsession *); void relay_hash_addr(SIPHASH_CTX *, struct sockaddr_storage *, int); DH * relay_tls_get_dhparams(int); -void relay_tls_callback_info(const SSL *, int, int); DH *relay_tls_callback_dh(SSL *, int, int); SSL_CTX *relay_tls_ctx_create(struct relay *); void relay_tls_transaction(struct rsession *, @@ -1961,40 +1960,6 @@ relay_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) return (0); } -void -relay_tls_callback_info(const SSL *ssl, int where, int rc) -{ - struct ctl_relay_event *cre; - int tls_state; - - cre = (struct ctl_relay_event *)SSL_get_app_data(ssl); - - if (cre == NULL || cre->tlsreneg_state == TLSRENEG_ALLOW) - return; - - tls_state = SSL_get_state(ssl); - - /* Check renegotiations */ - if ((where & SSL_CB_ACCEPT_LOOP) && - (cre->tlsreneg_state == TLSRENEG_DENY)) { - if ((tls_state == SSL3_ST_SR_CLNT_HELLO_A) || - (tls_state == SSL23_ST_SR_CLNT_HELLO_A)) { - /* - * This is a client initiated renegotiation - * that we do not allow - */ - cre->tlsreneg_state = TLSRENEG_ABORT; - } - } else if ((where & SSL_CB_HANDSHAKE_DONE) && - (cre->tlsreneg_state == TLSRENEG_INIT)) { - /* - * This is right after the first handshake, - * disallow any further negotiations. - */ - cre->tlsreneg_state = TLSRENEG_DENY; - } -} - DH * relay_tls_get_dhparams(int keylen) { @@ -2103,6 +2068,8 @@ relay_tls_ctx_create(struct relay *rlay) SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); if (proto->tlsflags & TLSFLAG_CIPHER_SERVER_PREF) SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + if ((proto->tlsflags & TLSFLAG_CLIENT_RENEG) == 0) + SSL_CTX_set_options(ctx, SSL_OP_NO_CLIENT_RENEGOTIATION); /* Set the allowed SSL protocols */ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); @@ -2119,9 +2086,6 @@ relay_tls_ctx_create(struct relay *rlay) if ((proto->tlsflags & TLSFLAG_TLSV1_2) == 0) SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2); - /* add the SSL info callback */ - SSL_CTX_set_info_callback(ctx, relay_tls_callback_info); - if (proto->tlsecdhcurve > 0) { /* Enable ECDHE support for TLS perfect forward secrecy */ if ((ecdhkey = @@ -2200,7 +2164,6 @@ void relay_tls_transaction(struct rsession *con, struct ctl_relay_event *cre) { struct relay *rlay = con->se_relay; - struct protocol *proto = rlay->rl_proto; SSL *ssl; const SSL_METHOD *method; void (*cb)(int, short, void *); @@ -2229,19 +2192,10 @@ relay_tls_transaction(struct rsession *con, struct ctl_relay_event *cre) if (!SSL_set_fd(ssl, cre->s)) goto err; - if (cre->dir == RELAY_DIR_REQUEST) { - if ((proto->tlsflags & TLSFLAG_CLIENT_RENEG) == 0) - /* Only allow negotiation during the first handshake */ - cre->tlsreneg_state = TLSRENEG_INIT; - else - /* Allow client initiated renegotiations */ - cre->tlsreneg_state = TLSRENEG_ALLOW; + if (cre->dir == RELAY_DIR_REQUEST) SSL_set_accept_state(ssl); - } else { - /* Always allow renegotiations if we're the client */ - cre->tlsreneg_state = TLSRENEG_ALLOW; + else SSL_set_connect_state(ssl); - } SSL_set_app_data(ssl, cre); cre->ssl = ssl; @@ -2423,11 +2377,6 @@ relay_tls_readcb(int fd, short event, void *arg) goto err; } - if (cre->tlsreneg_state == TLSRENEG_ABORT) { - what |= EVBUFFER_ERROR; - goto err; - } - if (bufev->wm_read.high != 0) howmuch = MINIMUM(sizeof(rbuf), bufev->wm_read.high); @@ -2500,11 +2449,6 @@ relay_tls_writecb(int fd, short event, void *arg) goto err; } - if (cre->tlsreneg_state == TLSRENEG_ABORT) { - what |= EVBUFFER_ERROR; - goto err; - } - if (EVBUFFER_LENGTH(bufev->output)) { if (cre->buf == NULL) { cre->buflen = EVBUFFER_LENGTH(bufev->output); diff --git a/usr.sbin/relayd/relayd.conf.5 b/usr.sbin/relayd/relayd.conf.5 index 67b296fee3b..d3609cff266 100644 --- a/usr.sbin/relayd/relayd.conf.5 +++ b/usr.sbin/relayd/relayd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: relayd.conf.5,v 1.173 2016/09/03 18:28:45 jmc Exp $ +.\" $OpenBSD: relayd.conf.5,v 1.174 2017/02/02 08:24:16 reyk Exp $ .\" .\" Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org> .\" Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 3 2016 $ +.Dd $Mdocdate: February 2 2017 $ .Dt RELAYD.CONF 5 .Os .Sh NAME @@ -927,6 +927,11 @@ will be used (strong crypto cipher suites without anonymous DH). See the CIPHERS section of .Xr openssl 1 for information about SSL/TLS cipher suites and preference lists. +.It Ic client-renegotiation +Allow client-initiated renegotiation. +To mitigate a potential DoS risk, +the default is +.Ic no client-renegotiation . .It Ic ecdh Op Ic curve Ar name Set a named curve to use when generating EC keys for ECDHE-based cipher suites with Perfect Forward Secrecy (PFS). @@ -955,10 +960,6 @@ The default is Prefer the client's cipher list over the server's preferences when choosing a cipher for the connection. The default is to prefer the server's cipher list. -.It Ic no client-renegotiation -Disallow client-initiated renegotiation, -to mitigate a potential DoS risk. -The default is to allow client-initiated renegotiation. .It Ic no session tickets Disable TLS session tickets. .Xr relayd 8 diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index 6fb8186ff7c..fc24c975950 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.238 2017/01/24 10:49:14 benno Exp $ */ +/* $OpenBSD: relayd.h,v 1.239 2017/02/02 08:24:16 reyk Exp $ */ /* * Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org> @@ -176,13 +176,6 @@ enum direction { RELAY_DIR_RESPONSE = 2 }; -enum tlsreneg_state { - TLSRENEG_INIT = 0, /* first/next negotiation is allowed */ - TLSRENEG_ALLOW = 1, /* all (re-)negotiations are allowed */ - TLSRENEG_DENY = 2, /* next renegotiation must be denied */ - TLSRENEG_ABORT = 3 /* the connection should be aborted */ -}; - enum relay_state { STATE_INIT, STATE_PENDING, @@ -202,7 +195,6 @@ struct ctl_relay_event { SSL *ssl; /* libssl object */ X509 *tlscert; - enum tlsreneg_state tlsreneg_state; off_t splicelen; off_t toread; @@ -681,7 +673,7 @@ TAILQ_HEAD(relay_rules, relay_rule); #define TLSFLAG_CIPHER_SERVER_PREF 0x20 #define TLSFLAG_CLIENT_RENEG 0x40 #define TLSFLAG_DEFAULT \ - (TLSFLAG_TLSV1_2|TLSFLAG_CIPHER_SERVER_PREF|TLSFLAG_CLIENT_RENEG) + (TLSFLAG_TLSV1_2|TLSFLAG_CIPHER_SERVER_PREF) #define TLSFLAG_BITS \ "\06\01sslv3\02tlsv1.0\03tlsv1.1\04tlsv1.2" \ |