From: Hugo Landau Date: Mon, 16 Jan 2023 15:29:16 +0000 (+0000) Subject: QUIC SSL: SSL_set_fd for BIO_s_datagram X-Git-Tag: openssl-3.2.0-alpha1~520 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e6015af4df7c4b3ef2e6c3c2f3657bafde88805;p=thirdparty%2Fopenssl.git QUIC SSL: SSL_set_fd for BIO_s_datagram Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/20061) --- diff --git a/doc/man3/SSL_set_fd.pod b/doc/man3/SSL_set_fd.pod index f519630752a..6e0ab578e67 100644 --- a/doc/man3/SSL_set_fd.pod +++ b/doc/man3/SSL_set_fd.pod @@ -23,6 +23,9 @@ interface between the B and B. The BIO and hence the SSL engine inherit the behaviour of B. If B is nonblocking, the B will also have nonblocking behaviour. +When used on a QUIC SSL object, a B is automatically created +instead of a B. + If there was already a BIO connected to B, BIO_free() will be called (for both the reading and writing side, if different). diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 97a95ce4b99..d6edc5be165 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -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); diff --git a/test/quicapitest.c b/test/quicapitest.c index 1205e968da6..2784f981983 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -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();