From: Hugo Landau Date: Mon, 6 Mar 2023 17:58:32 +0000 (+0000) Subject: QUIC: Add support for datagram injection X-Git-Tag: openssl-3.2.0-alpha1~1118 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=553a4e00aab3e2cc04f47678cba3cd8345e7b0e3;p=thirdparty%2Fopenssl.git QUIC: Add support for datagram injection Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/20451) --- diff --git a/doc/man3/SSL_inject_net_dgram.pod b/doc/man3/SSL_inject_net_dgram.pod new file mode 100644 index 00000000000..01714accb00 --- /dev/null +++ b/doc/man3/SSL_inject_net_dgram.pod @@ -0,0 +1,51 @@ +=pod + +=head1 NAME + +SSL_inject_net_dgram - inject a datagram as though received from the network + +=head1 SYNOPSIS + + #include + + int SSL_inject_net_dgram(SSL *s, const unsigned char *buf, + size_t buf_len, + const BIO_ADDR *peer, + const BIO_ADDR *local); + +=head1 DESCRIPTION + +This function can be used to inject a datagram payload to a QUIC connection SSL +object. The payload is processed as though it was received from the network. +This function can be used for debugging purposes or to allow datagrams to be fed +to QUIC from alternative sources. + +I is required and must point to a datagram payload to inject. I is +the length of the buffer in bytes. The buffer is copied and need not remain +valid after this function returns. + +I and I are optional values pointing to B structures +describing the remote and local UDP endpoint addresses for the packet. Though +the injected packet was not actually received from the network directly by +OpenSSL, the packet will be processed as though the received datagram had the +given addresses. + +=head1 RETURN VALUES + +Returns 1 on success or 0 on failure. This function always fails if called +on a SSL object which is not a QUIC connection SSL object. + +=head1 SEE ALSO + +L, L, L + +=head1 COPYRIGHT + +Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/include/internal/quic_channel.h b/include/internal/quic_channel.h index 29682ff72f5..f08252d1f9e 100644 --- a/include/internal/quic_channel.h +++ b/include/internal/quic_channel.h @@ -194,6 +194,8 @@ int ossl_quic_channel_is_active(const QUIC_CHANNEL *ch); int ossl_quic_channel_is_handshake_complete(const QUIC_CHANNEL *ch); int ossl_quic_channel_is_handshake_confirmed(const QUIC_CHANNEL *ch); +QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch); + SSL *ossl_quic_channel_get0_ssl(QUIC_CHANNEL *ch); # endif diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in index b669cec8883..a50378f27dd 100644 --- a/include/openssl/ssl.h.in +++ b/include/openssl/ssl.h.in @@ -2257,6 +2257,12 @@ __owur int SSL_net_write_desired(SSL *s); __owur int SSL_set_blocking_mode(SSL *s, int blocking); __owur int SSL_get_blocking_mode(SSL *s); __owur int SSL_set_initial_peer_addr(SSL *s, const BIO_ADDR *peer_addr); +# ifndef OPENSSL_NO_QUIC +__owur int SSL_inject_net_dgram(SSL *s, const unsigned char *buf, + size_t buf_len, + const BIO_ADDR *peer, + const BIO_ADDR *local); +# endif typedef struct ssl_shutdown_ex_args_st { uint64_t quic_error_code; diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index 984ee871b2f..86eed313ab4 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -438,6 +438,11 @@ int ossl_quic_channel_is_handshake_confirmed(const QUIC_CHANNEL *ch) return ch->handshake_confirmed; } +QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch) +{ + return ch->demux; +} + /* * QUIC Channel: Callbacks from Miscellaneous Subsidiary Components * ================================================================ diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index 12099043ff7..436d2efc03a 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -1244,6 +1244,29 @@ int ossl_quic_conn_stream_conclude(QUIC_CONNECTION *qc) return 1; } +/* + * SSL_inject_net_dgram + * -------------------- + */ +int SSL_inject_net_dgram(SSL *s, const unsigned char *buf, + size_t buf_len, + const BIO_ADDR *peer, + const BIO_ADDR *local) +{ + QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s); + QUIC_DEMUX *demux; + + if (!expect_quic_conn(qc)) + return 0; + + if (qc->ch == NULL) + return QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, + NULL); + + demux = ossl_quic_channel_get0_demux(qc->ch); + return ossl_quic_demux_inject(demux, buf, buf_len, peer, local); +} + /* * QUIC Front-End I/O API: SSL_CTX Management * ========================================== diff --git a/util/libssl.num b/util/libssl.num index 0c5e2f5d59a..f697f31114a 100644 --- a/util/libssl.num +++ b/util/libssl.num @@ -543,3 +543,4 @@ SSL_net_read_desired ? 3_2_0 EXIST::FUNCTION: SSL_net_write_desired ? 3_2_0 EXIST::FUNCTION: SSL_shutdown_ex ? 3_2_0 EXIST::FUNCTION: SSL_stream_conclude ? 3_2_0 EXIST::FUNCTION: +SSL_inject_net_dgram ? 3_2_0 EXIST::FUNCTION:QUIC