summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2020-05-03 15:57:25 +0000
committerjsing <>2020-05-03 15:57:25 +0000
commitc011805d37d80a9f55b2f013aa73f0183dff7d25 (patch)
tree755d94da4a23dcf730eefb7412abdd7925f3d7a7
parent2e6d47dd230cf0a1dc61aea57faf78019cf22858 (diff)
downloadopenbsd-c011805d37d80a9f55b2f013aa73f0183dff7d25.tar.gz
openbsd-c011805d37d80a9f55b2f013aa73f0183dff7d25.tar.bz2
openbsd-c011805d37d80a9f55b2f013aa73f0183dff7d25.zip
Accept two ChangeCipherSpec messages during a TLSv1.3 handshake.
In compatibility mode, a TLSv1.3 server MUST send a dummy CCS message immediately after its first handshake message. This is normally after the ServerHello message, but it can be after the HelloRetryRequest message. As such we accept one CCS message from the server during the handshake. However, it turns out that in the HelloRetryRequest case, Facebook's fizz TLSv1.3 stack sends CCS messages after both the HelloRetryRequest message and the ServerHello message. This is unexpected and as far as I'm aware, no other TLSv1.3 implementation does this. Unfortunately the RFC is rather ambiguous here, which probably means it is not strictly an RFC violation. Relax the CCS message handling to allow two dummy CCS messages during a TLSv1.3. This makes our TLSv1.3 client work with Facebook Fizz when HRR is triggered. Issue discovered by inoguchi@ and investigated by tb@. ok deraadt@ tb@
-rw-r--r--src/lib/libssl/tls13_record_layer.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/src/lib/libssl/tls13_record_layer.c b/src/lib/libssl/tls13_record_layer.c
index 0bf1d19d91..5c2c2116c0 100644
--- a/src/lib/libssl/tls13_record_layer.c
+++ b/src/lib/libssl/tls13_record_layer.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls13_record_layer.c,v 1.32 2020/05/02 00:31:54 inoguchi Exp $ */ 1/* $OpenBSD: tls13_record_layer.c,v 1.33 2020/05/03 15:57:25 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -787,7 +787,7 @@ tls13_record_layer_read_record(struct tls13_record_layer *rl)
787 * ignored. 787 * ignored.
788 */ 788 */
789 if (content_type == SSL3_RT_CHANGE_CIPHER_SPEC) { 789 if (content_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
790 if (!rl->ccs_allowed || rl->ccs_seen) 790 if (!rl->ccs_allowed || rl->ccs_seen >= 2)
791 return tls13_send_alert(rl, SSL_AD_UNEXPECTED_MESSAGE); 791 return tls13_send_alert(rl, SSL_AD_UNEXPECTED_MESSAGE);
792 if (!tls13_record_content(rl->rrec, &cbs)) 792 if (!tls13_record_content(rl->rrec, &cbs))
793 return tls13_send_alert(rl, TLS1_AD_DECODE_ERROR); 793 return tls13_send_alert(rl, TLS1_AD_DECODE_ERROR);
@@ -795,7 +795,7 @@ tls13_record_layer_read_record(struct tls13_record_layer *rl)
795 return tls13_send_alert(rl, TLS1_AD_DECODE_ERROR); 795 return tls13_send_alert(rl, TLS1_AD_DECODE_ERROR);
796 if (ccs != 1) 796 if (ccs != 1)
797 return tls13_send_alert(rl, SSL_AD_ILLEGAL_PARAMETER); 797 return tls13_send_alert(rl, SSL_AD_ILLEGAL_PARAMETER);
798 rl->ccs_seen = 1; 798 rl->ccs_seen++;
799 tls13_record_layer_rrec_free(rl); 799 tls13_record_layer_rrec_free(rl);
800 return TLS13_IO_WANT_RETRY; 800 return TLS13_IO_WANT_RETRY;
801 } 801 }