Skip to content

Commit

Permalink
Reduce memory used by handshake arrays (#2628)
Browse files Browse the repository at this point in the history
  • Loading branch information
lrstewart authored Mar 6, 2021
1 parent f1092c0 commit 3973821
Show file tree
Hide file tree
Showing 20 changed files with 600 additions and 185 deletions.
25 changes: 13 additions & 12 deletions tests/saw/spec/handshake/s2n_handshake_io.cry
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ IS_TLS13_HANDSHAKE conn = conn.actual_protocol_version == S2N_TLS13
ACTIVE_STATE_MACHINE : connection -> [20]handshake_action
ACTIVE_STATE_MACHINE conn = if IS_TLS13_HANDSHAKE conn then tls13_state_machine else state_machine # zero

ACTIVE_HANDSHAKES : connection -> [1024][32][32]
ACTIVE_HANDSHAKES : connection -> [128][32][32]
ACTIVE_HANDSHAKES conn = if IS_TLS13_HANDSHAKE conn then tls13_handshakes else handshakes

ACTIVE_MESSAGE : connection -> [32]
Expand Down Expand Up @@ -257,8 +257,8 @@ state_machine_fn m =
else zero

// A model of the tls1.3 handshake state machine (array handshakes in C)
tls13_handshakes : [1024][32][32]
tls13_handshakes = [tls13_handshakes_fn h | h <- [0..1023]]
tls13_handshakes : [128][32][32]
tls13_handshakes = [tls13_handshakes_fn h | h <- [0..127]]

// A function that gives the tls1.3 handshake sequence for each valid handshake_type.
tls13_handshakes_fn: [32] -> [32][32]
Expand All @@ -285,8 +285,8 @@ tls13_handshakes_fn handshk =
else zero

// A model of the handshake state machine (array handshakes in C)
handshakes : [1024][32][32]
handshakes = [handshakes_fn h | h <- [0..1023]]
handshakes : [128][32][32]
handshakes = [handshakes_fn h | h <- [0..127]]

// A function that gives the handshake sequence for each valid handshake_type.
// This is a sparse encoding of the handshakes array (which is sparse too).
Expand Down Expand Up @@ -481,16 +481,17 @@ RESUME : [32]
RESUME = zero # 0x01
FULL_HANDSHAKE : [32]
FULL_HANDSHAKE = zero # 0x02
CLIENT_AUTH : [32]
CLIENT_AUTH = zero # 0x04
NO_CLIENT_CERT : [32]
NO_CLIENT_CERT = zero # 0x08

PERFECT_FORWARD_SECRECY : [32]
PERFECT_FORWARD_SECRECY= zero # 0x04
PERFECT_FORWARD_SECRECY= zero # 0x10
OCSP_STATUS : [32]
OCSP_STATUS = zero # 0x08
OCSP_STATUS = zero # 0x20
WITH_SESSION_TICKET : [32]
WITH_SESSION_TICKET = zero # 0x20
CLIENT_AUTH : [32]
CLIENT_AUTH = zero # 0x10
NO_CLIENT_CERT : [32]
NO_CLIENT_CERT = zero # 0x40
WITH_SESSION_TICKET = zero # 0x40

S2N_TLS13 : [8]
S2N_TLS13 = 34
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/s2n_cert_chain_and_key_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ int main(int argc, char **argv)
EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));
EXPECT_SUCCESS(s2n_set_server_name(client_conn, "www.alligator.com"));
EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));
EXPECT_TRUE(IS_FULL_HANDSHAKE(server_conn->handshake.handshake_type));
EXPECT_TRUE(IS_FULL_HANDSHAKE(server_conn));
EXPECT_EQUAL(num_times_cb_executed, NUM_TIED_CERTS - 1);
struct s2n_cert_chain_and_key *selected_cert = s2n_connection_get_selected_cert(server_conn);
/* The last alligator certificate should have the highest priority */
Expand Down Expand Up @@ -132,7 +132,7 @@ int main(int argc, char **argv)
EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair));

EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));
EXPECT_TRUE(IS_FULL_HANDSHAKE(server_conn->handshake.handshake_type));
EXPECT_TRUE(IS_FULL_HANDSHAKE(server_conn));
EXPECT_SUCCESS(s2n_shutdown_test_server_and_client(server_conn, client_conn));

EXPECT_SUCCESS(s2n_connection_free(server_conn));
Expand Down
10 changes: 5 additions & 5 deletions tests/unit/s2n_client_auth_handshake_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ int s2n_test_client_auth_negotiation(struct s2n_config *server_config, struct s2
/* Negotiate handshake */
EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn));

