]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Unexpected QUIC post-handshake CertificateRequests are a PROTOCOL_VIOLATION
authorMatt Caswell <matt@openssl.org>
Wed, 2 Aug 2023 15:43:11 +0000 (16:43 +0100)
committerMatt Caswell <matt@openssl.org>
Tue, 15 Aug 2023 13:41:31 +0000 (14:41 +0100)
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 <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21686)

include/internal/quic_tls.h
ssl/quic/quic_channel.c
ssl/quic/quic_tls.c

index 770c698d315ddbe3e887f910d9721c5ee59c0e1c..7d9c533728456489a267a36162accbad1983bd75 100644 (file)
@@ -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
index f12dfd504931aea79f999215f595bc3a4731fa94..7cabcb5ccf0d0e65c45f8263b8b539b792c0518c 100644 (file)
@@ -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;
 }
 
index e8d46f5e86bfe16ee1c7dab615146d44cca7f1cc..f3ef2c979e4eb573facf43a3e2b5e7faddc8fa32 100644 (file)
@@ -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;
+}