diff options
author | Matt Caswell <matt@openssl.org> | 2022-10-31 14:23:18 +0000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2022-11-14 10:14:49 +0100 |
commit | cbf965b4f3ba8567624767239aebe4d04c62558a (patch) | |
tree | 0f0313559a9f8b204dceae0feb1471379588e1b8 /test | |
parent | 732435026b0141063084fb68c076bc1c9fd9bee8 (diff) |
Test SSL_shutdown() with async writes
As well as SSL_shutdown() itself this excercises the async write paths
in ssl3_dispatch_alert().
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19550)
Diffstat (limited to 'test')
-rw-r--r-- | test/sslapitest.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/test/sslapitest.c b/test/sslapitest.c index 57ff080dd5..8f14381b56 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -8148,6 +8148,82 @@ static int test_shutdown(int tst) return testresult; } +/* + * Test that sending close_notify alerts works correctly in the case of a + * retryable write failure. + */ +static int test_async_shutdown(void) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + BIO *bretry = BIO_new(bio_s_always_retry()), *tmp = NULL; + + if (!TEST_ptr(bretry)) + goto end; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, + NULL))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* Close write side of clientssl */ + if (!TEST_int_eq(SSL_shutdown(clientssl), 0)) + goto end; + + tmp = SSL_get_wbio(serverssl); + if (!TEST_true(BIO_up_ref(tmp))) { + tmp = NULL; + goto end; + } + SSL_set0_wbio(serverssl, bretry); + bretry = NULL; + + /* First server shutdown should fail because of a retrable write failure */ + if (!TEST_int_eq(SSL_shutdown(serverssl), -1) + || !TEST_int_eq(SSL_get_error(serverssl, -1), SSL_ERROR_WANT_WRITE)) + goto end; + + /* Second server shutdown should fail for the same reason */ + if (!TEST_int_eq(SSL_shutdown(serverssl), -1) + || !TEST_int_eq(SSL_get_error(serverssl, -1), SSL_ERROR_WANT_WRITE)) + goto end; + + SSL_set0_wbio(serverssl, tmp); + tmp = NULL; + + /* Third server shutdown should send close_notify */ + if (!TEST_int_eq(SSL_shutdown(serverssl), 0)) + goto end; + + /* Fourth server shutdown should read close_notify from client and finish */ + if (!TEST_int_eq(SSL_shutdown(serverssl), 1)) + goto end; + + /* Client should also successfully fully shutdown */ + if (!TEST_int_eq(SSL_shutdown(clientssl), 1)) + goto end; + + testresult = 1; + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + BIO_free(bretry); + BIO_free(tmp); + + return testresult; +} + #if !defined(OPENSSL_NO_TLS1_2) || !defined(OSSL_NO_USABLE_TLS1_3) static int cert_cb_cnt; @@ -10580,6 +10656,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_ssl_get_shared_ciphers, OSSL_NELEM(shared_ciphers_data)); ADD_ALL_TESTS(test_ticket_callbacks, 20); ADD_ALL_TESTS(test_shutdown, 7); + ADD_TEST(test_async_shutdown); ADD_ALL_TESTS(test_incorrect_shutdown, 2); ADD_ALL_TESTS(test_cert_cb, 6); ADD_ALL_TESTS(test_client_cert_cb, 2); |