]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Introduce the PACKET_msg_start() function
authorMatt Caswell <matt@openssl.org>
Thu, 5 Jun 2025 13:41:55 +0000 (14:41 +0100)
committerTomas Mraz <tomas@openssl.org>
Tue, 18 Nov 2025 08:34:30 +0000 (09:34 +0100)
This gives us the start of the buffer in use for the PACKET.

We then use this information when calculating the TLS PSK binder.
Previously we were assuming knowledge about where the buffer starts.
However, with ECH, we may be using a different buffer to normal so it is
better to ask the PACKET where the start of the buffer is.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27776)

include/internal/packet.h
ssl/statem/extensions_srvr.c
ssl/statem/statem.c

index 2051cabd99d02fa5e63a218cc0ee155f60824470..cce3bf5c9ff4e359a82a4bf206a9aff402fe02fd 100644 (file)
@@ -22,6 +22,8 @@
 typedef struct {
     /* Pointer to where we are currently reading from */
     const unsigned char *curr;
+    /* Pointer to the start of the message */
+    const unsigned char *msgstart;
     /* Number of bytes remaining */
     size_t remaining;
 } PACKET;
@@ -52,6 +54,15 @@ static ossl_inline const unsigned char *PACKET_end(const PACKET *pkt)
     return pkt->curr + pkt->remaining;
 }
 
+/*
+ * Returns a pointer to the very start of the buffer. If this is a sub packet
+ * this will be the start of the buffer for the top of the PACKET tree.
+ */
+static ossl_inline const unsigned char *PACKET_msg_start(const PACKET *pkt)
+{
+    return pkt->msgstart;
+}
+
 /*
  * Returns a pointer to the PACKET's current position.
  * For use in non-PACKETized APIs.
@@ -74,7 +85,7 @@ __owur static ossl_inline int PACKET_buf_init(PACKET *pkt,
     if (len > (size_t)(SIZE_MAX / 2))
         return 0;
 
-    pkt->curr = buf;
+    pkt->curr = pkt->msgstart = buf;
     pkt->remaining = len;
     return 1;
 }
@@ -82,7 +93,7 @@ __owur static ossl_inline int PACKET_buf_init(PACKET *pkt,
 /* Initialize a PACKET to hold zero bytes. */
 static ossl_inline void PACKET_null_init(PACKET *pkt)
 {
-    pkt->curr = NULL;
+    pkt->curr = pkt->msgstart = NULL;
     pkt->remaining = 0;
 }
 
@@ -110,7 +121,11 @@ __owur static ossl_inline int PACKET_peek_sub_packet(const PACKET *pkt,
     if (PACKET_remaining(pkt) < len)
         return 0;
 
-    return PACKET_buf_init(subpkt, pkt->curr, len);
+    if (!PACKET_buf_init(subpkt, pkt->curr, len))
+        return 0;
+
+    subpkt->msgstart = pkt->msgstart;
+    return 1;
 }
 
 /*
@@ -543,6 +558,7 @@ __owur static ossl_inline int PACKET_get_length_prefixed_1(PACKET *pkt,
 
     *pkt = tmp;
     subpkt->curr = data;
+    subpkt->msgstart = pkt->msgstart;
     subpkt->remaining = length;
 
     return 1;
@@ -566,6 +582,7 @@ __owur static ossl_inline int PACKET_as_length_prefixed_1(PACKET *pkt,
 
     *pkt = tmp;
     subpkt->curr = data;
+    subpkt->msgstart = pkt->msgstart;
     subpkt->remaining = length;
 
     return 1;
@@ -592,6 +609,7 @@ __owur static ossl_inline int PACKET_get_length_prefixed_2(PACKET *pkt,
 
     *pkt = tmp;
     subpkt->curr = data;
+    subpkt->msgstart = pkt->msgstart;
     subpkt->remaining = length;
 
     return 1;
@@ -616,6 +634,7 @@ __owur static ossl_inline int PACKET_as_length_prefixed_2(PACKET *pkt,
 
     *pkt = tmp;
     subpkt->curr = data;
+    subpkt->msgstart = pkt->msgstart;
     subpkt->remaining = length;
 
     return 1;
@@ -641,6 +660,7 @@ __owur static ossl_inline int PACKET_get_length_prefixed_3(PACKET *pkt,
 
     *pkt = tmp;
     subpkt->curr = data;
+    subpkt->msgstart = pkt->msgstart;
     subpkt->remaining = length;
 
     return 1;
index ac2bddde3b0c7dffc83c792141b44bb1baf550f3..0fc03e9acca6bc0f2985b3e3d88e23dcb51ffa08 100644 (file)
@@ -1517,7 +1517,7 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context,
     if (sess == NULL)
         return 1;
 
-    binderoffset = PACKET_data(pkt) - (const unsigned char *)s->init_buf->data;
+    binderoffset = PACKET_data(pkt) - PACKET_msg_start(pkt);
     hashsize = EVP_MD_get_size(md);
     if (hashsize <= 0)
         goto err;
@@ -1538,9 +1538,8 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context,
         SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
         goto err;
     }
-    if (tls_psk_do_binder(s, md, (const unsigned char *)s->init_buf->data,
-                          binderoffset, PACKET_data(&binder), NULL, sess, 0,
-                          ext) != 1) {
+    if (tls_psk_do_binder(s, md, PACKET_msg_start(pkt), binderoffset,
+                          PACKET_data(&binder), NULL, sess, 0, ext) != 1) {
         /* SSLfatal() already called */
         goto err;
     }
index 864a2f1a339f00fd5e67bbcbb367fcf8d48425d4..97df583f5dcde061f0b1916b446536a0e376bde5 100644 (file)
@@ -588,7 +588,7 @@ static SUB_STATE_RETURN read_state_machine(SSL_CONNECTION *s)
 {
     OSSL_STATEM *st = &s->statem;
     int ret, mt;
-    size_t len = 0;
+    size_t len = 0, headerlen;
     int (*transition) (SSL_CONNECTION *s, int mt);
     PACKET pkt;
     MSG_PROCESS_RETURN(*process_message) (SSL_CONNECTION *s, PACKET *pkt);
@@ -682,10 +682,23 @@ static SUB_STATE_RETURN read_state_machine(SSL_CONNECTION *s)
             }
 
             s->first_packet = 0;
-            if (!PACKET_buf_init(&pkt, s->init_msg, len)) {
+            /*
+             * We initialise the buffer including the message header, and
+             * then skip over header ready to process the message. This
+             * ensures that calls to PACKET_msg_start() gives us the whole
+             * message
+             */
+            headerlen = (char *)s->init_msg - s->init_buf->data;
+            if (!PACKET_buf_init(&pkt, (unsigned char *)s->init_buf->data,
+                                 len + headerlen)) {
+                SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+                return SUB_STATE_ERROR;
+            }
+            if (!PACKET_forward(&pkt, headerlen)) {
                 SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
                 return SUB_STATE_ERROR;
             }
+
             ret = process_message(s, &pkt);
 
             /* Discard the packet data */