提交 c748834f 编写于 作者: M Matt Caswell

Add a bi-directional shutdown test

Reviewed-by: NBernd Edlinger <bernd.edlinger@hotmail.de>
Reviewed-by: NKurt Roeckx <kurt@roeckx.be>
(Merged from https://github.com/openssl/openssl/pull/6340)
上级 93f528f3
......@@ -4972,6 +4972,128 @@ static int test_ticket_callbacks(int tst)
return testresult;
}
/*
* Test bi-directional shutdown.
* Test 0: TLSv1.2
* Test 1: TLSv1.2, server continues to read/write after client shutdown
* Test 2: TLSv1.3, no pending NewSessionTicket messages
* Test 3: TLSv1.3, pending NewSessionTicket messages
* Test 4: TLSv1.3, server continues to read/write after client shutdown, client
* reads it
* Test 5: TLSv1.3, server continues to read/write after client shutdown, client
* doesn't read it
*/
static int test_shutdown(int tst)
{
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *clientssl = NULL, *serverssl = NULL;
int testresult = 0;
char msg[] = "A test message";
char buf[80];
size_t written, readbytes;
#ifdef OPENSSL_NO_TLS1_2
if (tst == 0)
return 1;
#endif
#ifdef OPENSSL_NO_TLS1_3
if (tst != 0)
return 1;
#endif
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
TLS_client_method(),
TLS1_VERSION,
(tst <= 1) ? TLS1_2_VERSION
: TLS1_3_VERSION,
&sctx, &cctx, cert, privkey))
|| !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
NULL, NULL)))
goto end;
if (tst == 3) {
if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl,
SSL_ERROR_NONE)))
goto end;
} else if (!TEST_true(create_ssl_connection(serverssl, clientssl,
SSL_ERROR_NONE))) {
goto end;
}
if (!TEST_int_eq(SSL_shutdown(clientssl), 0))
goto end;
if (tst >= 4) {
/*
* Reading on the server after the client has sent close_notify should
* fail and provide SSL_ERROR_ZERO_RETURN
*/
if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
|| !TEST_int_eq(SSL_get_error(serverssl, 0),
SSL_ERROR_ZERO_RETURN)
|| !TEST_int_eq(SSL_get_shutdown(serverssl),
SSL_RECEIVED_SHUTDOWN)
/*
* Even though we're shutdown on receive we should still be
* able to write.
*/
|| !TEST_true(SSL_write(serverssl, msg, sizeof(msg)))
|| !TEST_int_eq(SSL_shutdown(serverssl), 1))
goto end;
if (tst == 4) {
/* Should still be able to read data from server */
if (!TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf),
&readbytes))
|| !TEST_size_t_eq(readbytes, sizeof(msg))
|| !TEST_int_eq(memcmp(msg, buf, readbytes), 0))
goto end;
}
}
/* Writing on the client after sending close_notify shouldn't be possible */
if (!TEST_false(SSL_write_ex(clientssl, msg, sizeof(msg), &written))
/*
* Writing on the server after sending close_notify shouldn't be
* possible.
*/
|| !TEST_false(SSL_write_ex(clientssl, msg, sizeof(msg), &written)))
goto end;
if (tst < 4) {
/*
* For these tests the client has sent close_notify but it has not yet
* been received by the server. The server has not sent close_notify
* yet.
*/
if (!TEST_int_eq(SSL_shutdown(serverssl), 0)
|| !TEST_int_eq(SSL_shutdown(clientssl), 1)
|| !TEST_int_eq(SSL_shutdown(serverssl), 1))
goto end;
} else {
/*
* In this test the client has sent close_notify and it has been
* received by the server which has responded with a close_notify. The
* client needs to read the close_notify sent by the server. When
* tst == 5, there is application data to be read first but this is
* discarded with a -1 return value.
*/
if (tst == 5 && !TEST_int_eq(SSL_shutdown(clientssl), -1))
goto end;
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);
return testresult;
}
int setup_tests(void)
{
if (!TEST_ptr(cert = test_get_argument(0))
......@@ -5069,6 +5191,7 @@ int setup_tests(void)
ADD_ALL_TESTS(test_ssl_pending, 2);
ADD_ALL_TESTS(test_ssl_get_shared_ciphers, OSSL_NELEM(shared_ciphers_data));
ADD_ALL_TESTS(test_ticket_callbacks, 12);
ADD_ALL_TESTS(test_shutdown, 6);
return 1;
}
......
......@@ -680,12 +680,14 @@ int create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
return 0;
}
int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want)
/*
* Create an SSL connection, but does not ready any post-handshake
* NewSessionTicket messages.
*/
int create_bare_ssl_connection(SSL *serverssl, SSL *clientssl, int want)
{
int retc = -1, rets = -1, err, abortctr = 0, i;
int retc = -1, rets = -1, err, abortctr = 0;
int clienterr = 0, servererr = 0;
unsigned char buf;
size_t readbytes;
int isdtls = SSL_is_dtls(serverssl);
do {
......@@ -738,6 +740,22 @@ int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want)
}
} while (retc <=0 || rets <= 0);
return 1;
}
/*
* Create an SSL connection including any post handshake NewSessionTicket
* messages.
*/
int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want)
{
int i;
unsigned char buf;
size_t readbytes;
if (!create_bare_ssl_connection(serverssl, clientssl, want))
return 0;
/*
* We attempt to read some data on the client side which we expect to fail.
* This will ensure we have received the NewSessionTicket in TLSv1.3 where
......
......@@ -18,6 +18,7 @@ int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
char *privkeyfile);
int create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
SSL **cssl, BIO *s_to_c_fbio, BIO *c_to_s_fbio);
int create_bare_ssl_connection(SSL *serverssl, SSL *clientssl, int want);
int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want);
void shutdown_ssl_connection(SSL *serverssl, SSL *clientssl);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册