Loading test/sslapitest.c +123 −0 Original line number Diff line number Diff line Loading @@ -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)) Loading Loading @@ -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; } Loading test/ssltestlib.c +22 −4 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 Loading test/ssltestlib.h +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
test/sslapitest.c +123 −0 Original line number Diff line number Diff line Loading @@ -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)) Loading Loading @@ -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; } Loading
test/ssltestlib.c +22 −4 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 Loading
test/ssltestlib.h +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading