diff options
author | Matt Caswell <matt@openssl.org> | 2023-10-23 12:16:44 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2023-10-24 17:37:19 +0100 |
commit | dbbdb940d421daca4a65e765b5244bde6aed3f61 (patch) | |
tree | 4fd346b4aeb4567efabb382f3a91bef609c1d643 /test/sslapitest.c | |
parent | b9b9f4886f87abd39535721243d4297fd45e558a (diff) | |
download | openssl-dbbdb940d421daca4a65e765b5244bde6aed3f61.tar.gz |
Add a test for retries when sending app data
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22473)
Diffstat (limited to 'test/sslapitest.c')
-rw-r--r-- | test/sslapitest.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/test/sslapitest.c b/test/sslapitest.c index 9539b4cf3a..2fbe76f979 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -11138,6 +11138,102 @@ end: return testresult; } +/* + * Test that receiving retries when writing application data works as expected + */ +static int test_data_retry(void) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + unsigned char inbuf[1200], outbuf[1200]; + size_t i; + BIO *tmp = NULL; + BIO *bretry = BIO_new(bio_s_maybe_retry()); + size_t written, readbytes, totread = 0; + + if (!TEST_ptr(bretry)) + goto end; + + for (i = 0; i < sizeof(inbuf); i++) + inbuf[i] = i; + memset(outbuf, 0, sizeof(outbuf)); + + 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; + + /* Smallest possible max send fragment is 512 */ + if (!TEST_true(SSL_set_max_send_fragment(clientssl, 512))) + goto end; + + tmp = SSL_get_wbio(clientssl); + if (!TEST_ptr(tmp)) + goto end; + if (!TEST_true(BIO_up_ref(tmp))) + goto end; + BIO_push(bretry, tmp); + tmp = NULL; + SSL_set0_wbio(clientssl, bretry); + if (!BIO_up_ref(bretry)) { + bretry = NULL; + goto end; + } + + for (i = 0; i < 3; i++) { + /* We expect this call to make no progress and indicate retry */ + if (!TEST_false(SSL_write_ex(clientssl, inbuf, sizeof(inbuf), &written))) + goto end; + if (!TEST_int_eq(SSL_get_error(clientssl, 0), SSL_ERROR_WANT_WRITE)) + goto end; + + /* Allow one write to progess, but the next one to signal retry */ + if (!TEST_true(BIO_ctrl(bretry, MAYBE_RETRY_CTRL_SET_RETRY_AFTER_CNT, 1, + NULL))) + goto end; + + if (i == 2) + break; + + /* + * This call will hopefully make progress but will still indicate retry + * because there is more data than will fit into a single record. + */ + if (!TEST_false(SSL_write_ex(clientssl, inbuf, sizeof(inbuf), &written))) + goto end; + if (!TEST_int_eq(SSL_get_error(clientssl, 0), SSL_ERROR_WANT_WRITE)) + goto end; + } + + /* The final call should write the last chunk of data and succeed */ + if (!TEST_true(SSL_write_ex(clientssl, inbuf, sizeof(inbuf), &written))) + goto end; + /* Read all the data available */ + while (SSL_read_ex(serverssl, outbuf + totread, sizeof(outbuf) - totread, + &readbytes)) + totread += readbytes; + if (!TEST_mem_eq(inbuf, sizeof(inbuf), outbuf, totread)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + BIO_free_all(bretry); + BIO_free(tmp); + return testresult; +} + OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n") int setup_tests(void) @@ -11444,6 +11540,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_version, 6); ADD_TEST(test_rstate_string); ADD_ALL_TESTS(test_handshake_retry, 16); + ADD_TEST(test_data_retry); return 1; err: @@ -11473,6 +11570,7 @@ void cleanup_tests(void) OPENSSL_free(privkey8192); bio_s_mempacket_test_free(); bio_s_always_retry_free(); + bio_s_maybe_retry_free(); OSSL_PROVIDER_unload(defctxnull); OSSL_LIB_CTX_free(libctx); } |