mirror of
https://github.com/openssl/openssl.git
synced 2025-03-31 20:10:45 +08:00
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)
This commit is contained in:
parent
f7f2b665cf
commit
5de8c49d6c
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user