From 2e48de1728d97eb9e6c00d590416448f0afeb23b Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Tue, 30 Apr 2024 19:36:13 +0000 Subject: [PATCH 01/28] send zero-length NST when session key is expired --- tests/unit/s2n_session_ticket_test.c | 67 ++++++++++++++++++++++++++++ tls/s2n_server_new_session_ticket.c | 6 ++- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 5c9fdb42fb2..d5f7343a5b8 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1348,6 +1348,73 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_free(config)); } + /* Test TLS 1.2 Server sends zero-length ticket in the NewSessionTicket handshake + * if the ticket key was expired after SERVER_HELLO + */ + { + /* Initialize client and server configurations with TLS 1.2 */ + DEFER_CLEANUP(struct s2n_config *client_configuration = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_NOT_NULL(client_configuration); + EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(client_configuration, 1)); + EXPECT_SUCCESS(s2n_config_set_cipher_preferences(client_configuration, "default")); + EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(client_configuration)); + + DEFER_CLEANUP(struct s2n_config *server_configuration = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_NOT_NULL(server_configuration); + EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(server_configuration, 1)); + EXPECT_SUCCESS(s2n_config_set_cipher_preferences(server_configuration, "default")); + EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(server_configuration)); + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_configuration, + chain_and_key)); + + EXPECT_SUCCESS(s2n_config_add_ticket_crypto_key(server_configuration, ticket_key_name1, + s2n_array_len(ticket_key_name1), ticket_key1, s2n_array_len(ticket_key1), 0)); + + /* Initialize client and server connections*/ + DEFER_CLEANUP(struct s2n_connection *client_connection = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client_connection); + EXPECT_SUCCESS(s2n_connection_set_session(client_connection, serialized_session_state, + serialized_session_state_length)); + EXPECT_SUCCESS(s2n_connection_set_config(client_connection, client_configuration)); + DEFER_CLEANUP(struct s2n_connection *server_connection = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_connection); + EXPECT_SUCCESS(s2n_connection_set_config(server_connection, server_configuration)); + + /* Create nonblocking pipes */ + DEFER_CLEANUP(struct s2n_test_io_stuffer_pair input_output_pair = { 0 }, + s2n_io_stuffer_pair_free); + EXPECT_OK(s2n_io_stuffer_pair_init(&input_output_pair)); + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client_connection, server_connection, + &input_output_pair)); + + /* Negotiate until session ticket is encrypted with session ticket key */ + EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server_connection, + client_connection, CLIENT_FINISHED)); + + /* After session ticket is encrypted, expire current session ticket key */ + uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; + EXPECT_SUCCESS(s2n_config_set_wall_clock(server_configuration, mock_nanoseconds_since_epoch, + &mock_delay)); + + /* Try to send a NewSessionTicket. This should send a zero-length NST message */ + EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server_connection, + client_connection, SERVER_FINISHED)); + + /* Verify that TLS1.2 was negotiated */ + EXPECT_EQUAL(client_connection->actual_protocol_version, S2N_TLS12); + EXPECT_EQUAL(server_connection->actual_protocol_version, S2N_TLS12); + + /* Verify that the server did issue a new session ticket */ + EXPECT_TRUE(IS_ISSUING_NEW_SESSION_TICKET(server_connection)); + + /* Verify that the client received a zero-length NewSessionTicket message */ + EXPECT_EQUAL(client_connection->client_ticket.allocated, 0); + } + EXPECT_SUCCESS(s2n_io_pair_close(&io_pair)); EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); EXPECT_SUCCESS(s2n_cert_chain_and_key_free(ecdsa_chain_and_key)); diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index db40ea5a8b4..1d09bb3eeb6 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -82,8 +82,10 @@ int s2n_server_nst_send(struct s2n_connection *conn) uint32_t lifetime_hint_in_secs = (conn->config->encrypt_decrypt_key_lifetime_in_nanos + conn->config->decrypt_key_lifetime_in_nanos) / ONE_SEC_IN_NANOS; - /* When server changes it's mind mid handshake send lifetime hint and session ticket length as zero */ - if (!conn->config->use_tickets) { + /* When server changes it's mind mid handshake, or when session key is expired, + * send lifetime hint and session ticket length as zero + */ + if (!conn->config->use_tickets || !s2n_config_is_encrypt_decrypt_key_available(conn->config)) { POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0)); POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0)); From becb306cf2c8bcb6719ef6a057c369afbb1b490e Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Tue, 30 Apr 2024 21:23:15 +0000 Subject: [PATCH 02/28] add another to test the impact on tls 1.3 path --- tests/unit/s2n_session_ticket_test.c | 66 +++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index d5f7343a5b8..1c50b267630 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1348,7 +1348,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_free(config)); } - /* Test TLS 1.2 Server sends zero-length ticket in the NewSessionTicket handshake + /* Test TLS 1.2 Server sends a zero-length ticket in the NewSessionTicket handshake * if the ticket key was expired after SERVER_HELLO */ { @@ -1415,6 +1415,70 @@ int main(int argc, char **argv) EXPECT_EQUAL(client_connection->client_ticket.allocated, 0); } + /* Test TLS 1.3 Server does not send a zero-length ticket in the NewSessionTicket handshake + * if the ticket key was expired after SERVER_HELLO + */ + { + /* Initialize client and server configurations with TLS 1.2 */ + DEFER_CLEANUP(struct s2n_config *client_configuration = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_NOT_NULL(client_configuration); + EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(client_configuration, 1)); + EXPECT_SUCCESS(s2n_config_set_cipher_preferences(client_configuration, "default_tls13")); + EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(client_configuration)); + + DEFER_CLEANUP(struct s2n_config *server_configuration = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_NOT_NULL(server_configuration); + EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(server_configuration, 1)); + EXPECT_SUCCESS(s2n_config_set_cipher_preferences(server_configuration, "default_tls13")); + EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(server_configuration)); + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_configuration, + chain_and_key)); + + EXPECT_SUCCESS(s2n_config_add_ticket_crypto_key(server_configuration, ticket_key_name1, + s2n_array_len(ticket_key_name1), ticket_key1, s2n_array_len(ticket_key1), 0)); + + /* Initialize client and server connections*/ + DEFER_CLEANUP(struct s2n_connection *client_connection = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client_connection); + EXPECT_SUCCESS(s2n_connection_set_session(client_connection, serialized_session_state, + serialized_session_state_length)); + EXPECT_SUCCESS(s2n_connection_set_config(client_connection, client_configuration)); + DEFER_CLEANUP(struct s2n_connection *server_connection = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_connection); + EXPECT_SUCCESS(s2n_connection_set_config(server_connection, server_configuration)); + + /* Create nonblocking pipes */ + DEFER_CLEANUP(struct s2n_test_io_stuffer_pair input_output_pair = { 0 }, + s2n_io_stuffer_pair_free); + EXPECT_OK(s2n_io_stuffer_pair_init(&input_output_pair)); + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client_connection, server_connection, + &input_output_pair)); + + /* Negotiate until session ticket is encrypted with session ticket key */ + EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server_connection, + client_connection, CLIENT_FINISHED)); + + /* After session ticket is encrypted, expire current session ticket key */ + uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; + EXPECT_SUCCESS(s2n_config_set_wall_clock(server_configuration, mock_nanoseconds_since_epoch, + &mock_delay)); + + /* Try to send a NewSessionTicket. This should not send a zero-length NST message */ + EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server_connection, + client_connection, SERVER_FINISHED)); + + /* Verify that TLS1.3 was negotiated */ + EXPECT_EQUAL(client_connection->actual_protocol_version, S2N_TLS13); + EXPECT_EQUAL(server_connection->actual_protocol_version, S2N_TLS13); + + /* Verify that the server did not issue a new session ticket */ + EXPECT_FALSE(IS_ISSUING_NEW_SESSION_TICKET(server_connection)); + } + EXPECT_SUCCESS(s2n_io_pair_close(&io_pair)); EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); EXPECT_SUCCESS(s2n_cert_chain_and_key_free(ecdsa_chain_and_key)); From e023d4606b9160dd8d4be933874d0c2113259c40 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Tue, 30 Apr 2024 21:53:23 +0000 Subject: [PATCH 03/28] check if tls1.3 is fully supported --- tests/unit/s2n_session_ticket_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 1c50b267630..6fd2a6b762f 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1418,7 +1418,7 @@ int main(int argc, char **argv) /* Test TLS 1.3 Server does not send a zero-length ticket in the NewSessionTicket handshake * if the ticket key was expired after SERVER_HELLO */ - { + if (s2n_is_tls13_fully_supported()) { /* Initialize client and server configurations with TLS 1.2 */ DEFER_CLEANUP(struct s2n_config *client_configuration = s2n_config_new(), s2n_config_ptr_free); From edff88a0edde56d5a3689d8814789a83a85de4a9 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Wed, 1 May 2024 00:31:32 +0000 Subject: [PATCH 04/28] use shorter variable names --- tests/unit/s2n_session_ticket_test.c | 81 ++++++++++++---------------- tls/s2n_server_new_session_ticket.c | 4 +- 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 6fd2a6b762f..7d7e266f6bb 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1352,7 +1352,6 @@ int main(int argc, char **argv) * if the ticket key was expired after SERVER_HELLO */ { - /* Initialize client and server configurations with TLS 1.2 */ DEFER_CLEANUP(struct s2n_config *client_configuration = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(client_configuration); @@ -1372,54 +1371,49 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_add_ticket_crypto_key(server_configuration, ticket_key_name1, s2n_array_len(ticket_key_name1), ticket_key1, s2n_array_len(ticket_key1), 0)); - /* Initialize client and server connections*/ - DEFER_CLEANUP(struct s2n_connection *client_connection = s2n_connection_new(S2N_CLIENT), + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); - EXPECT_NOT_NULL(client_connection); - EXPECT_SUCCESS(s2n_connection_set_session(client_connection, serialized_session_state, + EXPECT_NOT_NULL(client); + EXPECT_SUCCESS(s2n_connection_set_session(client, serialized_session_state, serialized_session_state_length)); - EXPECT_SUCCESS(s2n_connection_set_config(client_connection, client_configuration)); - DEFER_CLEANUP(struct s2n_connection *server_connection = s2n_connection_new(S2N_SERVER), + EXPECT_SUCCESS(s2n_connection_set_config(client, client_configuration)); + + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); - EXPECT_NOT_NULL(server_connection); - EXPECT_SUCCESS(s2n_connection_set_config(server_connection, server_configuration)); + EXPECT_NOT_NULL(server); + EXPECT_SUCCESS(s2n_connection_set_config(server, server_configuration)); - /* Create nonblocking pipes */ - DEFER_CLEANUP(struct s2n_test_io_stuffer_pair input_output_pair = { 0 }, + DEFER_CLEANUP(struct s2n_test_io_stuffer_pair test_io = { 0 }, s2n_io_stuffer_pair_free); - EXPECT_OK(s2n_io_stuffer_pair_init(&input_output_pair)); - EXPECT_OK(s2n_connections_set_io_stuffer_pair(client_connection, server_connection, - &input_output_pair)); + EXPECT_OK(s2n_io_stuffer_pair_init(&test_io)); + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &test_io)); /* Negotiate until session ticket is encrypted with session ticket key */ - EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server_connection, - client_connection, CLIENT_FINISHED)); + EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, CLIENT_FINISHED)); /* After session ticket is encrypted, expire current session ticket key */ uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; EXPECT_SUCCESS(s2n_config_set_wall_clock(server_configuration, mock_nanoseconds_since_epoch, &mock_delay)); - /* Try to send a NewSessionTicket. This should send a zero-length NST message */ - EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server_connection, - client_connection, SERVER_FINISHED)); + /* Attempt to send a NewSessionTicket. This should send a zero-length NST message */ + EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, SERVER_FINISHED)); /* Verify that TLS1.2 was negotiated */ - EXPECT_EQUAL(client_connection->actual_protocol_version, S2N_TLS12); - EXPECT_EQUAL(server_connection->actual_protocol_version, S2N_TLS12); + EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS12); + EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS12); /* Verify that the server did issue a new session ticket */ - EXPECT_TRUE(IS_ISSUING_NEW_SESSION_TICKET(server_connection)); + EXPECT_TRUE(IS_ISSUING_NEW_SESSION_TICKET(server)); /* Verify that the client received a zero-length NewSessionTicket message */ - EXPECT_EQUAL(client_connection->client_ticket.allocated, 0); + EXPECT_EQUAL(client->client_ticket.allocated, 0); } /* Test TLS 1.3 Server does not send a zero-length ticket in the NewSessionTicket handshake * if the ticket key was expired after SERVER_HELLO */ if (s2n_is_tls13_fully_supported()) { - /* Initialize client and server configurations with TLS 1.2 */ DEFER_CLEANUP(struct s2n_config *client_configuration = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(client_configuration); @@ -1439,44 +1433,39 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_add_ticket_crypto_key(server_configuration, ticket_key_name1, s2n_array_len(ticket_key_name1), ticket_key1, s2n_array_len(ticket_key1), 0)); - /* Initialize client and server connections*/ - DEFER_CLEANUP(struct s2n_connection *client_connection = s2n_connection_new(S2N_CLIENT), + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); - EXPECT_NOT_NULL(client_connection); - EXPECT_SUCCESS(s2n_connection_set_session(client_connection, serialized_session_state, + EXPECT_NOT_NULL(client); + EXPECT_SUCCESS(s2n_connection_set_session(client, serialized_session_state, serialized_session_state_length)); - EXPECT_SUCCESS(s2n_connection_set_config(client_connection, client_configuration)); - DEFER_CLEANUP(struct s2n_connection *server_connection = s2n_connection_new(S2N_SERVER), + EXPECT_SUCCESS(s2n_connection_set_config(client, client_configuration)); + + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); - EXPECT_NOT_NULL(server_connection); - EXPECT_SUCCESS(s2n_connection_set_config(server_connection, server_configuration)); + EXPECT_NOT_NULL(server); + EXPECT_SUCCESS(s2n_connection_set_config(server, server_configuration)); - /* Create nonblocking pipes */ - DEFER_CLEANUP(struct s2n_test_io_stuffer_pair input_output_pair = { 0 }, - s2n_io_stuffer_pair_free); - EXPECT_OK(s2n_io_stuffer_pair_init(&input_output_pair)); - EXPECT_OK(s2n_connections_set_io_stuffer_pair(client_connection, server_connection, - &input_output_pair)); + DEFER_CLEANUP(struct s2n_test_io_stuffer_pair test_io = { 0 }, s2n_io_stuffer_pair_free); + EXPECT_OK(s2n_io_stuffer_pair_init(&test_io)); + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &test_io)); /* Negotiate until session ticket is encrypted with session ticket key */ - EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server_connection, - client_connection, CLIENT_FINISHED)); + EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, CLIENT_FINISHED)); /* After session ticket is encrypted, expire current session ticket key */ uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; EXPECT_SUCCESS(s2n_config_set_wall_clock(server_configuration, mock_nanoseconds_since_epoch, &mock_delay)); - /* Try to send a NewSessionTicket. This should not send a zero-length NST message */ - EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server_connection, - client_connection, SERVER_FINISHED)); + /* Attempt to send a NewSessionTicket. This should not send a zero-length NST message */ + EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, SERVER_FINISHED)); /* Verify that TLS1.3 was negotiated */ - EXPECT_EQUAL(client_connection->actual_protocol_version, S2N_TLS13); - EXPECT_EQUAL(server_connection->actual_protocol_version, S2N_TLS13); + EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS13); + EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS13); /* Verify that the server did not issue a new session ticket */ - EXPECT_FALSE(IS_ISSUING_NEW_SESSION_TICKET(server_connection)); + EXPECT_FALSE(IS_ISSUING_NEW_SESSION_TICKET(server)); } EXPECT_SUCCESS(s2n_io_pair_close(&io_pair)); diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index 1d09bb3eeb6..cfd4ec9dbaa 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -82,8 +82,8 @@ int s2n_server_nst_send(struct s2n_connection *conn) uint32_t lifetime_hint_in_secs = (conn->config->encrypt_decrypt_key_lifetime_in_nanos + conn->config->decrypt_key_lifetime_in_nanos) / ONE_SEC_IN_NANOS; - /* When server changes it's mind mid handshake, or when session key is expired, - * send lifetime hint and session ticket length as zero + /* When server changes it's mind mid handshake, or if session key used to encrypt session ticket + * is expired, send lifetime hint and session ticket length as zero */ if (!conn->config->use_tickets || !s2n_config_is_encrypt_decrypt_key_available(conn->config)) { POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0)); From c4a5474970e8a7b7139012497357a07b07f5edcd Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Wed, 1 May 2024 20:10:54 +0000 Subject: [PATCH 05/28] modify test setups --- tests/unit/s2n_session_ticket_test.c | 12 ++++-------- tls/s2n_server_new_session_ticket.c | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 7d7e266f6bb..27b36f14b93 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1356,14 +1356,12 @@ int main(int argc, char **argv) s2n_config_ptr_free); EXPECT_NOT_NULL(client_configuration); EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(client_configuration, 1)); - EXPECT_SUCCESS(s2n_config_set_cipher_preferences(client_configuration, "default")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(client_configuration)); DEFER_CLEANUP(struct s2n_config *server_configuration = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(server_configuration); EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(server_configuration, 1)); - EXPECT_SUCCESS(s2n_config_set_cipher_preferences(server_configuration, "default")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(server_configuration)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_configuration, chain_and_key)); @@ -1374,8 +1372,8 @@ int main(int argc, char **argv) DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); EXPECT_NOT_NULL(client); - EXPECT_SUCCESS(s2n_connection_set_session(client, serialized_session_state, - serialized_session_state_length)); + // EXPECT_SUCCESS(s2n_connection_set_session(client, serialized_session_state, + // serialized_session_state_length)); EXPECT_SUCCESS(s2n_connection_set_config(client, client_configuration)); DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), @@ -1397,7 +1395,7 @@ int main(int argc, char **argv) &mock_delay)); /* Attempt to send a NewSessionTicket. This should send a zero-length NST message */ - EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, SERVER_FINISHED)); + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); /* Verify that TLS1.2 was negotiated */ EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS12); @@ -1436,8 +1434,6 @@ int main(int argc, char **argv) DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); EXPECT_NOT_NULL(client); - EXPECT_SUCCESS(s2n_connection_set_session(client, serialized_session_state, - serialized_session_state_length)); EXPECT_SUCCESS(s2n_connection_set_config(client, client_configuration)); DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), @@ -1458,7 +1454,7 @@ int main(int argc, char **argv) &mock_delay)); /* Attempt to send a NewSessionTicket. This should not send a zero-length NST message */ - EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, SERVER_FINISHED)); + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); /* Verify that TLS1.3 was negotiated */ EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS13); diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index cfd4ec9dbaa..017ab69aa43 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -85,7 +85,7 @@ int s2n_server_nst_send(struct s2n_connection *conn) /* When server changes it's mind mid handshake, or if session key used to encrypt session ticket * is expired, send lifetime hint and session ticket length as zero */ - if (!conn->config->use_tickets || !s2n_config_is_encrypt_decrypt_key_available(conn->config)) { + if (!conn->config->use_tickets || s2n_config_is_encrypt_decrypt_key_available(conn->config) == 0) { POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0)); POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0)); From 9beba2cba2ca981a164eb380e0001cf7d337ef6f Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Wed, 1 May 2024 22:22:52 +0000 Subject: [PATCH 06/28] address comment --- tests/unit/s2n_session_ticket_test.c | 3 --- tls/s2n_server_new_session_ticket.c | 6 +++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 27b36f14b93..67b94096fa8 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1459,9 +1459,6 @@ int main(int argc, char **argv) /* Verify that TLS1.3 was negotiated */ EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS13); EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS13); - - /* Verify that the server did not issue a new session ticket */ - EXPECT_FALSE(IS_ISSUING_NEW_SESSION_TICKET(server)); } EXPECT_SUCCESS(s2n_io_pair_close(&io_pair)); diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index 017ab69aa43..bec3df799d6 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -84,7 +84,11 @@ int s2n_server_nst_send(struct s2n_connection *conn) /* When server changes it's mind mid handshake, or if session key used to encrypt session ticket * is expired, send lifetime hint and session ticket length as zero - */ + * + *= https://tools.ietf.org/rfc/rfc5077#3.3 + *# This message MUST be sent if the server included + *# a SessionTicket extension in the ServerHello. + **/ if (!conn->config->use_tickets || s2n_config_is_encrypt_decrypt_key_available(conn->config) == 0) { POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0)); POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0)); From 8ead510e4d825ec3da3b9a26f06aff6103095ede Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Wed, 1 May 2024 23:43:32 +0000 Subject: [PATCH 07/28] add compliance comments --- tests/unit/s2n_session_ticket_test.c | 6 ++---- tls/s2n_server_new_session_ticket.c | 8 +++++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 67b94096fa8..8c8b4330f5c 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1372,8 +1372,6 @@ int main(int argc, char **argv) DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); EXPECT_NOT_NULL(client); - // EXPECT_SUCCESS(s2n_connection_set_session(client, serialized_session_state, - // serialized_session_state_length)); EXPECT_SUCCESS(s2n_connection_set_config(client, client_configuration)); DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), @@ -1386,10 +1384,10 @@ int main(int argc, char **argv) EXPECT_OK(s2n_io_stuffer_pair_init(&test_io)); EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &test_io)); - /* Negotiate until session ticket is encrypted with session ticket key */ + /* Perform initial part of handshake to verify that a valid key exists */ EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, CLIENT_FINISHED)); - /* After session ticket is encrypted, expire current session ticket key */ + /* Expire current session ticket key so that server no longer holds a valid key */ uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; EXPECT_SUCCESS(s2n_config_set_wall_clock(server_configuration, mock_nanoseconds_since_epoch, &mock_delay)); diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index bec3df799d6..a046a6a0a97 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -85,9 +85,15 @@ int s2n_server_nst_send(struct s2n_connection *conn) /* When server changes it's mind mid handshake, or if session key used to encrypt session ticket * is expired, send lifetime hint and session ticket length as zero * - *= https://tools.ietf.org/rfc/rfc5077#3.3 + *= https://tools.ietf.org/rfc/rfc5077#section-3.3 *# This message MUST be sent if the server included *# a SessionTicket extension in the ServerHello. + * + *= https://tools.ietf.org/rfc/rfc5077#section-3.3 + *# If the server determines that it does not want to include a + *# ticket after it has included the SessionTicket extension in the + *# ServerHello, then it sends a zero-length ticket in the + *# NewSessionTicket handshake message. **/ if (!conn->config->use_tickets || s2n_config_is_encrypt_decrypt_key_available(conn->config) == 0) { POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0)); From ab18c07873b81bf2af4c6a7685697045a428ddc8 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Mon, 6 May 2024 20:40:06 +0000 Subject: [PATCH 08/28] add unit test for s2n_server_send --- .../unit/s2n_server_new_session_ticket_test.c | 66 +++++++++++++++++++ tests/unit/s2n_session_ticket_test.c | 6 +- tls/s2n_server_new_session_ticket.c | 8 ++- 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index 49fb0eb04f5..7c6ebc033d4 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -34,6 +34,7 @@ #define MAX_TEST_SESSION_SIZE 300 #define EXPECT_TICKETS_SENT(conn, count) EXPECT_OK(s2n_assert_tickets_sent(conn, count)) +#define S2N_CLOCK_SYS CLOCK_REALTIME static S2N_RESULT s2n_assert_tickets_sent(struct s2n_connection *conn, uint16_t expected_tickets_sent) { @@ -80,6 +81,32 @@ static int s2n_setup_test_resumption_secret(struct s2n_connection *conn) return S2N_SUCCESS; } +/** + * This function is used to "skip" time in unit tests. It will mock the system + * time to be current_time (ns) + data (ns). The "data" parameter is a uint64_t + * passed in as a void*. + */ +int mock_nanoseconds_since_epoch(void *data, uint64_t *nanoseconds) +{ + struct timespec current_time; + + clock_gettime(S2N_CLOCK_SYS, ¤t_time); + + /** + * current_time fields are represented as time_t, and time_t has a platform + * dependent size. On 32 bit platforms, attempting to convert the current + * system time to nanoseconds will overflow, causing odd failures in unit + * tests. We upcast current_time fields to uint64_t before multiplying to + * avoid this. + */ + *nanoseconds = 0; + *nanoseconds += (uint64_t) current_time.tv_sec * ONE_SEC_IN_NANOS; + *nanoseconds += (uint64_t) current_time.tv_nsec; + *nanoseconds += *(uint64_t *) data; + + return 0; +} + int main(int argc, char **argv) { BEGIN_TEST(); @@ -801,6 +828,45 @@ int main(int argc, char **argv) }; }; + /* s2n_server_nst_send */ + { + /* TLS 1.2 server sends zero ticket lifetime and zero-length ticket if key expires */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + EXPECT_OK(s2n_resumption_test_ticket_key_setup(config)); + EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); + + EXPECT_NOT_EQUAL(s2n_stuffer_space_remaining(&conn->handshake.io), 0); + + /* Expire current session ticket key so that server no longer holds a valid key */ + uint64_t mock_delay = config->encrypt_decrypt_key_lifetime_in_nanos; + EXPECT_SUCCESS(s2n_config_set_wall_clock(config, mock_nanoseconds_since_epoch, + &mock_delay)); + + /* Send a new session ticket with lifetime hint and session ticket length as zero. + * tickets_sent does not get incremented in this codepath and therefore we + * technically expect 0 tickets_sent in connection object. + */ + EXPECT_SUCCESS(s2n_server_nst_send(conn)); + EXPECT_TICKETS_SENT(conn, 0); + + uint32_t lifetime = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint32(&conn->handshake.io, &lifetime)); + EXPECT_TRUE(lifetime == 0); + EXPECT_SUCCESS(s2n_stuffer_skip_read(&conn->handshake.io, lifetime)); + + uint16_t ticket_len = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint16(&conn->handshake.io, &ticket_len)); + EXPECT_TRUE(ticket_len == 0); + EXPECT_SUCCESS(s2n_stuffer_skip_read(&conn->handshake.io, ticket_len)); + } + } + /* s2n_tls13_server_nst_send */ { /* Mode is not server */ diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 8c8b4330f5c..11c43a5a6ad 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1401,9 +1401,6 @@ int main(int argc, char **argv) /* Verify that the server did issue a new session ticket */ EXPECT_TRUE(IS_ISSUING_NEW_SESSION_TICKET(server)); - - /* Verify that the client received a zero-length NewSessionTicket message */ - EXPECT_EQUAL(client->client_ticket.allocated, 0); } /* Test TLS 1.3 Server does not send a zero-length ticket in the NewSessionTicket handshake @@ -1457,6 +1454,9 @@ int main(int argc, char **argv) /* Verify that TLS1.3 was negotiated */ EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS13); EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS13); + + /* Verify that the server did not issue a new session ticket */ + EXPECT_FALSE(IS_ISSUING_NEW_SESSION_TICKET(server)); } EXPECT_SUCCESS(s2n_io_pair_close(&io_pair)); diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index a046a6a0a97..c09df4f2227 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -94,12 +94,18 @@ int s2n_server_nst_send(struct s2n_connection *conn) *# ticket after it has included the SessionTicket extension in the *# ServerHello, then it sends a zero-length ticket in the *# NewSessionTicket handshake message. + * + *= https://tools.ietf.org/rfc/rfc5077#section-3.3 + *# struct { + *# uint32 ticket_lifetime_hint; + *# opaque ticket<0..2^16-1>; + *# } NewSessionTicket; **/ if (!conn->config->use_tickets || s2n_config_is_encrypt_decrypt_key_available(conn->config) == 0) { POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0)); POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0)); - return 0; + return S2N_SUCCESS; } if (!s2n_server_sending_nst(conn)) { From e86b5b3ed3af32a01d17aa4118942fa464c6dc6f Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Mon, 6 May 2024 21:12:20 +0000 Subject: [PATCH 09/28] address clang format issues --- .../unit/s2n_server_new_session_ticket_test.c | 11 +- tests/unit/s2n_session_ticket_test.c | 116 +++++++++--------- 2 files changed, 63 insertions(+), 64 deletions(-) diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index 7c6ebc033d4..135e1e07863 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -34,7 +34,7 @@ #define MAX_TEST_SESSION_SIZE 300 #define EXPECT_TICKETS_SENT(conn, count) EXPECT_OK(s2n_assert_tickets_sent(conn, count)) -#define S2N_CLOCK_SYS CLOCK_REALTIME +#define S2N_CLOCK_SYS CLOCK_REALTIME static S2N_RESULT s2n_assert_tickets_sent(struct s2n_connection *conn, uint16_t expected_tickets_sent) { @@ -832,11 +832,10 @@ int main(int argc, char **argv) { /* TLS 1.2 server sends zero ticket lifetime and zero-length ticket if key expires */ { - DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), - s2n_config_ptr_free); + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(config); DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), - s2n_connection_ptr_free); + s2n_connection_ptr_free); EXPECT_NOT_NULL(conn); EXPECT_OK(s2n_resumption_test_ticket_key_setup(config)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -846,7 +845,7 @@ int main(int argc, char **argv) /* Expire current session ticket key so that server no longer holds a valid key */ uint64_t mock_delay = config->encrypt_decrypt_key_lifetime_in_nanos; EXPECT_SUCCESS(s2n_config_set_wall_clock(config, mock_nanoseconds_since_epoch, - &mock_delay)); + &mock_delay)); /* Send a new session ticket with lifetime hint and session ticket length as zero. * tickets_sent does not get incremented in this codepath and therefore we @@ -864,7 +863,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_read_uint16(&conn->handshake.io, &ticket_len)); EXPECT_TRUE(ticket_len == 0); EXPECT_SUCCESS(s2n_stuffer_skip_read(&conn->handshake.io, ticket_len)); - } + }; } /* s2n_tls13_server_nst_send */ diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 0c8a3d70f5c..cedad4e51b8 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1348,30 +1348,46 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_free(config)); } - /* Test TLS 1.2 Server sends a zero-length ticket in the NewSessionTicket handshake - * if the ticket key was expired after SERVER_HELLO - */ - { + /* Test: TLS1.3 resumption is successful when key used to encrypt ticket is in decrypt-only state */ + if (s2n_is_tls13_fully_supported()) { DEFER_CLEANUP(struct s2n_config *client_configuration = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(client_configuration); EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(client_configuration, 1)); + EXPECT_SUCCESS(s2n_config_set_cipher_preferences(client_configuration, "default_tls13")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(client_configuration)); DEFER_CLEANUP(struct s2n_config *server_configuration = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(server_configuration); EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(server_configuration, 1)); + EXPECT_SUCCESS(s2n_config_set_cipher_preferences(server_configuration, "default_tls13")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(server_configuration)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_configuration, chain_and_key)); + /* Add the key that encrypted the session ticket so that the server will be able to decrypt + * the ticket successfully. + */ EXPECT_SUCCESS(s2n_config_add_ticket_crypto_key(server_configuration, ticket_key_name1, s2n_array_len(ticket_key_name1), ticket_key1, s2n_array_len(ticket_key1), 0)); + /* Add a mock delay such that key 1 moves to decrypt-only state */ + uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; + EXPECT_SUCCESS(s2n_config_set_wall_clock(server_configuration, mock_nanoseconds_since_epoch, + &mock_delay)); + + /* Add one session ticket key with an intro time in the past so that the key is immediately valid */ + POSIX_GUARD(server_configuration->wall_clock(server_configuration->sys_clock_ctx, &now)); + uint64_t key_intro_time = (now / ONE_SEC_IN_NANOS) - ONE_SEC_DELAY; + EXPECT_SUCCESS(s2n_config_add_ticket_crypto_key(server_configuration, ticket_key_name2, + s2n_array_len(ticket_key_name2), ticket_key2, s2n_array_len(ticket_key2), key_intro_time)); + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); EXPECT_NOT_NULL(client); + EXPECT_SUCCESS(s2n_connection_set_session(client, tls13_serialized_session_state.blob.data, + s2n_stuffer_data_available(&tls13_serialized_session_state))); EXPECT_SUCCESS(s2n_connection_set_config(client, client_configuration)); DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), @@ -1379,46 +1395,41 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(server); EXPECT_SUCCESS(s2n_connection_set_config(server, server_configuration)); + /* Create nonblocking pipes */ DEFER_CLEANUP(struct s2n_test_io_stuffer_pair test_io = { 0 }, s2n_io_stuffer_pair_free); EXPECT_OK(s2n_io_stuffer_pair_init(&test_io)); EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &test_io)); - /* Perform initial part of handshake to verify that a valid key exists */ - EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, CLIENT_FINISHED)); - - /* Expire current session ticket key so that server no longer holds a valid key */ - uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; - EXPECT_SUCCESS(s2n_config_set_wall_clock(server_configuration, mock_nanoseconds_since_epoch, - &mock_delay)); - - /* Attempt to send a NewSessionTicket. This should send a zero-length NST message */ EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); - /* Verify that TLS1.2 was negotiated */ - EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS12); - EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS12); + /* Verify that TLS1.3 was negotiated */ + EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS13); + EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS13); - /* Verify that the server did issue a new session ticket */ - EXPECT_TRUE(IS_ISSUING_NEW_SESSION_TICKET(server)); + /* Expect a resumption handshake because the session ticket is valid. + * If a full handshake is performed instead, then the session ticket is incorrectly + * being evaluated as invalid. This was previously known to happen with a decrypt-only + * key because we'd incorrectly try to set a TLS1.2-only handshake type flag, + * triggering an error while decrypting the session ticket. + */ + EXPECT_TRUE(IS_RESUMPTION_HANDSHAKE(server)); } - /* Test TLS 1.3 Server does not send a zero-length ticket in the NewSessionTicket handshake + /* Test TLS 1.2 Server sends a zero-length ticket in the NewSessionTicket handshake * if the ticket key was expired after SERVER_HELLO */ - if (s2n_is_tls13_fully_supported()) { + { DEFER_CLEANUP(struct s2n_config *client_configuration = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(client_configuration); EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(client_configuration, 1)); - EXPECT_SUCCESS(s2n_config_set_cipher_preferences(client_configuration, "default_tls13")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(client_configuration)); DEFER_CLEANUP(struct s2n_config *server_configuration = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(server_configuration); EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(server_configuration, 1)); - EXPECT_SUCCESS(s2n_config_set_cipher_preferences(server_configuration, "default_tls13")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(server_configuration)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_configuration, chain_and_key)); @@ -1436,30 +1447,33 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(server); EXPECT_SUCCESS(s2n_connection_set_config(server, server_configuration)); - DEFER_CLEANUP(struct s2n_test_io_stuffer_pair test_io = { 0 }, s2n_io_stuffer_pair_free); + DEFER_CLEANUP(struct s2n_test_io_stuffer_pair test_io = { 0 }, + s2n_io_stuffer_pair_free); EXPECT_OK(s2n_io_stuffer_pair_init(&test_io)); EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &test_io)); - /* Negotiate until session ticket is encrypted with session ticket key */ + /* Perform initial part of handshake to verify that a valid key exists */ EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, CLIENT_FINISHED)); - /* After session ticket is encrypted, expire current session ticket key */ + /* Expire current session ticket key so that server no longer holds a valid key */ uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; EXPECT_SUCCESS(s2n_config_set_wall_clock(server_configuration, mock_nanoseconds_since_epoch, &mock_delay)); - /* Attempt to send a NewSessionTicket. This should not send a zero-length NST message */ + /* Attempt to send a NewSessionTicket. This should send a zero-length NST message */ EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); - /* Verify that TLS1.3 was negotiated */ - EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS13); - EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS13); + /* Verify that TLS1.2 was negotiated */ + EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS12); + EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS12); - /* Verify that the server did not issue a new session ticket */ - EXPECT_FALSE(IS_ISSUING_NEW_SESSION_TICKET(server)); + /* Verify that the server did issue a new session ticket */ + EXPECT_TRUE(IS_ISSUING_NEW_SESSION_TICKET(server)); } - /* Test: TLS1.3 resumption is successful when key used to encrypt ticket is in decrypt-only state */ + /* Test TLS 1.3 Server does not send a zero-length ticket in the NewSessionTicket handshake + * if the ticket key was expired after SERVER_HELLO + */ if (s2n_is_tls13_fully_supported()) { DEFER_CLEANUP(struct s2n_config *client_configuration = s2n_config_new(), s2n_config_ptr_free); @@ -1477,28 +1491,12 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_configuration, chain_and_key)); - /* Add the key that encrypted the session ticket so that the server will be able to decrypt - * the ticket successfully. - */ EXPECT_SUCCESS(s2n_config_add_ticket_crypto_key(server_configuration, ticket_key_name1, s2n_array_len(ticket_key_name1), ticket_key1, s2n_array_len(ticket_key1), 0)); - /* Add a mock delay such that key 1 moves to decrypt-only state */ - uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; - EXPECT_SUCCESS(s2n_config_set_wall_clock(server_configuration, mock_nanoseconds_since_epoch, - &mock_delay)); - - /* Add one session ticket key with an intro time in the past so that the key is immediately valid */ - POSIX_GUARD(server_configuration->wall_clock(server_configuration->sys_clock_ctx, &now)); - uint64_t key_intro_time = (now / ONE_SEC_IN_NANOS) - ONE_SEC_DELAY; - EXPECT_SUCCESS(s2n_config_add_ticket_crypto_key(server_configuration, ticket_key_name2, - s2n_array_len(ticket_key_name2), ticket_key2, s2n_array_len(ticket_key2), key_intro_time)); - DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); EXPECT_NOT_NULL(client); - EXPECT_SUCCESS(s2n_connection_set_session(client, tls13_serialized_session_state.blob.data, - s2n_stuffer_data_available(&tls13_serialized_session_state))); EXPECT_SUCCESS(s2n_connection_set_config(client, client_configuration)); DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), @@ -1506,25 +1504,27 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(server); EXPECT_SUCCESS(s2n_connection_set_config(server, server_configuration)); - /* Create nonblocking pipes */ - DEFER_CLEANUP(struct s2n_test_io_stuffer_pair test_io = { 0 }, - s2n_io_stuffer_pair_free); + DEFER_CLEANUP(struct s2n_test_io_stuffer_pair test_io = { 0 }, s2n_io_stuffer_pair_free); EXPECT_OK(s2n_io_stuffer_pair_init(&test_io)); EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &test_io)); + /* Negotiate until session ticket is encrypted with session ticket key */ + EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, CLIENT_FINISHED)); + + /* After session ticket is encrypted, expire current session ticket key */ + uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; + EXPECT_SUCCESS(s2n_config_set_wall_clock(server_configuration, mock_nanoseconds_since_epoch, + &mock_delay)); + + /* Attempt to send a NewSessionTicket. This should not send a zero-length NST message */ EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); /* Verify that TLS1.3 was negotiated */ EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS13); EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS13); - /* Expect a resumption handshake because the session ticket is valid. - * If a full handshake is performed instead, then the session ticket is incorrectly - * being evaluated as invalid. This was previously known to happen with a decrypt-only - * key because we'd incorrectly try to set a TLS1.2-only handshake type flag, - * triggering an error while decrypting the session ticket. - */ - EXPECT_TRUE(IS_RESUMPTION_HANDSHAKE(server)); + /* Verify that the server did not issue a new session ticket */ + EXPECT_FALSE(IS_ISSUING_NEW_SESSION_TICKET(server)); } EXPECT_SUCCESS(s2n_io_pair_close(&io_pair)); From ae343b8497e90fac4b9f154fb99e52c776751b67 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Mon, 6 May 2024 21:18:06 +0000 Subject: [PATCH 10/28] edit rfc comment format --- tls/s2n_server_new_session_ticket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index f04a3e392d5..84314e65ed4 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -85,17 +85,17 @@ int s2n_server_nst_send(struct s2n_connection *conn) /* When server changes it's mind mid handshake, or if session key used to encrypt session ticket * is expired, send lifetime hint and session ticket length as zero * - *= https://tools.ietf.org/rfc/rfc5077#section-3.3 + *= https://www.rfc-editor.org/rfc/rfc8446#section-3.3 *# This message MUST be sent if the server included *# a SessionTicket extension in the ServerHello. * - *= https://tools.ietf.org/rfc/rfc5077#section-3.3 + *= https://www.rfc-editor.org/rfc/rfc8446#section-3.3 *# If the server determines that it does not want to include a *# ticket after it has included the SessionTicket extension in the *# ServerHello, then it sends a zero-length ticket in the *# NewSessionTicket handshake message. * - *= https://tools.ietf.org/rfc/rfc5077#section-3.3 + *= https://www.rfc-editor.org/rfc/rfc8446#section-3.3 *# struct { *# uint32 ticket_lifetime_hint; *# opaque ticket<0..2^16-1>; From 9302a3a6d22bc5b22c391afcc38dc59b46250a7b Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Mon, 6 May 2024 21:21:12 +0000 Subject: [PATCH 11/28] fix rfc number --- tls/s2n_server_new_session_ticket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index 84314e65ed4..05663306968 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -85,17 +85,17 @@ int s2n_server_nst_send(struct s2n_connection *conn) /* When server changes it's mind mid handshake, or if session key used to encrypt session ticket * is expired, send lifetime hint and session ticket length as zero * - *= https://www.rfc-editor.org/rfc/rfc8446#section-3.3 + *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 *# This message MUST be sent if the server included *# a SessionTicket extension in the ServerHello. * - *= https://www.rfc-editor.org/rfc/rfc8446#section-3.3 + *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 *# If the server determines that it does not want to include a *# ticket after it has included the SessionTicket extension in the *# ServerHello, then it sends a zero-length ticket in the *# NewSessionTicket handshake message. * - *= https://www.rfc-editor.org/rfc/rfc8446#section-3.3 + *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 *# struct { *# uint32 ticket_lifetime_hint; *# opaque ticket<0..2^16-1>; From 112574cefcd3e6a629897d23e2bb8f44fb1404c4 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Mon, 6 May 2024 21:26:35 +0000 Subject: [PATCH 12/28] remove unnecessary expect_false() --- tests/unit/s2n_session_ticket_test.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index cedad4e51b8..18ceed652df 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1522,9 +1522,6 @@ int main(int argc, char **argv) /* Verify that TLS1.3 was negotiated */ EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS13); EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS13); - - /* Verify that the server did not issue a new session ticket */ - EXPECT_FALSE(IS_ISSUING_NEW_SESSION_TICKET(server)); } EXPECT_SUCCESS(s2n_io_pair_close(&io_pair)); From 82709eec642a3a4d6fa49090dc4059c4ff879e48 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Mon, 6 May 2024 22:12:42 +0000 Subject: [PATCH 13/28] add test case for sending non-zero nst --- .../unit/s2n_server_new_session_ticket_test.c | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index 135e1e07863..0aefe4350db 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -830,6 +830,33 @@ int main(int argc, char **argv) /* s2n_server_nst_send */ { + /* TLS 1.2 server sends a new session ticket key */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + EXPECT_OK(s2n_resumption_test_ticket_key_setup(config)); + EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); + + EXPECT_NOT_EQUAL(s2n_stuffer_space_remaining(&conn->handshake.io), 0); + + conn->config->use_tickets = 1; + conn->session_ticket_status = S2N_NEW_TICKET; + + EXPECT_SUCCESS(s2n_server_nst_send(conn)); + EXPECT_TICKETS_SENT(conn, 1); + + uint32_t lifetime = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint32(&conn->handshake.io, &lifetime)); + EXPECT_TRUE(lifetime > 0); + + uint16_t ticket_len = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint16(&conn->handshake.io, &ticket_len)); + EXPECT_TRUE(ticket_len > 0); + }; + /* TLS 1.2 server sends zero ticket lifetime and zero-length ticket if key expires */ { DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); @@ -842,6 +869,9 @@ int main(int argc, char **argv) EXPECT_NOT_EQUAL(s2n_stuffer_space_remaining(&conn->handshake.io), 0); + conn->config->use_tickets = 1; + conn->session_ticket_status = S2N_NEW_TICKET; + /* Expire current session ticket key so that server no longer holds a valid key */ uint64_t mock_delay = config->encrypt_decrypt_key_lifetime_in_nanos; EXPECT_SUCCESS(s2n_config_set_wall_clock(config, mock_nanoseconds_since_epoch, @@ -857,12 +887,10 @@ int main(int argc, char **argv) uint32_t lifetime = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint32(&conn->handshake.io, &lifetime)); EXPECT_TRUE(lifetime == 0); - EXPECT_SUCCESS(s2n_stuffer_skip_read(&conn->handshake.io, lifetime)); uint16_t ticket_len = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&conn->handshake.io, &ticket_len)); EXPECT_TRUE(ticket_len == 0); - EXPECT_SUCCESS(s2n_stuffer_skip_read(&conn->handshake.io, ticket_len)); }; } From 8118b83f6052b5d715f0a52d01b702ac0f442531 Mon Sep 17 00:00:00 2001 From: Jou Ho <43765840+jouho@users.noreply.github.com> Date: Tue, 7 May 2024 14:49:20 -0700 Subject: [PATCH 14/28] use suggested comment Co-authored-by: maddeleine <59030281+maddeleine@users.noreply.github.com> --- tests/unit/s2n_session_ticket_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 18ceed652df..44009c62a4f 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1452,7 +1452,7 @@ int main(int argc, char **argv) EXPECT_OK(s2n_io_stuffer_pair_init(&test_io)); EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &test_io)); - /* Perform initial part of handshake to verify that a valid key exists */ + /* Stop the handshake after the peers have established that a ticket will be sent in this handshake. */ EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, CLIENT_FINISHED)); /* Expire current session ticket key so that server no longer holds a valid key */ From aad3a35d1accdeaa5acc3d605bfecdaec6624379 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Tue, 7 May 2024 21:52:52 +0000 Subject: [PATCH 15/28] remove unnecessary test case --- tests/unit/s2n_session_ticket_test.c | 54 ---------------------------- tls/s2n_server_new_session_ticket.c | 4 +-- 2 files changed, 2 insertions(+), 56 deletions(-) diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 44009c62a4f..735b25a6372 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1430,7 +1430,6 @@ int main(int argc, char **argv) s2n_config_ptr_free); EXPECT_NOT_NULL(server_configuration); EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(server_configuration, 1)); - EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(server_configuration)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_configuration, chain_and_key)); @@ -1471,59 +1470,6 @@ int main(int argc, char **argv) EXPECT_TRUE(IS_ISSUING_NEW_SESSION_TICKET(server)); } - /* Test TLS 1.3 Server does not send a zero-length ticket in the NewSessionTicket handshake - * if the ticket key was expired after SERVER_HELLO - */ - if (s2n_is_tls13_fully_supported()) { - DEFER_CLEANUP(struct s2n_config *client_configuration = s2n_config_new(), - s2n_config_ptr_free); - EXPECT_NOT_NULL(client_configuration); - EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(client_configuration, 1)); - EXPECT_SUCCESS(s2n_config_set_cipher_preferences(client_configuration, "default_tls13")); - EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(client_configuration)); - - DEFER_CLEANUP(struct s2n_config *server_configuration = s2n_config_new(), - s2n_config_ptr_free); - EXPECT_NOT_NULL(server_configuration); - EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(server_configuration, 1)); - EXPECT_SUCCESS(s2n_config_set_cipher_preferences(server_configuration, "default_tls13")); - EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(server_configuration)); - EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_configuration, - chain_and_key)); - - EXPECT_SUCCESS(s2n_config_add_ticket_crypto_key(server_configuration, ticket_key_name1, - s2n_array_len(ticket_key_name1), ticket_key1, s2n_array_len(ticket_key1), 0)); - - DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), - s2n_connection_ptr_free); - EXPECT_NOT_NULL(client); - EXPECT_SUCCESS(s2n_connection_set_config(client, client_configuration)); - - DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), - s2n_connection_ptr_free); - EXPECT_NOT_NULL(server); - EXPECT_SUCCESS(s2n_connection_set_config(server, server_configuration)); - - DEFER_CLEANUP(struct s2n_test_io_stuffer_pair test_io = { 0 }, s2n_io_stuffer_pair_free); - EXPECT_OK(s2n_io_stuffer_pair_init(&test_io)); - EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &test_io)); - - /* Negotiate until session ticket is encrypted with session ticket key */ - EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, CLIENT_FINISHED)); - - /* After session ticket is encrypted, expire current session ticket key */ - uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; - EXPECT_SUCCESS(s2n_config_set_wall_clock(server_configuration, mock_nanoseconds_since_epoch, - &mock_delay)); - - /* Attempt to send a NewSessionTicket. This should not send a zero-length NST message */ - EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); - - /* Verify that TLS1.3 was negotiated */ - EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS13); - EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS13); - } - EXPECT_SUCCESS(s2n_io_pair_close(&io_pair)); EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); EXPECT_SUCCESS(s2n_cert_chain_and_key_free(ecdsa_chain_and_key)); diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index 05663306968..303bb57d279 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -82,8 +82,8 @@ int s2n_server_nst_send(struct s2n_connection *conn) uint32_t lifetime_hint_in_secs = (conn->config->encrypt_decrypt_key_lifetime_in_nanos + conn->config->decrypt_key_lifetime_in_nanos) / ONE_SEC_IN_NANOS; - /* When server changes it's mind mid handshake, or if session key used to encrypt session ticket - * is expired, send lifetime hint and session ticket length as zero + /* Send a zero-length ticket in the NewSessionTicket message if the server changes + *its mind mid-handshake or if there are no valid encrypt keys currently available. * *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 *# This message MUST be sent if the server included From 13ec6d3ac5891141920d1f314ff86bf1a6d1f9f0 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Tue, 7 May 2024 22:36:36 +0000 Subject: [PATCH 16/28] check all data is read --- tests/unit/s2n_server_new_session_ticket_test.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index 0aefe4350db..6e42d0cd331 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -830,6 +830,8 @@ int main(int argc, char **argv) /* s2n_server_nst_send */ { + uint8_t nst_data[S2N_TLS12_TICKET_SIZE_IN_BYTES] = { 0 }; + /* TLS 1.2 server sends a new session ticket key */ { DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); @@ -840,9 +842,6 @@ int main(int argc, char **argv) EXPECT_OK(s2n_resumption_test_ticket_key_setup(config)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); - EXPECT_NOT_EQUAL(s2n_stuffer_space_remaining(&conn->handshake.io), 0); - - conn->config->use_tickets = 1; conn->session_ticket_status = S2N_NEW_TICKET; EXPECT_SUCCESS(s2n_server_nst_send(conn)); @@ -855,6 +854,11 @@ int main(int argc, char **argv) uint16_t ticket_len = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&conn->handshake.io, &ticket_len)); EXPECT_TRUE(ticket_len > 0); + + struct s2n_blob nst_message = { 0 }; + EXPECT_SUCCESS(s2n_blob_init(&nst_message, nst_data, sizeof(nst_data))); + EXPECT_SUCCESS(s2n_stuffer_read(&conn->handshake.io, &nst_message)); + EXPECT_EQUAL(0, s2n_stuffer_data_available(&conn->handshake.io)); }; /* TLS 1.2 server sends zero ticket lifetime and zero-length ticket if key expires */ From 1c8b71d46b1cdba9681dd57b5ae7fe76937a30ad Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Tue, 7 May 2024 22:39:24 +0000 Subject: [PATCH 17/28] give better test description --- tests/unit/s2n_server_new_session_ticket_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index 6e42d0cd331..280e24d6d20 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -832,7 +832,7 @@ int main(int argc, char **argv) { uint8_t nst_data[S2N_TLS12_TICKET_SIZE_IN_BYTES] = { 0 }; - /* TLS 1.2 server sends a new session ticket key */ + /* s2n_server_nst_send writes a non-zero ticket when a valid encryption key exists */ { DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(config); @@ -861,7 +861,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(0, s2n_stuffer_data_available(&conn->handshake.io)); }; - /* TLS 1.2 server sends zero ticket lifetime and zero-length ticket if key expires */ + /* s2n_server_nst_send writes a zero-length ticket when no valid encryption key exists */ { DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(config); From 0a4c8eed7ba779a31d3bc265527a5b268e811b2d Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Tue, 7 May 2024 22:44:30 +0000 Subject: [PATCH 18/28] add compliance comment to the test --- tests/unit/s2n_server_new_session_ticket_test.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index 280e24d6d20..3399509e52b 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -863,6 +863,13 @@ int main(int argc, char **argv) /* s2n_server_nst_send writes a zero-length ticket when no valid encryption key exists */ { + /*= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 + *= type=test + *# If the server determines that it does not want to include a + *# ticket after it has included the SessionTicket extension in the + *# ServerHello, then it sends a zero-length ticket in the + *# NewSessionTicket handshake message. + */ DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(config); DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), @@ -881,10 +888,6 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_set_wall_clock(config, mock_nanoseconds_since_epoch, &mock_delay)); - /* Send a new session ticket with lifetime hint and session ticket length as zero. - * tickets_sent does not get incremented in this codepath and therefore we - * technically expect 0 tickets_sent in connection object. - */ EXPECT_SUCCESS(s2n_server_nst_send(conn)); EXPECT_TICKETS_SENT(conn, 0); From 9ff9261dbb35892475b941e0688b980e89f6dc80 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Tue, 7 May 2024 22:51:06 +0000 Subject: [PATCH 19/28] fix comment format --- tests/unit/s2n_server_new_session_ticket_test.c | 5 +++-- tls/s2n_server_new_session_ticket.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index 3399509e52b..8909c085a04 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -863,13 +863,14 @@ int main(int argc, char **argv) /* s2n_server_nst_send writes a zero-length ticket when no valid encryption key exists */ { - /*= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 + /** + *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 *= type=test *# If the server determines that it does not want to include a *# ticket after it has included the SessionTicket extension in the *# ServerHello, then it sends a zero-length ticket in the *# NewSessionTicket handshake message. - */ + **/ DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(config); DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index 303bb57d279..0ece7de5cb4 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -83,7 +83,7 @@ int s2n_server_nst_send(struct s2n_connection *conn) (conn->config->encrypt_decrypt_key_lifetime_in_nanos + conn->config->decrypt_key_lifetime_in_nanos) / ONE_SEC_IN_NANOS; /* Send a zero-length ticket in the NewSessionTicket message if the server changes - *its mind mid-handshake or if there are no valid encrypt keys currently available. + * its mind mid-handshake or if there are no valid encrypt keys currently available. * *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 *# This message MUST be sent if the server included From 35547538b15f8d0b78d57b2681f5fbc3a63877d5 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Wed, 8 May 2024 20:12:54 +0000 Subject: [PATCH 20/28] verify ticket length and and lifetime hint is 0 --- tests/unit/s2n_session_ticket_test.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 735b25a6372..2cfafe1b09b 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1466,8 +1466,11 @@ int main(int argc, char **argv) EXPECT_EQUAL(client->actual_protocol_version, S2N_TLS12); EXPECT_EQUAL(server->actual_protocol_version, S2N_TLS12); - /* Verify that the server did issue a new session ticket */ + /* Verify that the server issued zero-length session ticket */ EXPECT_TRUE(IS_ISSUING_NEW_SESSION_TICKET(server)); + + EXPECT_EQUAL(client->client_ticket.size, 0); + EXPECT_EQUAL(client->ticket_lifetime_hint, 0); } EXPECT_SUCCESS(s2n_io_pair_close(&io_pair)); From ca92f5885702db1bc76c50ff926308df0919eb8c Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Wed, 8 May 2024 20:29:12 +0000 Subject: [PATCH 21/28] fix input orders --- tests/unit/s2n_server_new_session_ticket_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index 8909c085a04..bac8cb46bec 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -858,7 +858,7 @@ int main(int argc, char **argv) struct s2n_blob nst_message = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&nst_message, nst_data, sizeof(nst_data))); EXPECT_SUCCESS(s2n_stuffer_read(&conn->handshake.io, &nst_message)); - EXPECT_EQUAL(0, s2n_stuffer_data_available(&conn->handshake.io)); + EXPECT_EQUAL(s2n_stuffer_data_available(&conn->handshake.io), 0); }; /* s2n_server_nst_send writes a zero-length ticket when no valid encryption key exists */ From 14d56a3b002ce01f8081d727688b4008e3d11946 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Wed, 8 May 2024 22:38:08 +0000 Subject: [PATCH 22/28] address PR feedbacks --- .../unit/s2n_server_new_session_ticket_test.c | 30 ++++++++----------- tests/unit/s2n_session_ticket_test.c | 8 +++-- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index bac8cb46bec..02a22ca6a6e 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -830,8 +830,6 @@ int main(int argc, char **argv) /* s2n_server_nst_send */ { - uint8_t nst_data[S2N_TLS12_TICKET_SIZE_IN_BYTES] = { 0 }; - /* s2n_server_nst_send writes a non-zero ticket when a valid encryption key exists */ { DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); @@ -855,22 +853,20 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_read_uint16(&conn->handshake.io, &ticket_len)); EXPECT_TRUE(ticket_len > 0); - struct s2n_blob nst_message = { 0 }; - EXPECT_SUCCESS(s2n_blob_init(&nst_message, nst_data, sizeof(nst_data))); - EXPECT_SUCCESS(s2n_stuffer_read(&conn->handshake.io, &nst_message)); - EXPECT_EQUAL(s2n_stuffer_data_available(&conn->handshake.io), 0); + EXPECT_EQUAL(s2n_stuffer_data_available(&conn->handshake.io), + S2N_TLS12_TICKET_SIZE_IN_BYTES); }; - /* s2n_server_nst_send writes a zero-length ticket when no valid encryption key exists */ + /* s2n_server_nst_send writes a zero-length ticket when no valid encryption key exists + * + *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 + *= type=test + *# If the server determines that it does not want to include a + *# ticket after it has included the SessionTicket extension in the + *# ServerHello, then it sends a zero-length ticket in the + *# NewSessionTicket handshake message. + **/ { - /** - *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 - *= type=test - *# If the server determines that it does not want to include a - *# ticket after it has included the SessionTicket extension in the - *# ServerHello, then it sends a zero-length ticket in the - *# NewSessionTicket handshake message. - **/ DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); EXPECT_NOT_NULL(config); DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), @@ -879,9 +875,6 @@ int main(int argc, char **argv) EXPECT_OK(s2n_resumption_test_ticket_key_setup(config)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); - EXPECT_NOT_EQUAL(s2n_stuffer_space_remaining(&conn->handshake.io), 0); - - conn->config->use_tickets = 1; conn->session_ticket_status = S2N_NEW_TICKET; /* Expire current session ticket key so that server no longer holds a valid key */ @@ -899,6 +892,7 @@ int main(int argc, char **argv) uint16_t ticket_len = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&conn->handshake.io, &ticket_len)); EXPECT_TRUE(ticket_len == 0); + EXPECT_EQUAL(s2n_stuffer_data_available(&conn->handshake.io), 0); }; } diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 2cfafe1b09b..460df185a94 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -1451,8 +1451,11 @@ int main(int argc, char **argv) EXPECT_OK(s2n_io_stuffer_pair_init(&test_io)); EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &test_io)); - /* Stop the handshake after the peers have established that a ticket will be sent in this handshake. */ - EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, CLIENT_FINISHED)); + /* Stop the handshake after the peers have established that a ticket + * will be sent in this handshake. + */ + EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, + CLIENT_FINISHED)); /* Expire current session ticket key so that server no longer holds a valid key */ uint64_t mock_delay = server_configuration->encrypt_decrypt_key_lifetime_in_nanos; @@ -1469,6 +1472,7 @@ int main(int argc, char **argv) /* Verify that the server issued zero-length session ticket */ EXPECT_TRUE(IS_ISSUING_NEW_SESSION_TICKET(server)); + /* Client does not have a session ticket since it received zero-length NST message */ EXPECT_EQUAL(client->client_ticket.size, 0); EXPECT_EQUAL(client->ticket_lifetime_hint, 0); } From 6b3ace87449991a140e412505d1d284f2c286994 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Mon, 13 May 2024 20:14:16 +0000 Subject: [PATCH 23/28] send zero-length nst upon failing to retrieve encrypt key --- tls/s2n_server_new_session_ticket.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index 0ece7de5cb4..a1ff2d7fc29 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -86,20 +86,10 @@ int s2n_server_nst_send(struct s2n_connection *conn) * its mind mid-handshake or if there are no valid encrypt keys currently available. * *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 - *# This message MUST be sent if the server included - *# a SessionTicket extension in the ServerHello. - * - *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 *# If the server determines that it does not want to include a *# ticket after it has included the SessionTicket extension in the *# ServerHello, then it sends a zero-length ticket in the *# NewSessionTicket handshake message. - * - *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 - *# struct { - *# uint32 ticket_lifetime_hint; - *# opaque ticket<0..2^16-1>; - *# } NewSessionTicket; **/ if (!conn->config->use_tickets || s2n_result_is_error(s2n_config_is_encrypt_key_available(conn->config))) { POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0)); @@ -112,11 +102,24 @@ int s2n_server_nst_send(struct s2n_connection *conn) POSIX_BAIL(S2N_ERR_SENDING_NST); } + /* Send a zero-length ticket in the NewSessionTicket message if encrypt key expires in between + * the key validation and encryption + * + *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 + *# This message MUST be sent if the server included + *# a SessionTicket extension in the ServerHello. + **/ POSIX_GUARD(s2n_stuffer_init(&to, &entry)); + if (s2n_encrypt_session_ticket(conn, &to) != 0) { + POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0)); + POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0)); + + return S2N_SUCCESS; + } + POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, lifetime_hint_in_secs)); POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, session_ticket_len)); - POSIX_GUARD(s2n_encrypt_session_ticket(conn, &to)); POSIX_GUARD(s2n_stuffer_write(&conn->handshake.io, &to.blob)); /* For parity with TLS1.3, track the single ticket sent. From 9b09e9103e240f9a6f9d0fd6492103c822d9cc67 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Mon, 13 May 2024 20:33:24 +0000 Subject: [PATCH 24/28] address linter issue --- tls/s2n_server_new_session_ticket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index a1ff2d7fc29..6a2fbbd53dc 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -115,7 +115,7 @@ int s2n_server_nst_send(struct s2n_connection *conn) POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0)); return S2N_SUCCESS; - } + } POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, lifetime_hint_in_secs)); POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, session_ticket_len)); From 907da2b45d23aec899ae55344a2787ff03b8d707 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Mon, 13 May 2024 22:05:41 +0000 Subject: [PATCH 25/28] address redundant code --- tls/s2n_server_new_session_ticket.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index 6a2fbbd53dc..d01a9e82c3a 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -91,7 +91,8 @@ int s2n_server_nst_send(struct s2n_connection *conn) *# ServerHello, then it sends a zero-length ticket in the *# NewSessionTicket handshake message. **/ - if (!conn->config->use_tickets || s2n_result_is_error(s2n_config_is_encrypt_key_available(conn->config))) { + POSIX_GUARD(s2n_stuffer_init(&to, &entry)); + if (!conn->config->use_tickets || s2n_encrypt_session_ticket(conn, &to) != 0) { POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0)); POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0)); @@ -102,21 +103,6 @@ int s2n_server_nst_send(struct s2n_connection *conn) POSIX_BAIL(S2N_ERR_SENDING_NST); } - /* Send a zero-length ticket in the NewSessionTicket message if encrypt key expires in between - * the key validation and encryption - * - *= https://www.rfc-editor.org/rfc/rfc5077#section-3.3 - *# This message MUST be sent if the server included - *# a SessionTicket extension in the ServerHello. - **/ - POSIX_GUARD(s2n_stuffer_init(&to, &entry)); - if (s2n_encrypt_session_ticket(conn, &to) != 0) { - POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0)); - POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0)); - - return S2N_SUCCESS; - } - POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, lifetime_hint_in_secs)); POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, session_ticket_len)); From ab7c57d153ed5ec5a671b182fdc02ec115d8bb66 Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Wed, 15 May 2024 19:14:08 +0000 Subject: [PATCH 26/28] remove unnecessary test setup --- .../unit/s2n_server_new_session_ticket_test.c | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index 02a22ca6a6e..826ac937b1b 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -81,32 +81,6 @@ static int s2n_setup_test_resumption_secret(struct s2n_connection *conn) return S2N_SUCCESS; } -/** - * This function is used to "skip" time in unit tests. It will mock the system - * time to be current_time (ns) + data (ns). The "data" parameter is a uint64_t - * passed in as a void*. - */ -int mock_nanoseconds_since_epoch(void *data, uint64_t *nanoseconds) -{ - struct timespec current_time; - - clock_gettime(S2N_CLOCK_SYS, ¤t_time); - - /** - * current_time fields are represented as time_t, and time_t has a platform - * dependent size. On 32 bit platforms, attempting to convert the current - * system time to nanoseconds will overflow, causing odd failures in unit - * tests. We upcast current_time fields to uint64_t before multiplying to - * avoid this. - */ - *nanoseconds = 0; - *nanoseconds += (uint64_t) current_time.tv_sec * ONE_SEC_IN_NANOS; - *nanoseconds += (uint64_t) current_time.tv_nsec; - *nanoseconds += *(uint64_t *) data; - - return 0; -} - int main(int argc, char **argv) { BEGIN_TEST(); @@ -872,16 +846,10 @@ int main(int argc, char **argv) DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); EXPECT_NOT_NULL(conn); - EXPECT_OK(s2n_resumption_test_ticket_key_setup(config)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); conn->session_ticket_status = S2N_NEW_TICKET; - /* Expire current session ticket key so that server no longer holds a valid key */ - uint64_t mock_delay = config->encrypt_decrypt_key_lifetime_in_nanos; - EXPECT_SUCCESS(s2n_config_set_wall_clock(config, mock_nanoseconds_since_epoch, - &mock_delay)); - EXPECT_SUCCESS(s2n_server_nst_send(conn)); EXPECT_TICKETS_SENT(conn, 0); From 1bf7d88bd4f82b9e80fe4d0de605ce328816630f Mon Sep 17 00:00:00 2001 From: Jou Ho Date: Wed, 15 May 2024 19:14:33 +0000 Subject: [PATCH 27/28] change return value to S2N_SUCCESS --- tls/s2n_resume.c | 2 +- tls/s2n_server_new_session_ticket.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tls/s2n_resume.c b/tls/s2n_resume.c index 3c9a75651cd..e4c428ba2d4 100644 --- a/tls/s2n_resume.c +++ b/tls/s2n_resume.c @@ -817,7 +817,7 @@ int s2n_encrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer * POSIX_GUARD(s2n_aes256_gcm.destroy_key(&aes_ticket_key)); POSIX_GUARD(s2n_session_key_free(&aes_ticket_key)); - return 0; + return S2N_SUCCESS; } int s2n_decrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *from) diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index d01a9e82c3a..9aef392001d 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -92,7 +92,7 @@ int s2n_server_nst_send(struct s2n_connection *conn) *# NewSessionTicket handshake message. **/ POSIX_GUARD(s2n_stuffer_init(&to, &entry)); - if (!conn->config->use_tickets || s2n_encrypt_session_ticket(conn, &to) != 0) { + if (!conn->config->use_tickets || s2n_encrypt_session_ticket(conn, &to) != S2N_SUCCESS) { POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0)); POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0)); From b2e650d0906868a722bb67a62fc571b03efa4e49 Mon Sep 17 00:00:00 2001 From: Jou Ho <43765840+jouho@users.noreply.github.com> Date: Wed, 15 May 2024 12:39:51 -0700 Subject: [PATCH 28/28] remove unnecessary #define Co-authored-by: Lindsay Stewart --- tests/unit/s2n_server_new_session_ticket_test.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index 826ac937b1b..2dea0697ebe 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -34,8 +34,6 @@ #define MAX_TEST_SESSION_SIZE 300 #define EXPECT_TICKETS_SENT(conn, count) EXPECT_OK(s2n_assert_tickets_sent(conn, count)) -#define S2N_CLOCK_SYS CLOCK_REALTIME - static S2N_RESULT s2n_assert_tickets_sent(struct s2n_connection *conn, uint16_t expected_tickets_sent) { uint16_t tickets_sent = 0;