From c2c636122df9e366095ad1200a7107fa6e57069a Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Sun, 3 May 2020 15:57:26 +0000 Subject: 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@ --- lib/libssl/tls13_record_layer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/libssl/tls13_record_layer.c b/lib/libssl/tls13_record_layer.c index 0bf1d19d918..5c2c2116c04 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.32 2020/05/02 00:31:54 inoguchi Exp $ */ +/* $OpenBSD: tls13_record_layer.c,v 1.33 2020/05/03 15:57:25 jsing Exp $ */ /* * Copyright (c) 2018, 2019 Joel Sing * @@ -787,7 +787,7 @@ tls13_record_layer_read_record(struct tls13_record_layer *rl) * ignored. */ if (content_type == SSL3_RT_CHANGE_CIPHER_SPEC) { - if (!rl->ccs_allowed || rl->ccs_seen) + if (!rl->ccs_allowed || rl->ccs_seen >= 2) return tls13_send_alert(rl, SSL_AD_UNEXPECTED_MESSAGE); if (!tls13_record_content(rl->rrec, &cbs)) return tls13_send_alert(rl, TLS1_AD_DECODE_ERROR); @@ -795,7 +795,7 @@ tls13_record_layer_read_record(struct tls13_record_layer *rl) return tls13_send_alert(rl, TLS1_AD_DECODE_ERROR); if (ccs != 1) return tls13_send_alert(rl, SSL_AD_ILLEGAL_PARAMETER); - rl->ccs_seen = 1; + rl->ccs_seen++; tls13_record_layer_rrec_free(rl); return TLS13_IO_WANT_RETRY; } -- cgit v1.2.3