summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/internal/quic_channel.h6
-rw-r--r--include/internal/quic_record_tx.h22
-rw-r--r--include/internal/quic_tserver.h6
-rw-r--r--ssl/quic/quic_channel.c13
-rw-r--r--ssl/quic/quic_record_tx.c65
-rw-r--r--ssl/quic/quic_tserver.c10
6 files changed, 102 insertions, 20 deletions
diff --git a/include/internal/quic_channel.h b/include/internal/quic_channel.h
index 83eb90a662..a4039d8c02 100644
--- a/include/internal/quic_channel.h
+++ b/include/internal/quic_channel.h
@@ -73,6 +73,12 @@ QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args);
/* No-op if ch is NULL. */
void ossl_quic_channel_free(QUIC_CHANNEL *ch);
+/* Set mutator callbacks for test framework support */
+int ossl_quic_channel_set_mutator(QUIC_CHANNEL *ch,
+ ossl_mutate_packet_cb mutatecb,
+ ossl_finish_mutate_cb finishmutatecb,
+ void *mutatearg);
+
/*
* Connection Lifecycle Events
* ===========================
diff --git a/include/internal/quic_record_tx.h b/include/internal/quic_record_tx.h
index ba2cf7fe78..2cc7333c02 100644
--- a/include/internal/quic_record_tx.h
+++ b/include/internal/quic_record_tx.h
@@ -21,8 +21,22 @@
* QUIC Record Layer - TX
* ======================
*/
+typedef struct ossl_qtx_iovec_st {
+ const unsigned char *buf;
+ size_t buf_len;
+} OSSL_QTX_IOVEC;
+
typedef struct ossl_qtx_st OSSL_QTX;
+typedef int (*ossl_mutate_packet_cb)(const QUIC_PKT_HDR *hdrin,
+ const OSSL_QTX_IOVEC *iovecin, size_t numin,
+ QUIC_PKT_HDR **hdrout,
+ const OSSL_QTX_IOVEC **iovecout,
+ size_t *numout,
+ void *arg);
+
+typedef void (*ossl_finish_mutate_cb)(void *arg);
+
typedef struct ossl_qtx_args_st {
OSSL_LIB_CTX *libctx;
const char *propq;
@@ -40,6 +54,10 @@ OSSL_QTX *ossl_qtx_new(const OSSL_QTX_ARGS *args);
/* Frees the QTX. */
void ossl_qtx_free(OSSL_QTX *qtx);
+/* Set mutator callbacks for test framework support */
+void ossl_qtx_set_mutator(OSSL_QTX *qtx, ossl_mutate_packet_cb mutatecb,
+ ossl_finish_mutate_cb finishmutatecb, void *mutatearg);
+
/*
* Secret Management
* -----------------
@@ -114,10 +132,6 @@ uint32_t ossl_qrl_get_suite_cipher_tag_len(uint32_t suite_id);
* Packet Transmission
* -------------------
*/
-typedef struct ossl_qtx_iovec_st {
- const unsigned char *buf;
- size_t buf_len;
-} OSSL_QTX_IOVEC;
typedef struct ossl_qtx_pkt_st {
/* Logical packet header to be serialized. */
diff --git a/include/internal/quic_tserver.h b/include/internal/quic_tserver.h
index 438c68d20a..a19ec882ef 100644
--- a/include/internal/quic_tserver.h
+++ b/include/internal/quic_tserver.h
@@ -41,6 +41,12 @@ QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args,
void ossl_quic_tserver_free(QUIC_TSERVER *srv);
+/* Set mutator callbacks for test framework support */
+int ossl_quic_tserver_set_mutator(QUIC_TSERVER *srv,
+ ossl_mutate_packet_cb mutatecb,
+ ossl_finish_mutate_cb finishmutatecb,
+ void *mutatearg);
+
/* Advances the state machine. */
int ossl_quic_tserver_tick(QUIC_TSERVER *srv);
diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c
index bffd0d3244..6a0cc6d004 100644
--- a/ssl/quic/quic_channel.c
+++ b/ssl/quic/quic_channel.c
@@ -347,6 +347,19 @@ void ossl_quic_channel_free(QUIC_CHANNEL *ch)
OPENSSL_free(ch);
}
+/* Set mutator callbacks for test framework support */
+int ossl_quic_channel_set_mutator(QUIC_CHANNEL *ch,
+ ossl_mutate_packet_cb mutatecb,
+ ossl_finish_mutate_cb finishmutatecb,
+ void *mutatearg)
+{
+ if (ch->qtx == NULL)
+ return 0;
+
+ ossl_qtx_set_mutator(ch->qtx, mutatecb, finishmutatecb, mutatearg);
+ return 1;
+}
+
int ossl_quic_channel_get_peer_addr(QUIC_CHANNEL *ch, BIO_ADDR *peer_addr)
{
*peer_addr = ch->cur_peer_addr;
diff --git a/ssl/quic/quic_record_tx.c b/ssl/quic/quic_record_tx.c
index dddb29663c..28ebc436bb 100644
--- a/ssl/quic/quic_record_tx.c
+++ b/ssl/quic/quic_record_tx.c
@@ -90,6 +90,10 @@ struct ossl_qtx_st {
* confidentiality limit.
*/
uint64_t epoch_pkt_count;
+
+ ossl_mutate_packet_cb mutatecb;
+ ossl_finish_mutate_cb finishmutatecb;
+ void *mutatearg;
};
/* Instantiates a new QTX. */
@@ -141,6 +145,15 @@ void ossl_qtx_free(OSSL_QTX *qtx)
OPENSSL_free(qtx);
}
+/* Set mutator callbacks for test framework support */
+void ossl_qtx_set_mutator(OSSL_QTX *qtx, ossl_mutate_packet_cb mutatecb,
+ ossl_finish_mutate_cb finishmutatecb, void *mutatearg)
+{
+ qtx->mutatecb = mutatecb;
+ qtx->finishmutatecb = finishmutatecb;
+ qtx->mutatearg = mutatearg;
+}
+
int ossl_qtx_provide_secret(OSSL_QTX *qtx,
uint32_t enc_level,
uint32_t suite_id,
@@ -414,7 +427,7 @@ int ossl_qtx_calculate_plaintext_payload_len(OSSL_QTX *qtx, uint32_t enc_level,
*/
#define QTX_FAIL_INSUFFICIENT_LEN (-2)
-static int qtx_write_hdr(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe,
+static int qtx_write_hdr(OSSL_QTX *qtx, const QUIC_PKT_HDR *hdr, TXE *txe,
QUIC_PKT_HDR_PTRS *ptrs)
{
WPACKET wpkt;
@@ -424,8 +437,8 @@ static int qtx_write_hdr(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe,
txe->alloc_len - txe->data_len, 0))
return 0;
- if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, pkt->hdr->dst_conn_id.id_len,
- pkt->hdr, ptrs)
+ if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, hdr->dst_conn_id.id_len,
+ hdr, ptrs)
|| !WPACKET_get_total_written(&wpkt, &l)) {
WPACKET_finish(&wpkt);
return 0;
@@ -534,6 +547,9 @@ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe,
QUIC_PKT_HDR_PTRS ptrs;
unsigned char *hdr_start;
OSSL_QRL_ENC_LEVEL *el = NULL;
+ QUIC_PKT_HDR *hdr;
+ const OSSL_QTX_IOVEC *iovec;
+ size_t num_iovec;
/*
* Determine if the packet needs encryption and the minimum conceivable
@@ -558,8 +574,25 @@ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe,
goto err;
}
+ /* Set some fields in the header we are responsible for. */
+ if (pkt->hdr->type == QUIC_PKT_TYPE_1RTT)
+ pkt->hdr->key_phase = (unsigned char)(el->key_epoch & 1);
+
+ /* If we are running tests then mutate_packet may be non NULL */
+ if (qtx->mutatecb != NULL) {
+ if (!qtx->mutatecb(pkt->hdr, pkt->iovec, pkt->num_iovec, &hdr,
+ &iovec, &num_iovec, qtx->mutatearg)) {
+ ret = QTX_FAIL_GENERIC;
+ goto err;
+ }
+ } else {
+ hdr = pkt->hdr;
+ iovec = pkt->iovec;
+ num_iovec = pkt->num_iovec;
+ }
+
/* Walk the iovecs to determine actual input payload length. */
- iovec_cur_init(&cur, pkt->iovec, pkt->num_iovec);
+ iovec_cur_init(&cur, iovec, num_iovec);
if (cur.bytes_remaining == 0) {
/* No zero-length payloads allowed. */
@@ -573,10 +606,10 @@ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe,
: cur.bytes_remaining;
/* Determine header length. */
- pkt->hdr->data = NULL;
- pkt->hdr->len = payload_len;
- pred_hdr_len = ossl_quic_wire_get_encoded_pkt_hdr_len(pkt->hdr->dst_conn_id.id_len,
- pkt->hdr);
+ hdr->data = NULL;
+ hdr->len = payload_len;
+ pred_hdr_len = ossl_quic_wire_get_encoded_pkt_hdr_len(hdr->dst_conn_id.id_len,
+ hdr);
if (pred_hdr_len == 0) {
ret = QTX_FAIL_GENERIC;
goto err;
@@ -590,14 +623,10 @@ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe,
goto err;
}
- /* Set some fields in the header we are responsible for. */
- if (pkt->hdr->type == QUIC_PKT_TYPE_1RTT)
- pkt->hdr->key_phase = (unsigned char)(el->key_epoch & 1);
-
- if (ossl_quic_pkt_type_has_pn(pkt->hdr->type)) {
+ if (ossl_quic_pkt_type_has_pn(hdr->type)) {
if (!ossl_quic_wire_encode_pkt_hdr_pn(pkt->pn,
- pkt->hdr->pn,
- pkt->hdr->pn_len)) {
+ hdr->pn,
+ hdr->pn_len)) {
ret = QTX_FAIL_GENERIC;
goto err;
}
@@ -605,7 +634,7 @@ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe,
/* Append the header to the TXE. */
hdr_start = txe_data(txe) + txe->data_len;
- if (!qtx_write_hdr(qtx, pkt, txe, &ptrs)) {
+ if (!qtx_write_hdr(qtx, hdr, txe, &ptrs)) {
ret = QTX_FAIL_GENERIC;
goto err;
}
@@ -638,6 +667,8 @@ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe,
assert(txe->data_len - orig_data_len == pkt_len);
}
+ if (qtx->finishmutatecb != NULL)
+ qtx->finishmutatecb(qtx->mutatearg);
return 1;
err:
@@ -646,6 +677,8 @@ err:
* TXE.
*/
txe->data_len = orig_data_len;
+ if (qtx->finishmutatecb != NULL)
+ qtx->finishmutatecb(qtx->mutatearg);
return ret;
}
diff --git a/ssl/quic/quic_tserver.c b/ssl/quic/quic_tserver.c
index 5a03aa5327..2b5f04ac5a 100644
--- a/ssl/quic/quic_tserver.c
+++ b/ssl/quic/quic_tserver.c
@@ -122,6 +122,16 @@ void ossl_quic_tserver_free(QUIC_TSERVER *srv)
OPENSSL_free(srv);
}
+/* Set mutator callbacks for test framework support */
+int ossl_quic_tserver_set_mutator(QUIC_TSERVER *srv,
+ ossl_mutate_packet_cb mutatecb,
+ ossl_finish_mutate_cb finishmutatecb,
+ void *mutatearg)
+{
+ return ossl_quic_channel_set_mutator(srv->ch, mutatecb, finishmutatecb,
+ mutatearg);
+}
+
int ossl_quic_tserver_tick(QUIC_TSERVER *srv)
{
ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(srv->ch));