Skip to content

Commit

Permalink
QUIC SSL: SSL_set_fd for BIO_s_datagram
Browse files Browse the repository at this point in the history
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from #20061)
  • Loading branch information
hlandau authored and paulidale committed Jul 4, 2023
1 parent a1c56bb commit 5e6015a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 5 deletions.
3 changes: 3 additions & 0 deletions doc/man3/SSL_set_fd.pod
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down
12 changes: 7 additions & 5 deletions ssl/ssl_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down
57 changes: 57 additions & 0 deletions test/quicapitest.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,62 @@ static int test_quic_forbidden_options(void)
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)
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 5e6015a

Please sign in to comment.