summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorjsing <jsing@openbsd.org>2020-01-22 01:02:28 +0000
committerjsing <jsing@openbsd.org>2020-01-22 01:02:28 +0000
commit828ae560041be09ecf13fc549fac0f018344e48a (patch)
tree89728aef450221ebf4b34dac0e3960726dee5219 /lib
parentscsi_delay(): sleep without lbolt (diff)
downloadwireguard-openbsd-828ae560041be09ecf13fc549fac0f018344e48a.tar.xz
wireguard-openbsd-828ae560041be09ecf13fc549fac0f018344e48a.zip
Implement close-notify and SSL_shutdown() handling for the TLSv1.3 client.
ok beck@ inoguchi@ tb@
Diffstat (limited to 'lib')
-rw-r--r--lib/libssl/tls13_internal.h7
-rw-r--r--lib/libssl/tls13_lib.c52
-rw-r--r--lib/libssl/tls13_record_layer.c26
3 files changed, 76 insertions, 9 deletions
diff --git a/lib/libssl/tls13_internal.h b/lib/libssl/tls13_internal.h
index 3ee73782ecc..7fee37f5dd2 100644
--- a/lib/libssl/tls13_internal.h
+++ b/lib/libssl/tls13_internal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_internal.h,v 1.39 2020/01/21 12:08:04 jsing Exp $ */
+/* $OpenBSD: tls13_internal.h,v 1.40 2020/01/22 01:02:28 jsing Exp $ */
/*
* Copyright (c) 2018 Bob Beck <beck@openbsd.org>
* Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
@@ -126,6 +126,7 @@ int tls13_record_layer_set_read_traffic_key(struct tls13_record_layer *rl,
struct tls13_secret *read_key);
int tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl,
struct tls13_secret *write_key);
+ssize_t tls13_record_layer_send_pending(struct tls13_record_layer *rl);
ssize_t tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs);
ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n);
@@ -181,6 +182,9 @@ struct tls13_ctx {
struct tls13_handshake_stage handshake_stage;
int handshake_completed;
+ int close_notify_sent;
+ int close_notify_recv;
+
const EVP_AEAD *aead;
const EVP_MD *hash;
@@ -215,6 +219,7 @@ ssize_t tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg);
int tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len,
int peek);
int tls13_legacy_write_bytes(SSL *ssl, int type, const void *buf, int len);
+int tls13_legacy_shutdown(SSL *ssl);
/*
* Message Types - RFC 8446, Section B.3.
diff --git a/lib/libssl/tls13_lib.c b/lib/libssl/tls13_lib.c
index 451e798cb8e..bb749a9b68c 100644
--- a/lib/libssl/tls13_lib.c
+++ b/lib/libssl/tls13_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_lib.c,v 1.16 2020/01/21 05:19:02 jsing Exp $ */
+/* $OpenBSD: tls13_lib.c,v 1.17 2020/01/22 01:02:28 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2019 Bob Beck <beck@openbsd.org>
@@ -69,6 +69,7 @@ tls13_alert_received_cb(uint8_t alert_desc, void *arg)
SSL *s = ctx->ssl;
if (alert_desc == SSL_AD_CLOSE_NOTIFY) {
+ ctx->close_notify_recv = 1;
ctx->ssl->internal->shutdown |= SSL_RECEIVED_SHUTDOWN;
S3I(ctx->ssl)->warn_alert = alert_desc;
return;
@@ -482,3 +483,52 @@ tls13_legacy_write_bytes(SSL *ssl, int type, const void *vbuf, int len)
n -= ret;
}
}
+
+int
+tls13_legacy_shutdown(SSL *ssl)
+{
+ struct tls13_ctx *ctx = ssl->internal->tls13;
+ uint8_t buf[512]; /* XXX */
+ ssize_t ret;
+
+ /*
+ * We need to return 0 when we have sent a close-notify but have not
+ * yet received one. We return 1 only once we have sent and received
+ * close-notify alerts. All other cases return -1 and set internal
+ * state appropriately.
+ */
+ if (ctx == NULL || ssl->internal->quiet_shutdown) {
+ ssl->internal->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
+ return 1;
+ }
+
+ /* Send close notify. */
+ if (!ctx->close_notify_sent) {
+ ctx->close_notify_sent = 1;
+ if ((ret = tls13_send_alert(ctx->rl, SSL_AD_CLOSE_NOTIFY)) < 0)
+ return tls13_legacy_return_code(ssl, ret);
+ }
+
+ /* Ensure close notify has been sent. */
+ if ((ret = tls13_record_layer_send_pending(ctx->rl)) != TLS13_IO_SUCCESS)
+ return tls13_legacy_return_code(ssl, ret);
+
+ /* Receive close notify. */
+ if (!ctx->close_notify_recv) {
+ /*
+ * If there is still application data pending then we have no
+ * option but to discard it here. The application should have
+ * continued to call SSL_read() instead of SSL_shutdown().
+ */
+ /* XXX - tls13_drain_application_data()? */
+ if ((ret = tls13_read_application_data(ctx->rl, buf, sizeof(buf))) > 0)
+ ret = TLS13_IO_WANT_POLLIN;
+ if (ret != TLS13_IO_EOF)
+ return tls13_legacy_return_code(ssl, ret);
+ }
+
+ if (ctx->close_notify_recv)
+ return 1;
+
+ return 0;
+}
diff --git a/lib/libssl/tls13_record_layer.c b/lib/libssl/tls13_record_layer.c
index a6b00a83b3b..dff5cd2bbe9 100644
--- a/lib/libssl/tls13_record_layer.c
+++ b/lib/libssl/tls13_record_layer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_record_layer.c,v 1.18 2020/01/21 12:08:04 jsing Exp $ */
+/* $OpenBSD: tls13_record_layer.c,v 1.19 2020/01/22 01:02:28 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -51,6 +51,8 @@ struct tls13_record_layer {
/* Pending alert messages. */
uint8_t *alert_data;
size_t alert_len;
+ uint8_t alert_level;
+ uint8_t alert_desc;
/* Pending post-handshake handshake messages (RFC 8446, section 4.6). */
CBS phh_cbs;
@@ -281,12 +283,19 @@ tls13_record_layer_send_alert(struct tls13_record_layer *rl)
rl->alert_data = NULL;
rl->alert_len = 0;
- /* XXX - only close write channel when sending close notify. */
- rl->read_closed = 1;
- rl->write_closed = 1;
+ if (rl->alert_desc == SSL_AD_CLOSE_NOTIFY) {
+ rl->write_closed = 1;
+ ret = TLS13_IO_SUCCESS;
+ } else if (rl->alert_desc == SSL_AD_USER_CANCELLED) {
+ /* Ignored at the record layer. */
+ ret = TLS13_IO_SUCCESS;
+ } else {
+ rl->read_closed = 1;
+ rl->write_closed = 1;
+ ret = TLS13_IO_SUCCESS; /* XXX - ALERT? */
+ }
- /* XXX - we may want a TLS13_IO_ALERT (or handle as errors). */
- return TLS13_IO_FAILURE;
+ return ret;
}
static ssize_t
@@ -314,7 +323,7 @@ tls13_record_layer_send_phh(struct tls13_record_layer *rl)
return TLS13_IO_SUCCESS;
}
-static ssize_t
+ssize_t
tls13_record_layer_send_pending(struct tls13_record_layer *rl)
{
/*
@@ -354,6 +363,9 @@ tls13_record_layer_alert(struct tls13_record_layer *rl,
if (!CBB_finish(&cbb, &rl->alert_data, &rl->alert_len))
goto err;
+ rl->alert_level = alert_level;
+ rl->alert_desc = alert_desc;
+
return tls13_record_layer_send_pending(rl);
err: