Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Send zero-length NST when session key is expired #4532

Merged
merged 36 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2e48de1
send zero-length NST when session key is expired
jouho Apr 30, 2024
becb306
add another to test the impact on tls 1.3 path
jouho Apr 30, 2024
e023d46
check if tls1.3 is fully supported
jouho Apr 30, 2024
edff88a
use shorter variable names
jouho May 1, 2024
f22a5b9
Merge branch 'main' into zero-length-tls12-NST-message
jouho May 1, 2024
8352bce
Merge branch 'main' into zero-length-tls12-NST-message
jouho May 1, 2024
c4a5474
modify test setups
jouho May 1, 2024
9beba2c
address comment
jouho May 1, 2024
8ead510
add compliance comments
jouho May 1, 2024
8838bdf
Merge branch 'main' into zero-length-tls12-NST-message
jouho May 1, 2024
ab18c07
add unit test for s2n_server_send
jouho May 6, 2024
c1948e8
Merge branch 'main' into zero-length-tls12-NST-message
jouho May 6, 2024
e86b5b3
address clang format issues
jouho May 6, 2024
ae343b8
edit rfc comment format
jouho May 6, 2024
9302a3a
fix rfc number
jouho May 6, 2024
112574c
remove unnecessary expect_false()
jouho May 6, 2024
82709ee
add test case for sending non-zero nst
jouho May 6, 2024
8118b83
use suggested comment
jouho May 7, 2024
aad3a35
remove unnecessary test case
jouho May 7, 2024
13ec6d3
check all data is read
jouho May 7, 2024
1c8b71d
give better test description
jouho May 7, 2024
0a4c8ee
add compliance comment to the test
jouho May 7, 2024
9ff9261
fix comment format
jouho May 7, 2024
474f40f
Merge branch 'main' into zero-length-tls12-NST-message
jouho May 7, 2024
4fc4de4
Merge branch 'main' into zero-length-tls12-NST-message
jouho May 8, 2024
3554753
verify ticket length and and lifetime hint is 0
jouho May 8, 2024
ca92f58
fix input orders
jouho May 8, 2024
14d56a3
address PR feedbacks
jouho May 8, 2024
6b3ace8
send zero-length nst upon failing to retrieve encrypt key
jouho May 13, 2024
9b09e91
address linter issue
jouho May 13, 2024
8aeedd3
Merge branch 'main' into zero-length-tls12-NST-message
jouho May 13, 2024
907da2b
address redundant code
jouho May 13, 2024
ab7c57d
remove unnecessary test setup
jouho May 15, 2024
1bf7d88
change return value to S2N_SUCCESS
jouho May 15, 2024
8ee8b0f
Merge branch 'main' into zero-length-tls12-NST-message
jouho May 15, 2024
b2e650d
remove unnecessary #define
jouho May 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
120 changes: 120 additions & 0 deletions tests/unit/s2n_session_ticket_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,126 @@ 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
*/
{
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"));
jouho marked this conversation as resolved.
Show resolved Hide resolved
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));
jouho marked this conversation as resolved.
Show resolved Hide resolved
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_session(client, serialized_session_state,
jouho marked this conversation as resolved.
Show resolved Hide resolved
serialized_session_state_length));
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 */
jouho marked this conversation as resolved.
Show resolved Hide resolved
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 send a zero-length NST message */
EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, SERVER_FINISHED));
jouho marked this conversation as resolved.
Show resolved Hide resolved

/* 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 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);
jouho marked this conversation as resolved.
Show resolved Hide resolved
}
jouho marked this conversation as resolved.
Show resolved Hide resolved

/* Test TLS 1.3 Server does not send a zero-length ticket in the NewSessionTicket handshake
jouho marked this conversation as resolved.
Show resolved Hide resolved
* 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_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),
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_OK(s2n_negotiate_test_server_and_client_until_message(server, client, SERVER_FINISHED));

/* 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));
jouho marked this conversation as resolved.
Show resolved Hide resolved
}

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));
Expand Down
6 changes: 4 additions & 2 deletions tls/s2n_server_new_session_ticket.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 if session key used to encrypt session ticket
maddeleine marked this conversation as resolved.
Show resolved Hide resolved
jouho marked this conversation as resolved.
Show resolved Hide resolved
* 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)) {
jouho marked this conversation as resolved.
Show resolved Hide resolved
POSIX_GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0));
POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0));

Expand Down