Skip to content

Commit

Permalink
feat: Turns off automatic ticket creation for quic (#4239)
Browse files Browse the repository at this point in the history
  • Loading branch information
maddeleine authored Oct 12, 2023
1 parent 2d05302 commit a2b16d2
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 0 deletions.
135 changes: 135 additions & 0 deletions tests/unit/s2n_self_talk_session_resumption_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,36 @@ static S2N_RESULT s2n_test_negotiate(struct s2n_connection *server_conn, struct
return S2N_RESULT_OK;
}

static int s2n_wipe_psk_ke_ext(struct s2n_connection *conn, void *ctx)
{
struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(conn);
POSIX_ENSURE_REF(client_hello);
s2n_parsed_extension *parsed_extension = NULL;
POSIX_GUARD(s2n_client_hello_get_parsed_extension(TLS_EXTENSION_PSK_KEY_EXCHANGE_MODES, &client_hello->extensions, &parsed_extension));
POSIX_ENSURE_REF(parsed_extension);
POSIX_GUARD(s2n_blob_zero(&parsed_extension->extension));

return S2N_SUCCESS;
}

static int s2n_alter_psk_ke_ext(struct s2n_connection *conn, void *ctx)
{
struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(conn);
POSIX_ENSURE_REF(client_hello);
s2n_parsed_extension *parsed_extension = NULL;
POSIX_GUARD(s2n_client_hello_get_parsed_extension(TLS_EXTENSION_PSK_KEY_EXCHANGE_MODES, &client_hello->extensions, &parsed_extension));
POSIX_ENSURE_REF(parsed_extension);

/* Overwrite the extension so it only supports PSK_KE mode */
struct s2n_stuffer psk_ke_extension = { 0 };
POSIX_GUARD(s2n_stuffer_init(&psk_ke_extension, &parsed_extension->extension));
POSIX_GUARD(s2n_stuffer_skip_write(&psk_ke_extension, 1));
uint8_t mode = TLS_PSK_KE_MODE;
POSIX_GUARD(s2n_stuffer_write_bytes(&psk_ke_extension, &mode, 1));

return S2N_SUCCESS;
}

int main(int argc, char **argv)
{
BEGIN_TEST();
Expand Down Expand Up @@ -1099,6 +1129,111 @@ int main(int argc, char **argv)
EXPECT_SUCCESS(s2n_stuffer_rewrite(&cb_session_data));
}

/* Functional: Server in QUIC mode does not send a session ticket if psk_ke extension was not received */
{
DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free);
EXPECT_NOT_NULL(client_conn);

DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free);
EXPECT_NOT_NULL(server_conn);

EXPECT_SUCCESS(s2n_connection_set_config(client_conn, tls13_client_config));
EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

/* Enable QUIC mode */
EXPECT_SUCCESS(s2n_connection_enable_quic(client_conn));
EXPECT_SUCCESS(s2n_connection_enable_quic(server_conn));

/* Create nonblocking pipes */
DEFER_CLEANUP(struct s2n_stuffer input = { 0 }, s2n_stuffer_free);
DEFER_CLEANUP(struct s2n_stuffer output = { 0 }, s2n_stuffer_free);
EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&input, 0));
EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&output, 0));
EXPECT_SUCCESS(s2n_connection_set_io_stuffers(&input, &output, server_conn));
EXPECT_SUCCESS(s2n_connection_set_io_stuffers(&output, &input, client_conn));

/* Wipe psk_ke extension when it is received */
EXPECT_SUCCESS(s2n_config_set_client_hello_cb(server_config, s2n_wipe_psk_ke_ext, NULL));

/* Negotiate handshake */
EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));

/* Server did not send a ticket since the client did not send the psk_ke extension */
uint16_t tickets_sent = 0;
EXPECT_SUCCESS(s2n_connection_get_tickets_sent(server_conn, &tickets_sent));
EXPECT_EQUAL(tickets_sent, 0);
};

/* Functional: Server in QUIC mode does not send a session ticket if psk_ke extension does not support psk_dhe_ke */
{
DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free);
EXPECT_NOT_NULL(client_conn);

DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free);
EXPECT_NOT_NULL(server_conn);

EXPECT_SUCCESS(s2n_connection_set_config(client_conn, tls13_client_config));
EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

/* Enable QUIC mode */
EXPECT_SUCCESS(s2n_connection_enable_quic(client_conn));
EXPECT_SUCCESS(s2n_connection_enable_quic(server_conn));

/* Create nonblocking pipes */
DEFER_CLEANUP(struct s2n_stuffer input = { 0 }, s2n_stuffer_free);
DEFER_CLEANUP(struct s2n_stuffer output = { 0 }, s2n_stuffer_free);
EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&input, 0));
EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&output, 0));
EXPECT_SUCCESS(s2n_connection_set_io_stuffers(&input, &output, server_conn));
EXPECT_SUCCESS(s2n_connection_set_io_stuffers(&output, &input, client_conn));

/* Alter psk_ke extension when it is received so that it only supports psk_ke mode */
EXPECT_SUCCESS(s2n_config_set_client_hello_cb(server_config, s2n_alter_psk_ke_ext, NULL));

/* Negotiate handshake */
EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));

/* Server did not send a ticket since the client does not support psk_dhe_ke mode */
uint16_t tickets_sent = 0;
EXPECT_SUCCESS(s2n_connection_get_tickets_sent(server_conn, &tickets_sent));
EXPECT_EQUAL(tickets_sent, 0);
};

/* Functional: Server in QUIC mode sends a session ticket if the client indicates it supports psk_dhe_ke mode */
{
DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free);
EXPECT_NOT_NULL(client_conn);

DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free);
EXPECT_NOT_NULL(server_conn);

EXPECT_SUCCESS(s2n_connection_set_config(client_conn, tls13_client_config));
EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

/* Enable QUIC mode */
EXPECT_SUCCESS(s2n_connection_enable_quic(client_conn));
EXPECT_SUCCESS(s2n_connection_enable_quic(server_conn));

/* Create nonblocking pipes */
DEFER_CLEANUP(struct s2n_stuffer input = { 0 }, s2n_stuffer_free);
DEFER_CLEANUP(struct s2n_stuffer output = { 0 }, s2n_stuffer_free);
EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&input, 0));
EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&output, 0));
EXPECT_SUCCESS(s2n_connection_set_io_stuffers(&input, &output, server_conn));
EXPECT_SUCCESS(s2n_connection_set_io_stuffers(&output, &input, client_conn));

/* Disable any client hello cb changes */
EXPECT_SUCCESS(s2n_config_set_client_hello_cb(server_config, NULL, NULL));

/* Negotiate handshake */
EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));

/* Server sent one ticket since the client by default indicates it supports psk_dhe_ke mode */
uint16_t tickets_sent = 0;
EXPECT_SUCCESS(s2n_connection_get_tickets_sent(server_conn, &tickets_sent));
EXPECT_EQUAL(tickets_sent, 1);
};

/* Clean-up */
EXPECT_SUCCESS(s2n_config_free(server_config));
EXPECT_SUCCESS(s2n_config_free(tls12_server_config));
Expand Down
32 changes: 32 additions & 0 deletions tests/unit/s2n_server_new_session_ticket_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,38 @@ int main(int argc, char **argv)
EXPECT_SUCCESS(s2n_config_free(config));
};

/* QUIC mode is enabled */
{
DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(),
s2n_config_ptr_free);
EXPECT_NOT_NULL(config);
EXPECT_SUCCESS(s2n_setup_test_ticket_key(config));

DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER),
s2n_connection_ptr_free);
EXPECT_NOT_NULL(conn);
EXPECT_SUCCESS(s2n_connection_set_config(conn, config));
conn->secure->cipher_suite = &s2n_tls13_aes_128_gcm_sha256;
conn->tickets_to_send = 1;
conn->actual_protocol_version = S2N_TLS13;

DEFER_CLEANUP(struct s2n_stuffer stuffer = { 0 }, s2n_stuffer_free);
EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0));
EXPECT_SUCCESS(s2n_connection_set_io_stuffers(&stuffer, &stuffer, conn));

s2n_blocked_status blocked = 0;

conn->quic_enabled = true;
/* No mutually-supported psk mode agreed upon */
EXPECT_OK(s2n_tls13_server_nst_send(conn, &blocked));
EXPECT_TICKETS_SENT(conn, 0);

/* Client has indicated that it supports both resumption and psk_dhe_ke mode */
conn->psk_params.psk_ke_mode = S2N_PSK_DHE_KE;
EXPECT_OK(s2n_tls13_server_nst_send(conn, &blocked));
EXPECT_TICKETS_SENT(conn, 1);
};

/* Sends one new session ticket */
{
struct s2n_config *config;
Expand Down
8 changes: 8 additions & 0 deletions tls/s2n_server_new_session_ticket.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ S2N_RESULT s2n_tls13_server_nst_send(struct s2n_connection *conn, s2n_blocked_st
return S2N_RESULT_OK;
}

/* Legacy behavior is that the s2n server sends a NST even if the client did not indicate support
* for resumption or does not support the psk_dhe_ke mode. This is potentially wasteful so we
* choose to not extend this behavior to QUIC.
*/
if (conn->quic_enabled && conn->psk_params.psk_ke_mode != S2N_PSK_DHE_KE) {
return S2N_RESULT_OK;
}

/* No-op if all tickets already sent.
* Clean up the stuffer used for the ticket to conserve memory. */
if (conn->tickets_to_send == conn->tickets_sent) {
Expand Down

0 comments on commit a2b16d2

Please sign in to comment.