EXPECT_TRUE(IS_CLIENT_AUTH_HANDSHAKE(server_conn->handshake.handshake_type));
EXPECT_TRUE(IS_CLIENT_AUTH_HANDSHAKE(client_conn->handshake.handshake_type));
EXPECT_EQUAL(IS_CLIENT_AUTH_NO_CERT(server_conn->handshake.handshake_type), no_cert);
EXPECT_EQUAL(IS_CLIENT_AUTH_NO_CERT(client_conn->handshake.handshake_type), no_cert);
EXPECT_TRUE(IS_CLIENT_AUTH_HANDSHAKE(server_conn));
EXPECT_TRUE(IS_CLIENT_AUTH_HANDSHAKE(client_conn));
EXPECT_EQUAL(IS_CLIENT_AUTH_NO_CERT(server_conn), no_cert);
EXPECT_EQUAL(IS_CLIENT_AUTH_NO_CERT(client_conn), no_cert);

const char *app_data_str = "APPLICATION_DATA";
EXPECT_EQUAL(strcmp(app_data_str, s2n_connection_get_last_message_name(client_conn)), 0);
Expand Down Expand Up @@ -252,7 +252,7 @@ int s2n_test_client_auth_message_by_message(bool no_cert)
} else {
EXPECT_EQUAL(client_conn->handshake.handshake_type, NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | MIDDLEBOX_COMPAT);

/*Client sends CertVerify */
/* Client sends CertVerify */
EXPECT_EQUAL(s2n_conn_get_current_message_type(client_conn), CLIENT_CERT_VERIFY);
EXPECT_SUCCESS(s2n_handshake_write_io(client_conn));
}
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/s2n_handshake_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,11 @@ int test_cipher_preferences(struct s2n_config *server_config, struct s2n_config
EXPECT_EQUAL(server_conn->handshake_params.our_chain_and_key, expected_cert_chain);
EXPECT_EQUAL(server_conn->secure.conn_sig_scheme.sig_alg, expected_sig_alg);

EXPECT_TRUE(IS_NEGOTIATED(server_conn->handshake.handshake_type));
EXPECT_TRUE(IS_NEGOTIATED(client_conn->handshake.handshake_type));
EXPECT_TRUE(IS_NEGOTIATED(server_conn));
EXPECT_TRUE(IS_NEGOTIATED(client_conn));

EXPECT_TRUE(IS_FULL_HANDSHAKE(server_conn->handshake.handshake_type));
EXPECT_TRUE(IS_FULL_HANDSHAKE(client_conn->handshake.handshake_type));
EXPECT_TRUE(IS_FULL_HANDSHAKE(server_conn));
EXPECT_TRUE(IS_FULL_HANDSHAKE(client_conn));

EXPECT_STRING_EQUAL(s2n_connection_get_last_message_name(server_conn), "APPLICATION_DATA");
EXPECT_STRING_EQUAL(s2n_connection_get_last_message_name(client_conn), "APPLICATION_DATA");
Expand Down
276 changes: 276 additions & 0 deletions tests/unit/s2n_handshake_type_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

#include "s2n_test.h"

#include <sys/param.h>

#include "tls/s2n_connection.h"

#define S2N_FIRST_COMMON_HANDSHAKE_FLAG NEGOTIATED
#define S2N_LAST_COMMON_HANDSHAKE_FLAG NO_CLIENT_CERT
#define S2N_FIRST_TLS12_HANDSHAKE_FLAG TLS12_PERFECT_FORWARD_SECRECY
#define S2N_LAST_TLS12_HANDSHAKE_FLAG WITH_SESSION_TICKET
#define S2N_FIRST_TLS13_HANDSHAKE_FLAG HELLO_RETRY_REQUEST
#define S2N_LAST_TLS13_HANDSHAKE_FLAG MIDDLEBOX_COMPAT

int main(int argc, char **argv)
{
BEGIN_TEST();

/* Sanity check test setup */
EXPECT_EQUAL(S2N_FIRST_COMMON_HANDSHAKE_FLAG, 1);
EXPECT_TRUE(S2N_FIRST_COMMON_HANDSHAKE_FLAG < S2N_LAST_COMMON_HANDSHAKE_FLAG);
EXPECT_EQUAL(S2N_FIRST_TLS12_HANDSHAKE_FLAG, S2N_LAST_COMMON_HANDSHAKE_FLAG * 2);
EXPECT_TRUE(S2N_FIRST_TLS12_HANDSHAKE_FLAG < S2N_LAST_TLS12_HANDSHAKE_FLAG);
EXPECT_EQUAL(S2N_FIRST_TLS13_HANDSHAKE_FLAG, S2N_LAST_COMMON_HANDSHAKE_FLAG * 2);
EXPECT_TRUE(S2N_FIRST_TLS13_HANDSHAKE_FLAG < S2N_LAST_TLS13_HANDSHAKE_FLAG);
EXPECT_EQUAL(MAX(S2N_LAST_TLS12_HANDSHAKE_FLAG, S2N_LAST_TLS13_HANDSHAKE_FLAG), S2N_HANDSHAKES_COUNT / 2);

/* Test s2n_handshake_type_reset */
{
struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT);
EXPECT_NOT_NULL(conn);

conn->handshake.handshake_type = 0x12AB;
EXPECT_OK(s2n_handshake_type_reset(conn));
EXPECT_EQUAL(conn->handshake.handshake_type, 0);

EXPECT_OK(s2n_handshake_type_set_flag(conn, FULL_HANDSHAKE));
EXPECT_OK(s2n_handshake_type_reset(conn));
EXPECT_EQUAL(conn->handshake.handshake_type, 0);

EXPECT_OK(s2n_handshake_type_set_flag(conn, 0xFFFF));
EXPECT_OK(s2n_handshake_type_reset(conn));
EXPECT_EQUAL(conn->handshake.handshake_type, 0);

EXPECT_OK(s2n_handshake_type_set_flag(conn, 0));
EXPECT_OK(s2n_handshake_type_reset(conn));
EXPECT_EQUAL(conn->handshake.handshake_type, 0);

EXPECT_SUCCESS(s2n_connection_free(conn));
}

/* Test s2n_handshake_type_set_flag */
{
/* Safety */
EXPECT_ERROR_WITH_ERRNO(s2n_handshake_type_set_flag(NULL, 0), S2N_ERR_NULL);

/* Sets all common flags */
for (s2n_handshake_type_flag flag = S2N_FIRST_COMMON_HANDSHAKE_FLAG; flag <= S2N_LAST_COMMON_HANDSHAKE_FLAG; flag++) {
struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT);
EXPECT_NOT_NULL(conn);

conn->actual_protocol_version = S2N_TLS12;
EXPECT_OK(s2n_handshake_type_set_flag(conn, flag));
EXPECT_EQUAL(conn->handshake.handshake_type, flag);

EXPECT_OK(s2n_handshake_type_reset(conn));

conn->actual_protocol_version = S2N_TLS13;
EXPECT_OK(s2n_handshake_type_set_flag(conn, flag));
EXPECT_EQUAL(conn->handshake.handshake_type, flag);

EXPECT_SUCCESS(s2n_connection_free(conn));
}
}

