summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2017-02-02 08:24:17 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2017-02-02 08:24:17 +0000
commit98c67536e24c2a04a43e20aa44a686c667b0b2b7 (patch)
tree622d3294162b015a6ee8380e57c060262540ae90 /usr.sbin
parentd70dbd1ed85d76a7cc2945bab79b5d8b3c4f9efb (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.c66
-rw-r--r--usr.sbin/relayd/relayd.conf.513
-rw-r--r--usr.sbin/relayd/relayd.h12
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" \