Add the capability to listen for datagrams

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20030)
This commit is contained in:
Matt Caswell 2023-01-10 18:55:05 +00:00 committed by Hugo Landau
parent ce8f20b6ae
commit e4cb6583ef
2 changed files with 94 additions and 24 deletions

View File

@ -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)
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 (!PACKET_buf_init(&pkt, m.data, m.data_len))
return 0;
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;
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);
/*
* 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;
if (!BIO_sendmmsg(next, &m, stride, 1, flags, &tmpnump)) {
/*
* 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);
}
if (fault->datagramcb != NULL
&& !fault->datagramcb(fault, &fault->msg, stride,
fault->datagramcbarg))
goto out;
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;
}
}
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;
}

View File

@ -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);