diff options
author | Hugo Landau <hlandau@openssl.org> | 2022-05-23 10:42:03 +0100 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2022-05-27 08:00:52 +0200 |
commit | 416d0a638c1635a182e57fe80c7c065dd76818c0 (patch) | |
tree | aa70e7e9b9161ae2c30f7b6ed9bce6af66cace59 /test/wpackettest.c | |
parent | 1aef2c10f10e0685298008be596c80e148c71a51 (diff) | |
download | openssl-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.c | 199 |
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; } |