summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2023-08-17 09:44:37 +0100
committerTomas Mraz <tomas@openssl.org>2023-08-29 15:33:39 +0200
commit69169cd9faf68e6d8fb83895233c184543151168 (patch)
treeff40097f742898238066c9dedfb24406eef6de07
parentde85ec03f5c6044fae8f2d1812d59aab0687b12a (diff)
QUIC: Version negotiation testing
Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21764)
-rw-r--r--test/quic_multistream_test.c128
-rw-r--r--test/quic_record_test.c5
2 files changed, 132 insertions, 1 deletions
diff --git a/test/quic_multistream_test.c b/test/quic_multistream_test.c
index 42221880d1..ba97bfd7d4 100644
--- a/test/quic_multistream_test.c
+++ b/test/quic_multistream_test.c
@@ -80,6 +80,8 @@ struct helper {
unsigned char *buf, size_t buf_len);
int (*qtf_handshake_cb)(struct helper *h,
unsigned char *buf, size_t buf_len);
+ int (*qtf_datagram_cb)(struct helper *h,
+ BIO_MSG *m, size_t stride);
uint64_t inject_word0, inject_word1;
uint64_t scratch0, scratch1, fail_count;
};
@@ -101,6 +103,8 @@ struct script_op {
unsigned char *buf, size_t buf_len);
int (*qtf_handshake_cb)(struct helper *h,
unsigned char *buf, size_t buf_len);
+ int (*qtf_datagram_cb)(struct helper *h,
+ BIO_MSG *m, size_t stride);
};
#define OPK_END 0
@@ -152,6 +156,7 @@ struct script_op {
#define OPK_S_SET_INJECT_HANDSHAKE 46
#define OPK_S_NEW_TICKET 47
#define OPK_C_SKIP_IF_UNBOUND 48
+#define OPK_S_SET_INJECT_DATAGRAM 49
#define EXPECT_CONN_CLOSE_APP (1U << 0)
#define EXPECT_CONN_CLOSE_REMOTE (1U << 1)
@@ -286,6 +291,8 @@ struct script_op {
{OPK_S_NEW_TICKET},
#define OP_C_SKIP_IF_UNBOUND(stream_name, n) \
{OPK_C_SKIP_IF_UNBOUND, NULL, (n), NULL, #stream_name},
+#define OP_S_SET_INJECT_DATAGRAM(f) \
+ {OPK_S_SET_INJECT_DATAGRAM, NULL, 0, NULL, NULL, 0, NULL, NULL, (f)},
static OSSL_TIME get_time(void *arg)
{
@@ -779,6 +786,15 @@ static int helper_handshake_listener(QTEST_FAULT *fault,
return h->qtf_handshake_cb(h, buf, buf_len);
}
+static int helper_datagram_listener(QTEST_FAULT *fault,
+ BIO_MSG *msg, size_t stride,
+ void *arg)
+{
+ struct helper *h = arg;
+
+ return h->qtf_datagram_cb(h, msg, stride);
+}
+
static int is_want(SSL *s, int ret)
{
int ec = SSL_get_error(s, ret);
@@ -1599,6 +1615,17 @@ static int run_script_worker(struct helper *h, const struct script_op *script,
break;
+ case OPK_S_SET_INJECT_DATAGRAM:
+ h->qtf_datagram_cb = op->qtf_datagram_cb;
+
+ if (!TEST_true(qtest_fault_set_datagram_listener(h->qtf,
+ h->qtf_datagram_cb != NULL ?
+ helper_datagram_listener : NULL,
+ h)))
+ goto out;
+
+ break;
+
case OPK_SET_INJECT_WORD:
h->inject_word0 = op->arg1;
h->inject_word1 = op->arg2;
@@ -4411,6 +4438,103 @@ static const struct script_op script_73[] = {
OP_END
};
+/* 74. Version negotiation: QUIC_VERSION_1 ignored */
+static int generate_version_neg(WPACKET *wpkt, uint32_t version)
+{
+ QUIC_PKT_HDR hdr = {0};
+
+ hdr.type = QUIC_PKT_TYPE_VERSION_NEG;
+ hdr.fixed = 1;
+ hdr.dst_conn_id.id_len = 0;
+ hdr.src_conn_id.id_len = 8;
+ memset(hdr.src_conn_id.id, 0x55, 8);
+
+ if (!TEST_true(ossl_quic_wire_encode_pkt_hdr(wpkt, 0, &hdr, NULL)))
+ return 0;
+
+ if (!TEST_true(WPACKET_put_bytes_u32(wpkt, version)))
+ return 0;
+
+ return 1;
+}
+
+static int server_gen_version_neg(struct helper *h, BIO_MSG *msg, size_t stride)
+{
+ int rc = 0, have_wpkt = 0;
+ size_t l;
+ WPACKET wpkt;
+ BUF_MEM *buf = NULL;
+ uint32_t version;
+
+ switch (h->inject_word0) {
+ case 0:
+ return 1;
+ case 1:
+ version = QUIC_VERSION_1;
+ break;
+ default:
+ version = 0x5432abcd;
+ break;
+ }
+
+ if (!TEST_ptr(buf = BUF_MEM_new()))
+ goto err;
+
+ if (!TEST_true(WPACKET_init(&wpkt, buf)))
+ goto err;
+
+ have_wpkt = 1;
+
+ generate_version_neg(&wpkt, version);
+
+ if (!TEST_true(WPACKET_get_total_written(&wpkt, &l)))
+ goto err;
+
+ if (!TEST_true(qtest_fault_resize_datagram(h->qtf, l)))
+ return 0;
+
+ memcpy(msg->data, buf->data, l);
+ h->inject_word0 = 0;
+
+ rc = 1;
+err:
+ if (have_wpkt)
+ WPACKET_finish(&wpkt);
+
+ BUF_MEM_free(buf);
+ return rc;
+}
+
+static const struct script_op script_74[] = {
+ OP_S_SET_INJECT_DATAGRAM (server_gen_version_neg)
+ OP_SET_INJECT_WORD (1, 0)
+
+ OP_C_SET_ALPN ("ossltest")
+ OP_C_CONNECT_WAIT ()
+
+ OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE)
+
+ OP_C_NEW_STREAM_BIDI (a, C_BIDI_ID(0))
+ OP_C_WRITE (a, "apple", 5)
+ OP_S_BIND_STREAM_ID (a, C_BIDI_ID(0))
+ OP_S_READ_EXPECT (a, "apple", 5)
+
+ OP_END
+};
+
+/* 75. Version negotiation: Unknown version causes connection abort */
+static const struct script_op script_75[] = {
+ OP_S_SET_INJECT_DATAGRAM (server_gen_version_neg)
+ OP_SET_INJECT_WORD (2, 0)
+
+ OP_C_SET_ALPN ("ossltest")
+ OP_C_CONNECT_WAIT_OR_FAIL()
+
+ OP_C_EXPECT_CONN_CLOSE_INFO(QUIC_ERR_CONNECTION_REFUSED,0,0)
+
+ OP_END
+};
+
static const struct script_op *const scripts[] = {
script_1,
script_2,
@@ -4484,7 +4608,9 @@ static const struct script_op *const scripts[] = {
script_70,
script_71,
script_72,
- script_73
+ script_73,
+ script_74,
+ script_75
};
static int test_script(int idx)
diff --git a/test/quic_record_test.c b/test/quic_record_test.c
index 2521b0ce2c..a2144744a3 100644
--- a/test/quic_record_test.c
+++ b/test/quic_record_test.c
@@ -2753,6 +2753,11 @@ static int test_wire_pkt_hdr_actual(int tidx, int repeat, int cipher,
hpr_key[8] = (unsigned char)tidx;
hpr_key[9] = (unsigned char)repeat;
+ if (is_trunc && trunc_len > t->min_success_len
+ && t->hdr.type == QUIC_PKT_TYPE_VERSION_NEG
+ && ((trunc_len - t->min_success_len) % 4) != 0)
+ expect_fail = 1;
+
switch (cipher) {
case 0:
hpr_cipher_id = QUIC_HDR_PROT_CIPHER_AES_128;