/* Test s2n_handshake_type_check_flag */
{
/* Safety */
EXPECT_FALSE(s2n_handshake_type_check_flag(NULL, 0));

/* Check when common flags set */
for (s2n_handshake_type_flag flag = S2N_FIRST_COMMON_HANDSHAKE_FLAG; flag <= S2N_LAST_COMMON_HANDSHAKE_FLAG; flag++) {
struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT);
EXPECT_NOT_NULL(conn);

/* All flags set */
{
conn->handshake.handshake_type = 0xFFFF;

conn->actual_protocol_version = S2N_TLS12;
EXPECT_TRUE(s2n_handshake_type_check_flag(conn, flag));

conn->actual_protocol_version = S2N_TLS13;
EXPECT_TRUE(s2n_handshake_type_check_flag(conn, flag));
}

/* No flags set */
{
conn->handshake.handshake_type = 0;

conn->actual_protocol_version = S2N_TLS12;
EXPECT_FALSE(s2n_handshake_type_check_flag(conn, flag));

conn->actual_protocol_version = S2N_TLS13;
EXPECT_FALSE(s2n_handshake_type_check_flag(conn, flag));
}

/* One flag set */
{
conn->handshake.handshake_type = flag;

conn->actual_protocol_version = S2N_TLS12;
EXPECT_TRUE(s2n_handshake_type_check_flag(conn, flag));

conn->actual_protocol_version = S2N_TLS13;
EXPECT_TRUE(s2n_handshake_type_check_flag(conn, flag));
}

EXPECT_SUCCESS(s2n_connection_free(conn));
}
}

/* Test s2n_handshake_type_set_tls12_flag */
{
/* Safety */
EXPECT_ERROR_WITH_ERRNO(s2n_handshake_type_set_tls12_flag(NULL, 0), S2N_ERR_NULL);

/* Sets all TLS1.2 flags */
for (s2n_tls12_handshake_type_flag flag = S2N_FIRST_TLS12_HANDSHAKE_FLAG; flag <= S2N_LAST_TLS12_HANDSHAKE_FLAG; flag++) {
struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT);
EXPECT_NOT_NULL(conn);

conn->actual_protocol_version = S2N_TLS12;
EXPECT_OK(s2n_handshake_type_set_tls12_flag(conn, flag));
EXPECT_EQUAL(conn->handshake.handshake_type, flag);

EXPECT_OK(s2n_handshake_type_reset(conn));

conn->actual_protocol_version = S2N_TLS13;
EXPECT_ERROR_WITH_ERRNO(s2n_handshake_type_set_tls12_flag(conn, flag), S2N_ERR_HANDSHAKE_STATE);

EXPECT_SUCCESS(s2n_connection_free(conn));
}
}

