summaryrefslogtreecommitdiff
path: root/test/wpackettest.c
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2022-05-23 10:42:03 +0100
committerTomas Mraz <tomas@openssl.org>2022-05-27 08:00:52 +0200
commit416d0a638c1635a182e57fe80c7c065dd76818c0 (patch)
treeaa70e7e9b9161ae2c30f7b6ed9bce6af66cace59 /test/wpackettest.c
parent1aef2c10f10e0685298008be596c80e148c71a51 (diff)
downloadopenssl-new-416d0a638c1635a182e57fe80c7c065dd76818c0.tar.gz
QUIC wire format support
Reviewed-by: Tim Hudson <tjh@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/18382)
Diffstat (limited to 'test/wpackettest.c')
-rw-r--r--test/wpackettest.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/test/wpackettest.c b/test/wpackettest.c
index b03dfcd2e0..a90c9a1553 100644
--- a/test/wpackettest.c
+++ b/test/wpackettest.c
@@ -26,6 +26,30 @@ static const unsigned char simpleder[] = {
0xfc, 0x04, 0x00, 0x01, 0x02, 0x03, 0xff, 0xfe, 0xfd
};
+/* QUIC sub-packet with 4-byte length prefix, containing a 1-byte vlint */
+static const unsigned char quic1[] = { 0x80, 0x00, 0x00, 0x01, 0x09 };
+/* QUIC sub-packet with 1-byte length prefix, containing a 1-byte vlint */
+static const unsigned char quic2[] = { 0x01, 0x09 };
+/* QUIC sub-packet with 2-byte length prefix, containing a 2-byte vlint */
+static const unsigned char quic3[] = { 0x40, 0x02, 0x40, 0x41 };
+/* QUIC sub-packet with 8-byte length prefix, containing a 4-byte vlint */
+static const unsigned char quic4[] = {
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x80, 0x01, 0x3c, 0x6a
+};
+/* QUIC sub-packet with 8-byte length prefix, containing a 8-byte vlint */
+static const unsigned char quic5[] = {
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xef, 0x77, 0x21, 0x3f, 0x3f, 0x50, 0x5b, 0xa5
+};
+/* QUIC sub-packet, length known up-front */
+static const unsigned char quic6[] = { 0x03, 0x55, 0x66, 0x77 };
+/* Nested and sequential sub-packets with length prefixes */
+static const unsigned char quic7[] = {
+ 0x07, 0x80, 0x00, 0x00, 0x08, 0x65, 0x14, 0x40, 0x01, 0x05,
+ 0x40, 0x01, 0x11, 0x40, 0x01, 0x12, 0x40, 0x01, 0x13
+};
+
static BUF_MEM *buf;
static int cleanup(WPACKET *pkt)
@@ -424,6 +448,179 @@ static int test_WPACKET_init_der(void)
return 1;
}
+static int test_WPACKET_quic(void)
+{
+ WPACKET pkt;
+ size_t written, len;
+ unsigned char *bytes;
+
+ /* QUIC sub-packet with 4-byte length prefix, containing a 1-byte vlint */
+ if (!TEST_true(WPACKET_init(&pkt, buf))
+ || !TEST_true(WPACKET_start_quic_sub_packet(&pkt))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x09))
+ /* Can't finish because we have a sub packet */
+ || !TEST_false(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_close(&pkt))
+ /* Sub packet is closed so can't close again */
+ || !TEST_false(WPACKET_close(&pkt))
+ /* Now a top level so finish should succeed */
+ || !TEST_true(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_get_total_written(&pkt, &written))
+ || !TEST_mem_eq(buf->data, written, quic1, sizeof(quic1)))
+ return cleanup(&pkt);
+
+ /* QUIC sub-packet with 1-byte length prefix, containing a 1-byte vlint */
+ if (!TEST_true(WPACKET_init(&pkt, buf))
+ || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_1B_MAX))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x09))
+ || !TEST_false(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_close(&pkt))
+ || !TEST_false(WPACKET_close(&pkt))
+ || !TEST_true(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_get_total_written(&pkt, &written))
+ || !TEST_mem_eq(buf->data, written, quic2, sizeof(quic2)))
+ return cleanup(&pkt);
+
+ /* QUIC sub-packet with 2-byte length prefix, containing a 2-byte vlint */
+ if (!TEST_true(WPACKET_init(&pkt, buf))
+ || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_2B_MIN))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x41))
+ || !TEST_false(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_close(&pkt))
+ || !TEST_false(WPACKET_close(&pkt))
+ || !TEST_true(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_get_total_written(&pkt, &written))
+ || !TEST_mem_eq(buf->data, written, quic3, sizeof(quic3)))
+ return cleanup(&pkt);
+
+ /* QUIC sub-packet with 8-byte length prefix, containing a 4-byte vlint */
+ if (!TEST_true(WPACKET_init(&pkt, buf))
+ || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_8B_MIN))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x13c6a))
+ || !TEST_false(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_close(&pkt))
+ || !TEST_false(WPACKET_close(&pkt))
+ || !TEST_true(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_get_total_written(&pkt, &written))
+ || !TEST_mem_eq(buf->data, written, quic4, sizeof(quic4)))
+ return cleanup(&pkt);
+
+ /* QUIC sub-packet with 8-byte length prefix, containing a 8-byte vlint */
+ if (!TEST_true(WPACKET_init(&pkt, buf))
+ || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_8B_MIN))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x2f77213f3f505ba5ULL))
+ || !TEST_false(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_close(&pkt))
+ || !TEST_false(WPACKET_close(&pkt))
+ || !TEST_true(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_get_total_written(&pkt, &written))
+ || !TEST_mem_eq(buf->data, written, quic5, sizeof(quic5)))
+ return cleanup(&pkt);
+
+ /* QUIC sub-packet, length known up-front */
+ if (!TEST_true(WPACKET_init(&pkt, buf))
+ || !TEST_true(WPACKET_quic_sub_allocate_bytes(&pkt, 3, &bytes)))
+ return cleanup(&pkt);
+
+ bytes[0] = 0x55;
+ bytes[1] = 0x66;
+ bytes[2] = 0x77;
+
+ if (!TEST_true(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_get_total_written(&pkt, &written))
+ || !TEST_mem_eq(buf->data, written, quic6, sizeof(quic6)))
+ return cleanup(&pkt);
+
+ /* Nested and sequential sub-packets with length prefixes */
+ if (!TEST_true(WPACKET_init(&pkt, buf))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x07))
+ || !TEST_true(WPACKET_get_length(&pkt, &len))
+ || !TEST_size_t_eq(len, 1)
+ || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_4B_MIN))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x2514))
+ || !TEST_true(WPACKET_get_length(&pkt, &len))
+ || !TEST_size_t_eq(len, 2)
+ || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_2B_MIN))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x05))
+ || !TEST_true(WPACKET_get_length(&pkt, &len))
+ || !TEST_size_t_eq(len, 1)
+ || !TEST_true(WPACKET_close(&pkt))
+ || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_2B_MIN))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x11))
+ || !TEST_true(WPACKET_close(&pkt))
+ || !TEST_true(WPACKET_get_length(&pkt, &len))
+ || !TEST_size_t_eq(len, 8)
+ || !TEST_true(WPACKET_close(&pkt))
+ || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_2B_MIN))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x12))
+ || !TEST_true(WPACKET_close(&pkt))
+ || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_2B_MIN))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x13))
+ || !TEST_true(WPACKET_close(&pkt))
+ || !TEST_true(WPACKET_finish(&pkt))
+ || !TEST_true(WPACKET_get_total_written(&pkt, &written))
+ || !TEST_mem_eq(buf->data, written, quic7, sizeof(quic7)))
+ return cleanup(&pkt);
+
+ /* Trying to encode a value above OSSL_QUIC_VLINT_MAX should fail */
+ if (!TEST_true(WPACKET_init(&pkt, buf))
+ || !TEST_false(WPACKET_quic_write_vlint(&pkt, OSSL_QUIC_VLINT_MAX+1))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, OSSL_QUIC_VLINT_MAX)))
+ return cleanup(&pkt);
+
+ WPACKET_cleanup(&pkt);
+ return 1;
+}
+
+static int test_WPACKET_quic_vlint_random(void)
+{
+ size_t i, written;
+ uint64_t expected, actual = 0;
+ unsigned char rand_data[9];
+ WPACKET pkt;
+ PACKET read_pkt = {0};
+
+ for (i = 0; i < 10000; ++i) {
+ if (!TEST_true(RAND_bytes(rand_data, sizeof(rand_data))))
+ return cleanup(&pkt);
+
+ expected = *(uint64_t*)rand_data;
+
+ /*
+ * Ensure that all size classes get tested with equal probability.
+ */
+ switch (rand_data[8] & 3) {
+ case 0:
+ expected &= OSSL_QUIC_VLINT_1B_MAX;
+ break;
+ case 1:
+ expected &= OSSL_QUIC_VLINT_2B_MAX;
+ break;
+ case 2:
+ expected &= OSSL_QUIC_VLINT_4B_MAX;
+ break;
+ case 3:
+ expected &= OSSL_QUIC_VLINT_8B_MAX;
+ break;
+ }
+
+ if (!TEST_true(WPACKET_init(&pkt, buf))
+ || !TEST_true(WPACKET_quic_write_vlint(&pkt, expected))
+ || !TEST_true(WPACKET_get_total_written(&pkt, &written)))
+ return cleanup(&pkt);
+
+ if (!TEST_true(PACKET_buf_init(&read_pkt, (unsigned char *)buf->data, written))
+ || !TEST_true(PACKET_get_quic_vlint(&read_pkt, &actual))
+ || !TEST_uint64_t_eq(expected, actual))
+ return cleanup(&pkt);
+
+ WPACKET_cleanup(&pkt);
+ }
+
+ WPACKET_cleanup(&pkt);
+ return 1;
+}
+
int setup_tests(void)
{
if (!TEST_ptr(buf = BUF_MEM_new()))
@@ -436,6 +633,8 @@ int setup_tests(void)
ADD_TEST(test_WPACKET_allocate_bytes);
ADD_TEST(test_WPACKET_memcpy);
ADD_TEST(test_WPACKET_init_der);
+ ADD_TEST(test_WPACKET_quic);
+ ADD_TEST(test_WPACKET_quic_vlint_random);
return 1;
}