diff options
-rw-r--r-- | include/internal/quic_channel.h | 6 | ||||
-rw-r--r-- | include/internal/quic_record_tx.h | 22 | ||||
-rw-r--r-- | include/internal/quic_tserver.h | 6 | ||||
-rw-r--r-- | ssl/quic/quic_channel.c | 13 | ||||
-rw-r--r-- | ssl/quic/quic_record_tx.c | 65 | ||||
-rw-r--r-- | ssl/quic/quic_tserver.c | 10 |
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)); |