/* Test s2n_handshake_type_check_tls12_flag */
{
/* Safety */
EXPECT_FALSE(s2n_handshake_type_check_tls12_flag(NULL, 0));

/* Check when common flags set */
for (s2n_tls12_handshake_type_flag flag = S2N_FIRST_TLS12_HANDSHAKE_FLAG; flag <= S2N_LAST_TLS12_HANDSHAKE_FLAG; flag++) {
struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT);
EXPECT_NOT_NULL(conn);

/* All flags set */
{
conn->handshake.handshake_type = 0xFFFF;

conn->actual_protocol_version = S2N_TLS12;
EXPECT_TRUE(s2n_handshake_type_check_tls12_flag(conn, flag));

conn->actual_protocol_version = S2N_TLS13;
EXPECT_FALSE(s2n_handshake_type_check_tls12_flag(conn, flag));
}

/* No flags set */
{
conn->handshake.handshake_type = 0;

conn->actual_protocol_version = S2N_TLS12;
EXPECT_FALSE(s2n_handshake_type_check_tls12_flag(conn, flag));

conn->actual_protocol_version = S2N_TLS13;
EXPECT_FALSE(s2n_handshake_type_check_tls12_flag(conn, flag));
}

/* One flag set */
{
conn->handshake.handshake_type = flag;

conn->actual_protocol_version = S2N_TLS12;
EXPECT_TRUE(s2n_handshake_type_check_tls12_flag(conn, flag));

conn->actual_protocol_version = S2N_TLS13;
EXPECT_FALSE(s2n_handshake_type_check_tls12_flag(conn, flag));
}

EXPECT_SUCCESS(s2n_connection_free(conn));
}
}

/* Test s2n_handshake_type_set_tls13_flag */
{
/* Safety */
EXPECT_ERROR_WITH_ERRNO(s2n_handshake_type_set_tls13_flag(NULL, 0), S2N_ERR_NULL);

/* Sets all TLS1.3 flags */
for (s2n_tls13_handshake_type_flag flag = S2N_FIRST_TLS13_HANDSHAKE_FLAG; flag <= S2N_LAST_TLS13_HANDSHAKE_FLAG; flag++) {
struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT);
EXPECT_NOT_NULL(conn);

conn->actual_protocol_version = S2N_TLS13;
EXPECT_OK(s2n_handshake_type_set_tls13_flag(conn, flag));
EXPECT_EQUAL(conn->handshake.handshake_type, flag);

conn->actual_protocol_version = S2N_TLS12;
EXPECT_ERROR_WITH_ERRNO(s2n_handshake_type_set_tls13_flag(conn, flag), S2N_ERR_HANDSHAKE_STATE);

EXPECT_SUCCESS(s2n_connection_free(conn));
}
}

/* Test s2n_handshake_type_check_tls13_flag */
{
/* Safety */
EXPECT_FALSE(s2n_handshake_type_check_tls13_flag(NULL, 0));

/* Check when common flags set */
for (s2n_tls13_handshake_type_flag flag = S2N_FIRST_TLS13_HANDSHAKE_FLAG; flag <= S2N_LAST_TLS13_HANDSHAKE_FLAG; flag++) {
struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT);
EXPECT_NOT_NULL(conn);

/* All flags set */
{
conn->handshake.handshake_type = 0xFFFF;

conn->actual_protocol_version = S2N_TLS12;
EXPECT_FALSE(s2n_handshake_type_check_tls13_flag(conn, flag));

conn->actual_protocol_version = S2N_TLS13;
EXPECT_TRUE(s2n_handshake_type_check_tls13_flag(conn, flag));
}

/* No flags set */
{
conn->handshake.handshake_type = 0;

conn->actual_protocol_version = S2N_TLS12;
EXPECT_FALSE(s2n_handshake_type_check_tls13_flag(conn, flag));

conn->actual_protocol_version = S2N_TLS13;
EXPECT_FALSE(s2n_handshake_type_check_tls13_flag(conn, flag));
}

/* One flag set */
{
conn->handshake.handshake_type = flag;

conn->actual_protocol_version = S2N_TLS12;
EXPECT_FALSE(s2n_handshake_type_check_tls13_flag(conn, flag));

conn->actual_protocol_version = S2N_TLS13;
EXPECT_TRUE(s2n_handshake_type_check_tls13_flag(conn, flag));
}

EXPECT_SUCCESS(s2n_connection_free(conn));
}
}

END_TEST();
}
Loading

0 comments on commit 3973821

Please sign in to comment.