]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Support trace for QUIC Packets
authorMatt Caswell <matt@openssl.org>
Thu, 4 May 2023 14:47:32 +0000 (15:47 +0100)
committerMatt Caswell <matt@openssl.org>
Wed, 24 May 2023 11:18:27 +0000 (12:18 +0100)
We enable SSL_trace support for when we receive QUIC Packets. This is
called after header protection is removed, but before the packet is
decrypted.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20914)

include/openssl/ssl3.h
ssl/quic/quic_record_rx.c
ssl/quic/quic_trace.c

index f993d0baa068a3fc58cc166688dbf2e68a7ca182..6d83383ff4d5571eaa39211be26a6d06a1ce2d79 100644 (file)
@@ -241,6 +241,7 @@ extern "C" {
 
 /* Pseudo content types for QUIC */
 # define SSL3_RT_QUIC_DATAGRAM            0x200
+# define SSL3_RT_QUIC_PACKET              0x201
 
 # define SSL3_AL_WARNING                 1
 # define SSL3_AL_FATAL                   2
index 394050afe671e40605edccd114e66287faab0a6d..afc5011a491bea892e6f006ebdfb99bcc221d881 100644 (file)
@@ -840,6 +840,10 @@ static int qrx_process_pkt(OSSL_QRX *qrx, QUIC_URXE *urxe,
         if (ossl_quic_wire_decode_pkt_hdr(pkt, qrx->short_conn_id_len,
                                           0, &rxe->hdr, NULL) != 1)
             goto malformed;
+
+        if (qrx->msg_callback != NULL)
+            qrx->msg_callback(0, OSSL_QUIC1_VERSION, SSL3_RT_QUIC_PACKET, sop,
+                              eop - sop, qrx->msg_callback_s, qrx->msg_callback_arg);
     }
 
     /* Validate header and decode PN. */
@@ -995,7 +999,7 @@ static int qrx_process_datagram(OSSL_QRX *qrx, QUIC_URXE *e,
 
     for (; PACKET_remaining(&pkt) > 0; ++pkt_idx) {
         /*
-         * A packet smallest than the minimum possible QUIC packet size is not
+         * A packet smaller than the minimum possible QUIC packet size is not
          * considered valid. We also ignore more than a certain number of
          * packets within the same datagram.
          */
index 614167f2cbab1ed415c6c8bb2c5393dc0e61b8e4..1a083560038363be2b1dffa320f7ed5d382ab172 100644 (file)
@@ -9,6 +9,55 @@
 
 #include <openssl/bio.h>
 #include "../ssl_local.h"
+#include "internal/quic_wire_pkt.h"
+
+static const char *packet_type(int type)
+{
+    switch (type) {
+    case QUIC_PKT_TYPE_INITIAL:
+        return "Initial";
+
+    case QUIC_PKT_TYPE_0RTT:
+        return "0RTT";
+
+    case QUIC_PKT_TYPE_HANDSHAKE:
+        return "Handshake";
+
+    case QUIC_PKT_TYPE_RETRY:
+        return "Retry";
+
+    case QUIC_PKT_TYPE_1RTT:
+        return "1RTT";
+
+    case QUIC_PKT_TYPE_VERSION_NEG:
+        return "VersionNeg";
+
+    default:
+        return "Unknown";
+    }
+}
+
+static const char *conn_id(QUIC_CONN_ID *id, char *buf, size_t buflen)
+{
+    size_t i;
+    char *obuf = buf;
+
+    if (id->id_len == 0)
+        return "<zero length id>";
+
+    if ((((size_t)id->id_len * 2) + 2) > buflen - 1)
+        return "<id too long>"; /* Should never happen */
+
+    buf[0] = '0';
+    buf[1]= 'x';
+    buf += 2;
+    buflen -= 2;
+
+    for (i = 0; i < id->id_len; i++, buflen -= 2, buf += 2)
+        BIO_snprintf(buf, buflen, "%02x", id->id[i]);
+
+    return obuf;
+}
 
 int ossl_quic_trace(int write_p, int version, int content_type,
                     const void *buf, size_t msglen, SSL *ssl, void *arg)
@@ -26,6 +75,60 @@ int ossl_quic_trace(int write_p, int version, int content_type,
         BIO_printf(bio, " Datagram\n  Length: %zu\n", msglen);
         break;
 
+    case SSL3_RT_QUIC_PACKET:
+        {
+            PACKET pkt;
+            QUIC_PKT_HDR hdr;
+            /*
+             * Max Conn id is 20 bytes (40 hex digits) plus "0x" bytes plus NUL
+             * terminator
+             */
+            char tmpbuf[43];
+            size_t i;
+
+            if (!PACKET_buf_init(&pkt, buf, msglen))
+                return 0;
+            /* Decode the packet header */
+            /*
+             * TODO(QUIC): We need to query the short connection id len here,
+             *             e.g. via some API SSL_get_short_conn_id_len()
+             */
+            if (ossl_quic_wire_decode_pkt_hdr(&pkt, 0, 0, &hdr, NULL) != 1)
+                return 0;
+
+            BIO_puts(bio, write_p ? "Sent" : "Received");
+            BIO_puts(bio, " Packet\n");
+            BIO_printf(bio, "  Packet Type: %s\n", packet_type(hdr.type));
+            if (hdr.type != QUIC_PKT_TYPE_1RTT)
+                BIO_printf(bio, "  Version: 0x%08x\n", hdr.version);
+            BIO_printf(bio, "  Destination Conn Id: %s\n",
+                       conn_id(&hdr.dst_conn_id, tmpbuf, sizeof(tmpbuf)));
+            if (hdr.type != QUIC_PKT_TYPE_1RTT)
+                BIO_printf(bio, "  Source Conn Id: %s\n",
+                           conn_id(&hdr.src_conn_id, tmpbuf, sizeof(tmpbuf)));
+            BIO_printf(bio, "  Payload length: %zu\n", hdr.len);
+            if (hdr.type == QUIC_PKT_TYPE_INITIAL) {
+                BIO_puts(bio, "  Token: ");
+                if (hdr.token_len == 0) {
+                    BIO_puts(bio, "<zerlo length token>");
+                } else {
+                    for (i = 0; i < hdr.token_len; i++)
+                        BIO_printf(bio, "%02x", hdr.token[i]);
+                }
+                BIO_puts(bio, "\n");
+            }
+            if (hdr.type != QUIC_PKT_TYPE_VERSION_NEG
+                    && hdr.type != QUIC_PKT_TYPE_RETRY) {
+                BIO_puts(bio, "  Packet Number: 0x");
+                /* Will always be at least 1 byte */
+                for (i = 0; i < hdr.pn_len; i++)
+                    BIO_printf(bio, "%02x", hdr.pn[i]);
+                BIO_puts(bio, "\n");
+            }
+            break;
+        }
+
+
     default:
         /* Unrecognised content_type. We defer to SSL_trace */
         return 0;