From: Matt Caswell Date: Wed, 2 Aug 2023 15:43:11 +0000 (+0100) Subject: Unexpected QUIC post-handshake CertificateRequests are a PROTOCOL_VIOLATION X-Git-Tag: openssl-3.2.0-alpha1~216 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b644a9323f0060e27b3e45101856dc9e3bec0ac4;p=thirdparty%2Fopenssl.git Unexpected QUIC post-handshake CertificateRequests are a PROTOCOL_VIOLATION An OpenSSL QUIC client does not send the post_handshake_auth extension. Therefore if a server sends a post-handsahke CertificateRequest then this would be treated as a TLS protocol violation with an "unexpected message" alert code. However RFC 9001 specifically requires us to treat this as QUIC PROTOCOL_VIOLATION. So we have to translate the "unexpected message" alert code in this one instance. Reviewed-by: Hugo Landau Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21686) --- diff --git a/include/internal/quic_tls.h b/include/internal/quic_tls.h index 770c698d315..7d9c5337284 100644 --- a/include/internal/quic_tls.h +++ b/include/internal/quic_tls.h @@ -100,4 +100,6 @@ int ossl_quic_tls_get_error(QUIC_TLS *qtls, const char **error_msg, ERR_STATE **error_state); +int ossl_quic_tls_is_cert_request(QUIC_TLS *qtls); + #endif diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index f12dfd50493..7cabcb5ccf0 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -989,8 +989,25 @@ static int ch_on_handshake_alert(void *arg, unsigned char alert_code) { QUIC_CHANNEL *ch = arg; - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_CRYPTO_ERR_BEGIN + alert_code, - 0, "handshake alert"); + /* + * RFC 9001 s. 4.4: More specifically, servers MUST NOT send post-handshake + * TLS CertificateRequest messages, and clients MUST treat receipt of such + * messages as a connection error of type PROTOCOL_VIOLATION. + */ + if (alert_code == SSL3_AD_UNEXPECTED_MESSAGE + && ch->handshake_complete + && ossl_quic_tls_is_cert_request(ch->qtls)) + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + 0, + "Post-handshake TLS " + "CertificateRequest received"); + else + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_CRYPTO_ERR_BEGIN + + alert_code, + 0, "handshake alert"); + return 1; } diff --git a/ssl/quic/quic_tls.c b/ssl/quic/quic_tls.c index e8d46f5e86b..f3ef2c979e4 100644 --- a/ssl/quic/quic_tls.c +++ b/ssl/quic/quic_tls.c @@ -842,3 +842,14 @@ int ossl_quic_tls_get_error(QUIC_TLS *qtls, return qtls->inerror; } + +/* + * Returns true if the last handshake record message we processed was a + * CertificateRequest + */ +int ossl_quic_tls_is_cert_request(QUIC_TLS *qtls) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(qtls->args.s); + + return sc->s3.tmp.message_type == SSL3_MT_CERTIFICATE_REQUEST; +}