diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2020-05-09 15:47:12 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2020-05-09 15:47:12 +0000 |
commit | 1255f4593d55f6c28cc5a865759d9a6fc96e238f (patch) | |
tree | 2a7cbbb99c1b1df72b76d9580ed71d2051c24f24 /lib | |
parent | af321e3aadad9ca0c26057fa97c77eaeaa3b6ac9 (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.c | 6 | ||||
-rw-r--r-- | lib/libssl/tls13_handshake.c | 8 | ||||
-rw-r--r-- | lib/libssl/tls13_internal.h | 4 | ||||
-rw-r--r-- | lib/libssl/tls13_record_layer.c | 33 |
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) { |