diff options
author | Matt Caswell <matt@openssl.org> | 2024-01-16 13:53:30 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2024-01-31 10:10:55 +0000 |
commit | 5de8c49d6c019ad93149871989b755b5cc7b821c (patch) | |
tree | 6256b2110206f3df327d4981a45ea3adda5f0991 /test | |
parent | f7f2b665cf91650deb28beb1145ea3eca7df67aa (diff) |
Extend the testing of resetting/clearing an SSL connection
SSL_clear() explicitly clears an SSL object to enable it to be reused.
You can have a similar effect by calling SSL_set_accept_state() or
SSL_set_connect_state(). We extend the testing of SSL_clear() to use these
other methods. We also ensure we test the case where we have unread
bufferred data that needs to be cleared.
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23256)
Diffstat (limited to 'test')
-rw-r--r-- | test/sslapitest.c | 91 |
1 files changed, 81 insertions, 10 deletions
diff --git a/test/sslapitest.c b/test/sslapitest.c index b8c474d524..6ef64740db 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -7035,22 +7035,45 @@ static int test_key_update_local_in_read(int tst) } #endif /* OSSL_NO_USABLE_TLS1_3 */ +/* + * Test clearing a connection via SSL_clear(), or resetting it via + * SSL_set_connect_state()/SSL_set_accept_state() + * Test 0: SSL_set_connect_state, TLSv1.3 + * Test 1: SSL_set_connect_state, TLSv1.2 + * Test 2: SSL_set_accept_state, TLSv1.3 + * Test 3: SSL_set_accept_state, TLSv1.2 + * Test 4: SSL_clear (client), TLSv1.3 + * Test 5: SSL_clear (client), TLSv1.2 + * Test 6: SSL_clear (server), TLSv1.3 + * Test 7: SSL_clear (server), TLSv1.2 + */ static int test_ssl_clear(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; + SSL *writer, *reader; int testresult = 0; + int tls12test, servertest, cleartest; + size_t written, readbytes; + const char *msg = "Hello World"; + unsigned char buf[5]; + + tls12test = idx & 1; + idx >>= 1; + servertest = idx & 1; + idx >>= 1; + cleartest = idx & 1; #ifdef OPENSSL_NO_TLS1_2 - if (idx == 1) - return 1; + if (tls12test == 1) + return TEST_skip("No TLSv1.2 in this build"); #endif /* Create an initial connection */ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), TLS1_VERSION, 0, &sctx, &cctx, cert, privkey)) - || (idx == 1 + || (tls12test && !TEST_true(SSL_CTX_set_max_proto_version(cctx, TLS1_2_VERSION))) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, @@ -7059,20 +7082,68 @@ static int test_ssl_clear(int idx) SSL_ERROR_NONE))) goto end; + if (servertest) { + writer = clientssl; + reader = serverssl; + } else { + writer = serverssl; + reader = clientssl; + } + + /* Write some data */ + if (!TEST_true(SSL_write_ex(writer, msg, strlen(msg), &written)) + || written != strlen(msg)) + goto end; + + /* + * Read a partial record. The remaining buffered data should be cleared by + * the subsequent clear/reset + */ + if (!TEST_true(SSL_read_ex(reader, buf, sizeof(buf), &readbytes)) + || readbytes != sizeof(buf)) + goto end; + SSL_shutdown(clientssl); SSL_shutdown(serverssl); - SSL_free(serverssl); - serverssl = NULL; - /* Clear clientssl - we're going to reuse the object */ - if (!TEST_true(SSL_clear(clientssl))) - goto end; + /* Reset/clear one SSL object in order to reuse it. We free the other one */ + if (servertest) { + if (cleartest) { + if (!TEST_true(SSL_clear(serverssl))) + goto end; + } else { + SSL_set_accept_state(serverssl); + } + /* + * A peculiarity of SSL_clear() is that it does not clear the session. + * This is intended behaviour so that a client can create a new + * connection and reuse the session. But this doesn't make much sense + * on the server side - and causes incorrect behaviour due to the + * handshake failing (even though the documentation does say SSL_clear() + * is supposed to work on the server side). We clear the session + * explicitly - although note that the documentation for + * SSL_set_session() says that its only useful for clients! + */ + if (!TEST_true(SSL_set_session(serverssl, NULL))) + goto end; + SSL_free(clientssl); + clientssl = NULL; + } else { + if (cleartest) { + if (!TEST_true(SSL_clear(clientssl))) + goto end; + } else { + SSL_set_connect_state(clientssl); + } + SSL_free(serverssl); + serverssl = NULL; + } if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) || !TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) - || !TEST_true(SSL_session_reused(clientssl))) + || !TEST_true(servertest || SSL_session_reused(clientssl))) goto end; SSL_shutdown(clientssl); @@ -11637,7 +11708,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_key_update_local_in_write, 2); ADD_ALL_TESTS(test_key_update_local_in_read, 2); #endif - ADD_ALL_TESTS(test_ssl_clear, 2); + ADD_ALL_TESTS(test_ssl_clear, 8); ADD_ALL_TESTS(test_max_fragment_len_ext, OSSL_NELEM(max_fragment_len_test)); #if !defined(OPENSSL_NO_SRP) && !defined(OPENSSL_NO_TLS1_2) ADD_ALL_TESTS(test_srp, 6); |