summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2020-05-09 15:47:12 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2020-05-09 15:47:12 +0000
commit1255f4593d55f6c28cc5a865759d9a6fc96e238f (patch)
tree2a7cbbb99c1b1df72b76d9580ed71d2051c24f24 /lib
parentaf321e3aadad9ca0c26057fa97c77eaeaa3b6ac9 (diff)
Send dummy ChangeCipherSpec messages from the TLSv1.3 client.
When operating in middlebox compatibility mode, the TLSv1.3 client needs to send a dummy ChangeCipherSpec message immediately before its second flight of handshake messages (when early data is not offered). ok tb@
Diffstat (limited to 'lib')
-rw-r--r--lib/libssl/tls13_client.c6
-rw-r--r--lib/libssl/tls13_handshake.c8
-rw-r--r--lib/libssl/tls13_internal.h4
-rw-r--r--lib/libssl/tls13_record_layer.c33
4 files changed, 45 insertions, 6 deletions
diff --git a/lib/libssl/tls13_client.c b/lib/libssl/tls13_client.c
index d5ac6ba5e07..27b2d712ae9 100644
--- a/lib/libssl/tls13_client.c
+++ b/lib/libssl/tls13_client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_client.c,v 1.56 2020/05/09 15:30:21 jsing Exp $ */
+/* $OpenBSD: tls13_client.c,v 1.57 2020/05/09 15:47:11 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -150,6 +150,9 @@ tls13_client_hello_sent(struct tls13_ctx *ctx)
tls1_transcript_freeze(ctx->ssl);
+ if (ctx->middlebox_compat)
+ ctx->send_dummy_ccs = 1;
+
return 1;
}
@@ -544,6 +547,7 @@ tls13_server_certificate_request_recv(struct tls13_ctx *ctx, CBS *cbs)
err:
if (ctx->alert == 0)
ctx->alert = TLS1_AD_DECODE_ERROR;
+
return 0;
}
diff --git a/lib/libssl/tls13_handshake.c b/lib/libssl/tls13_handshake.c
index d739dc99e58..05446380ddb 100644
--- a/lib/libssl/tls13_handshake.c
+++ b/lib/libssl/tls13_handshake.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_handshake.c,v 1.56 2020/05/09 08:39:44 jsing Exp $ */
+/* $OpenBSD: tls13_handshake.c,v 1.57 2020/05/09 15:47:11 jsing Exp $ */
/*
* Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2019 Joel Sing <jsing@openbsd.org>
@@ -332,6 +332,12 @@ tls13_handshake_send_action(struct tls13_ctx *ctx,
ssize_t ret;
CBB cbb;
+ if (ctx->send_dummy_ccs) {
+ if ((ret = tls13_send_dummy_ccs(ctx->rl)) != TLS13_IO_SUCCESS)
+ return ret;
+ ctx->send_dummy_ccs = 0;
+ }
+
/* If we have no handshake message, we need to build one. */
if (ctx->hs_msg == NULL) {
if ((ctx->hs_msg = tls13_handshake_msg_new()) == NULL)
diff --git a/lib/libssl/tls13_internal.h b/lib/libssl/tls13_internal.h
index f15d11551a8..438423aaff5 100644
--- a/lib/libssl/tls13_internal.h
+++ b/lib/libssl/tls13_internal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_internal.h,v 1.69 2020/05/09 15:30:21 jsing Exp $ */
+/* $OpenBSD: tls13_internal.h,v 1.70 2020/05/09 15:47:11 jsing Exp $ */
/*
* Copyright (c) 2018 Bob Beck <beck@openbsd.org>
* Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
@@ -174,6 +174,7 @@ ssize_t tls13_write_application_data(struct tls13_record_layer *rl, const uint8_
size_t n);
ssize_t tls13_send_alert(struct tls13_record_layer *rl, uint8_t alert_desc);
+ssize_t tls13_send_dummy_ccs(struct tls13_record_layer *rl);
/*
* Handshake Messages.
@@ -219,6 +220,7 @@ struct tls13_ctx {
struct tls13_handshake_stage handshake_stage;
int handshake_completed;
int middlebox_compat;
+ int send_dummy_ccs;
int close_notify_sent;
int close_notify_recv;
diff --git a/lib/libssl/tls13_record_layer.c b/lib/libssl/tls13_record_layer.c
index 6b9be4028cc..ce6327b6941 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.35 2020/05/09 15:39:18 jsing Exp $ */
+/* $OpenBSD: tls13_record_layer.c,v 1.36 2020/05/09 15:47:11 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -30,6 +30,7 @@ struct tls13_record_layer {
int ccs_allowed;
int ccs_seen;
+ int ccs_sent;
int handshake_completed;
int legacy_alerts_allowed;
int phh;
@@ -603,7 +604,14 @@ tls13_record_layer_seal_record_plaintext(struct tls13_record_layer *rl,
size_t data_len = 0;
CBB cbb, body;
- if (rl->aead != NULL)
+ /*
+ * Allow dummy CCS messages to be sent in plaintext even when
+ * record protection has been engaged, as long as the handshake
+ * has not yet completed.
+ */
+ if (rl->handshake_completed)
+ return 0;
+ if (rl->aead != NULL && content_type != SSL3_RT_CHANGE_CIPHER_SPEC)
return 0;
/*
@@ -752,7 +760,7 @@ tls13_record_layer_seal_record(struct tls13_record_layer *rl,
if ((rl->wrec = tls13_record_new()) == NULL)
return 0;
- if (rl->aead == NULL)
+ if (rl->aead == NULL || content_type == SSL3_RT_CHANGE_CIPHER_SPEC)
return tls13_record_layer_seal_record_plaintext(rl,
content_type, content, content_len);
@@ -1071,6 +1079,25 @@ tls13_record_layer_write(struct tls13_record_layer *rl, uint8_t content_type,
return ret;
}
+static const uint8_t tls13_dummy_ccs[] = { 0x01 };
+
+ssize_t
+tls13_send_dummy_ccs(struct tls13_record_layer *rl)
+{
+ ssize_t ret;
+
+ if (rl->ccs_sent)
+ return TLS13_IO_FAILURE;
+
+ if ((ret = tls13_record_layer_write(rl, SSL3_RT_CHANGE_CIPHER_SPEC,
+ tls13_dummy_ccs, sizeof(tls13_dummy_ccs))) <= 0)
+ return ret;
+
+ rl->ccs_sent = 1;
+
+ return TLS13_IO_SUCCESS;
+}
+
ssize_t
tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n)
{