From: Matt Caswell Date: Tue, 10 Jan 2023 18:55:05 +0000 (+0000) Subject: Add the capability to listen for datagrams X-Git-Tag: openssl-3.2.0-alpha1~1250 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e4cb6583efa11decfa8d4d539c6cc2f08c99a067;p=thirdparty%2Fopenssl.git Add the capability to listen for datagrams Reviewed-by: Hugo Landau Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/20030) --- diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index 017ba54b5bf..423e50f29f1 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -46,6 +46,14 @@ struct ossl_quic_fault { /* Cipher packet mutations */ ossl_quic_fault_on_packet_cipher_cb pciphercb; void *pciphercbarg; + + /* Datagram mutations */ + ossl_quic_fault_on_datagram_cb datagramcb; + void *datagramcbarg; + /* The currently processed message */ + BIO_MSG msg; + /* Allocated size of msg data buffer */ + size_t msgalloc; }; static void packet_plain_finish(void *arg); @@ -546,18 +554,17 @@ static int pcipher_sendmmsg(BIO *b, BIO_MSG *msg, size_t stride, OSSL_QUIC_FAULT *fault; BIO *next = BIO_next(b); ossl_ssize_t ret = 0; - BIO_MSG m; size_t i = 0, tmpnump; QUIC_PKT_HDR hdr; PACKET pkt; - - m.data = NULL; + unsigned char *tmpdata; if (next == NULL) return 0; fault = BIO_get_data(b); - if (fault == NULL || fault->pciphercb == NULL) + if (fault == NULL + || (fault->pciphercb == NULL && fault->datagramcb == NULL)) return BIO_sendmmsg(next, msg, stride, num_msg, flags, num_processed); if (num_msg == 0) { @@ -566,35 +573,57 @@ static int pcipher_sendmmsg(BIO *b, BIO_MSG *msg, size_t stride, } for (i = 0; i < num_msg; ++i) { - m = BIO_MSG_N(msg, stride, i); + fault->msg = BIO_MSG_N(msg, stride, i); /* Take a copy of the data so that callbacks can modify it */ - m.data = OPENSSL_memdup(m.data, m.data_len); - if (m.data == NULL) - return 0; - - if (!PACKET_buf_init(&pkt, m.data, m.data_len)) + tmpdata = OPENSSL_malloc(fault->msg.data_len + GROWTH_ALLOWANCE); + if (tmpdata == NULL) return 0; + memcpy(tmpdata, fault->msg.data, fault->msg.data_len); + fault->msg.data = tmpdata; + fault->msgalloc = fault->msg.data_len + GROWTH_ALLOWANCE; + + if (fault->pciphercb != NULL) { + if (!PACKET_buf_init(&pkt, fault->msg.data, fault->msg.data_len)) + return 0; + + do { + if (!ossl_quic_wire_decode_pkt_hdr(&pkt, + 0 /* TODO(QUIC): Not sure how this should be set*/, 1, + &hdr, NULL)) + goto out; + + /* + * hdr.data is const - but its our buffer so casting away the + * const is safe + */ + if (!fault->pciphercb(fault, &hdr, (unsigned char *)hdr.data, + hdr.len, fault->pciphercbarg)) + goto out; + + /* + * TODO(QUIC): At the moment modifications to hdr by the callback + * are ignored. We might need to rewrite the QUIC header to + * enable tests to change this. We also don't yet have a + * mechanism for the callback to change the encrypted data + * length. It's not clear if that's needed or not. + */ + } while (PACKET_remaining(&pkt) > 0); + } - do { - if (!ossl_quic_wire_decode_pkt_hdr(&pkt, - 0/* TODO(QUIC): Not sure how this should be set*/, 1, &hdr, - NULL)) - goto out; - - /* TODO(QUIC): Resolve const issue here */ - if (!fault->pciphercb(fault, &hdr, (unsigned char *)hdr.data, - hdr.len, fault->pciphercbarg)) - goto out; - } while (PACKET_remaining(&pkt) > 0); + if (fault->datagramcb != NULL + && !fault->datagramcb(fault, &fault->msg, stride, + fault->datagramcbarg)) + goto out; - if (!BIO_sendmmsg(next, &m, stride, 1, flags, &tmpnump)) { + if (!BIO_sendmmsg(next, &fault->msg, stride, 1, flags, &tmpnump)) { *num_processed = i; goto out; } - OPENSSL_free(m.data); - m.data = NULL; + OPENSSL_free(fault->msg.data); + fault->msg.data = NULL; + fault->msgalloc = 0; } *num_processed = i; @@ -604,7 +633,8 @@ out: ret = 1; else ret = 0; - OPENSSL_free(m.data); + OPENSSL_free(fault->msg.data); + fault->msg.data = NULL; return ret; } @@ -649,4 +679,29 @@ int ossl_quic_fault_set_packet_cipher_listener(OSSL_QUIC_FAULT *fault, fault->pciphercbarg = pciphercbarg; return 1; -} \ No newline at end of file +} + +int ossl_quic_fault_set_datagram_listener(OSSL_QUIC_FAULT *fault, + ossl_quic_fault_on_datagram_cb datagramcb, + void *datagramcbarg) +{ + fault->datagramcb = datagramcb; + fault->datagramcbarg = datagramcbarg; + + return 1; +} + +/* To be called from a datagram_listener callback */ +int ossl_quic_fault_resize_datagram(OSSL_QUIC_FAULT *fault, size_t newlen) +{ + if (newlen > fault->msgalloc) + return 0; + + if (newlen > fault->msg.data_len) + memset((unsigned char *)fault->msg.data + fault->msg.data_len, 0, + newlen - fault->msg.data_len); + + fault->msg.data_len = newlen; + + return 1; +} diff --git a/test/helpers/quictestlib.h b/test/helpers/quictestlib.h index fb529b5c1a2..7cfbb6ce95f 100644 --- a/test/helpers/quictestlib.h +++ b/test/helpers/quictestlib.h @@ -149,3 +149,18 @@ typedef int (*ossl_quic_fault_on_packet_cipher_cb)(OSSL_QUIC_FAULT *fault, int ossl_quic_fault_set_packet_cipher_listener(OSSL_QUIC_FAULT *fault, ossl_quic_fault_on_packet_cipher_cb pciphercb, void *picphercbarg); + +/* + * Enable tests to listen for datagrams being sent + */ +typedef int (*ossl_quic_fault_on_datagram_cb)(OSSL_QUIC_FAULT *fault, + BIO_MSG *m, + size_t stride, + void *cbarg); + +int ossl_quic_fault_set_datagram_listener(OSSL_QUIC_FAULT *fault, + ossl_quic_fault_on_datagram_cb datagramcb, + void *datagramcbarg); + +/* To be called from a datagram_listener callback */ +int ossl_quic_fault_resize_datagram(OSSL_QUIC_FAULT *fault, size_t newlen);