Home | History | Annotate | Line # | Download | only in internal
packet_quic.h revision 1.1
      1 /*
      2  * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #ifndef OSSL_INTERNAL_PACKET_QUIC_H
     11 # define OSSL_INTERNAL_PACKET_QUIC_H
     12 # pragma once
     13 
     14 # include "internal/packet.h"
     15 # include "internal/quic_vlint.h"
     16 
     17 # ifndef OPENSSL_NO_QUIC
     18 /*
     19  * Decodes a QUIC variable-length integer in |pkt| and stores the result in
     20  * |data|.
     21  */
     22 __owur static ossl_inline int PACKET_get_quic_vlint(PACKET *pkt,
     23                                                     uint64_t *data)
     24 {
     25     size_t enclen;
     26 
     27     if (PACKET_remaining(pkt) < 1)
     28         return 0;
     29 
     30     enclen = ossl_quic_vlint_decode_len(*pkt->curr);
     31 
     32     if (PACKET_remaining(pkt) < enclen)
     33         return 0;
     34 
     35     *data = ossl_quic_vlint_decode_unchecked(pkt->curr);
     36     packet_forward(pkt, enclen);
     37     return 1;
     38 }
     39 
     40 /*
     41  * Decodes a QUIC variable-length integer in |pkt| and stores the result in
     42  * |data|. Unlike PACKET_get_quic_vlint, this does not advance the current
     43  * position. If was_minimal is non-NULL, *was_minimal is set to 1 if the integer
     44  * was encoded using the minimal possible number of bytes and 0 otherwise.
     45  */
     46 __owur static ossl_inline int PACKET_peek_quic_vlint_ex(PACKET *pkt,
     47                                                         uint64_t *data,
     48                                                         int *was_minimal)
     49 {
     50     size_t enclen;
     51 
     52     if (PACKET_remaining(pkt) < 1)
     53         return 0;
     54 
     55     enclen = ossl_quic_vlint_decode_len(*pkt->curr);
     56 
     57     if (PACKET_remaining(pkt) < enclen)
     58         return 0;
     59 
     60     *data = ossl_quic_vlint_decode_unchecked(pkt->curr);
     61 
     62     if (was_minimal != NULL)
     63         *was_minimal = (enclen == ossl_quic_vlint_encode_len(*data));
     64 
     65     return 1;
     66 }
     67 
     68 __owur static ossl_inline int PACKET_peek_quic_vlint(PACKET *pkt,
     69                                                      uint64_t *data)
     70 {
     71     return PACKET_peek_quic_vlint_ex(pkt, data, NULL);
     72 }
     73 
     74 /*
     75  * Skips over a QUIC variable-length integer in |pkt| without decoding it.
     76  */
     77 __owur static ossl_inline int PACKET_skip_quic_vlint(PACKET *pkt)
     78 {
     79     size_t enclen;
     80 
     81     if (PACKET_remaining(pkt) < 1)
     82         return 0;
     83 
     84     enclen = ossl_quic_vlint_decode_len(*pkt->curr);
     85 
     86     if (PACKET_remaining(pkt) < enclen)
     87         return 0;
     88 
     89     packet_forward(pkt, enclen);
     90     return 1;
     91 }
     92 
     93 /*
     94  * Reads a variable-length vector prefixed with a QUIC variable-length integer
     95  * denoting the length, and stores the contents in |subpkt|. |pkt| can equal
     96  * |subpkt|. Data is not copied: the |subpkt| packet will share its underlying
     97  * buffer with the original |pkt|, so data wrapped by |pkt| must outlive the
     98  * |subpkt|. Upon failure, the original |pkt| and |subpkt| are not modified.
     99  */
    100 __owur static ossl_inline int PACKET_get_quic_length_prefixed(PACKET *pkt,
    101                                                               PACKET *subpkt)
    102 {
    103     uint64_t length;
    104     const unsigned char *data;
    105     PACKET tmp = *pkt;
    106 
    107     if (!PACKET_get_quic_vlint(&tmp, &length) ||
    108         length > SIZE_MAX ||
    109         !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
    110         return 0;
    111     }
    112 
    113     *pkt = tmp;
    114     subpkt->curr = data;
    115     subpkt->remaining = (size_t)length;
    116 
    117     return 1;
    118 }
    119 
    120 /*
    121  * Starts a QUIC sub-packet headed by a QUIC variable-length integer. A 4-byte
    122  * representation is used.
    123  */
    124 __owur int WPACKET_start_quic_sub_packet(WPACKET *pkt);
    125 
    126 /*
    127  * Starts a QUIC sub-packet headed by a QUIC variable-length integer. max_len
    128  * specifies the upper bound for the sub-packet size at the time the sub-packet
    129  * is closed, which determines the encoding size for the variable-length
    130  * integer header. max_len can be a precise figure or a worst-case bound
    131  * if a precise figure is not available.
    132  */
    133 __owur int WPACKET_start_quic_sub_packet_bound(WPACKET *pkt, size_t max_len);
    134 
    135 /*
    136  * Allocates a QUIC sub-packet with exactly len bytes of payload, headed by a
    137  * QUIC variable-length integer. The pointer to the payload buffer is output and
    138  * must be filled by the caller. This function assures optimal selection of
    139  * variable-length integer encoding length.
    140  */
    141 __owur int WPACKET_quic_sub_allocate_bytes(WPACKET *pkt, size_t len,
    142                                            unsigned char **bytes);
    143 
    144 /*
    145  * Write a QUIC variable-length integer to the packet.
    146  */
    147 __owur int WPACKET_quic_write_vlint(WPACKET *pkt, uint64_t v);
    148 
    149 # endif                         /* OPENSSL_NO_QUIC */
    150 #endif                          /* OSSL_INTERNAL_PACKET_QUIC_H */
    151