QUIC SSL: SSL_set_fd for BIO_s_datagram

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20061)
This commit is contained in:
Hugo Landau 2023-01-16 15:29:16 +00:00 committed by Pauli
parent a1c56bbe79
commit 5e6015af4d
3 changed files with 67 additions and 5 deletions

View File

@ -23,6 +23,9 @@ interface between the B<ssl> and B<fd>. The BIO and hence the SSL engine
inherit the behaviour of B<fd>. If B<fd> is nonblocking, the B<ssl> will
also have nonblocking behaviour.
When used on a QUIC SSL object, a B<datagram BIO> is automatically created
instead of a B<socket BIO>.
If there was already a BIO connected to B<ssl>, BIO_free() will be called
(for both the reading and writing side, if different).

View File

@ -1662,7 +1662,7 @@ int SSL_set_fd(SSL *s, int fd)
int ret = 0;
BIO *bio = NULL;
bio = BIO_new(BIO_s_socket());
bio = BIO_new(IS_QUIC_SSL(s) ? BIO_s_datagram() : BIO_s_socket());
if (bio == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
@ -1687,10 +1687,11 @@ int SSL_set_fd(SSL *s, int fd)
int SSL_set_wfd(SSL *s, int fd)
{
BIO *rbio = SSL_get_rbio(s);
int desired_type = IS_QUIC_SSL(s) ? BIO_TYPE_DGRAM : BIO_TYPE_SOCKET;
if (rbio == NULL || BIO_method_type(rbio) != BIO_TYPE_SOCKET
if (rbio == NULL || BIO_method_type(rbio) != desired_type
|| (int)BIO_get_fd(rbio, NULL) != fd) {
BIO *bio = BIO_new(BIO_s_socket());
BIO *bio = BIO_new(IS_QUIC_SSL(s) ? BIO_s_datagram() : BIO_s_socket());
if (bio == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
@ -1717,10 +1718,11 @@ int SSL_set_wfd(SSL *s, int fd)
int SSL_set_rfd(SSL *s, int fd)
{
BIO *wbio = SSL_get_wbio(s);
int desired_type = IS_QUIC_SSL(s) ? BIO_TYPE_DGRAM : BIO_TYPE_SOCKET;
if (wbio == NULL || BIO_method_type(wbio) != BIO_TYPE_SOCKET
if (wbio == NULL || BIO_method_type(wbio) != desired_type
|| ((int)BIO_get_fd(wbio, NULL) != fd)) {
BIO *bio = BIO_new(BIO_s_socket());
BIO *bio = BIO_new(IS_QUIC_SSL(s) ? BIO_s_datagram() : BIO_s_socket());
if (bio == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);

View File

@ -505,6 +505,62 @@ err:
return testresult;
}
static int test_quic_set_fd(int idx)
{
int testresult = 0;
SSL_CTX *ctx = NULL;
SSL *ssl = NULL;
int fd = -1, resfd = -1;
BIO *bio = NULL;
if (!TEST_ptr(ctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method())))
goto err;
if (!TEST_ptr(ssl = SSL_new(ctx)))
goto err;
if (!TEST_int_ge(fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0), 0))
goto err;
if (idx == 0) {
if (!TEST_true(SSL_set_fd(ssl, fd)))
goto err;
if (!TEST_ptr(bio = SSL_get_rbio(ssl)))
goto err;
if (!TEST_ptr_eq(bio, SSL_get_wbio(ssl)))
goto err;
} else if (idx == 1) {
if (!TEST_true(SSL_set_rfd(ssl, fd)))
goto err;
if (!TEST_ptr(bio = SSL_get_rbio(ssl)))
goto err;
if (!TEST_ptr_null(SSL_get_wbio(ssl)))
goto err;
} else {
if (!TEST_true(SSL_set_wfd(ssl, fd)))
goto err;
if (!TEST_ptr(bio = SSL_get_wbio(ssl)))
goto err;
if (!TEST_ptr_null(SSL_get_rbio(ssl)))
goto err;
}
if (!TEST_int_eq(BIO_method_type(bio), BIO_TYPE_DGRAM))
goto err;
if (!TEST_true(BIO_get_fd(bio, &resfd))
|| !TEST_int_eq(resfd, fd))
goto err;
testresult = 1;
err:
SSL_free(ssl);
SSL_CTX_free(ctx);
if (fd >= 0)
BIO_closesocket(fd);
return testresult;
}
OPT_TEST_DECLARE_USAGE("provider config certsdir datadir\n")
int setup_tests(void)
@ -569,6 +625,7 @@ int setup_tests(void)
ADD_TEST(test_quic_forbidden_apis_ctx);
ADD_TEST(test_quic_forbidden_apis);
ADD_TEST(test_quic_forbidden_options);
ADD_ALL_TESTS(test_quic_set_fd, 3);
return 1;
err:
cleanup_tests();