diff --git a/error/s2n_errno.c b/error/s2n_errno.c index cea807ba489..49aab545c09 100644 --- a/error/s2n_errno.c +++ b/error/s2n_errno.c @@ -201,7 +201,7 @@ static const char *no_such_error = "Internal s2n error"; ERR_ENTRY(S2N_ERR_CLIENT_MODE, "Operation not allowed in client mode") \ ERR_ENTRY(S2N_ERR_CLIENT_MODE_DISABLED, "client connections not allowed") \ ERR_ENTRY(S2N_ERR_TOO_MANY_CERTIFICATES, "only 1 certificate is supported in client mode") \ - ERR_ENTRY(S2N_ERR_TOO_MANY_SIGNATURE_SCHEMES, "Max supported length of SignatureAlgorithms/SignatureSchemes list is 32") \ + ERR_ENTRY(S2N_ERR_TOO_MANY_SIGNATURE_SCHEMES, "Max supported length of SignatureAlgorithms/SignatureSchemes list is 128") \ ERR_ENTRY(S2N_ERR_CLIENT_AUTH_NOT_SUPPORTED_IN_FIPS_MODE, "Client Auth is not supported when in FIPS mode") \ ERR_ENTRY(S2N_ERR_INVALID_BASE64, "invalid base64 encountered") \ ERR_ENTRY(S2N_ERR_INVALID_HEX, "invalid HEX encountered") \ diff --git a/tests/unit/s2n_client_signature_algorithms_extension_test.c b/tests/unit/s2n_client_signature_algorithms_extension_test.c index 14e8581c6d7..0b4c8b7f5cb 100644 --- a/tests/unit/s2n_client_signature_algorithms_extension_test.c +++ b/tests/unit/s2n_client_signature_algorithms_extension_test.c @@ -64,7 +64,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_client_signature_algorithms_extension.recv(server_conn, &io)); EXPECT_EQUAL(s2n_stuffer_data_available(&io), 0); - EXPECT_TRUE(server_conn->handshake_params.client_sig_hash_algs.len > 0); + EXPECT_TRUE(server_conn->handshake_params.peer_sig_scheme_list.len > 0); s2n_stuffer_free(&io); s2n_connection_free(client_conn); @@ -91,7 +91,7 @@ int main(int argc, char **argv) /* If a valid algorithm is offered among unknown algorithms, the valid one should be chosen */ EXPECT_SUCCESS(s2n_client_signature_algorithms_extension.recv(conn, &signature_algorithms_extension)); - EXPECT_EQUAL(conn->handshake_params.client_sig_hash_algs.len, sig_hash_algs.len); + EXPECT_EQUAL(conn->handshake_params.peer_sig_scheme_list.len, sig_hash_algs.len); EXPECT_OK(s2n_signature_algorithm_select(conn)); EXPECT_EQUAL(conn->handshake_params.server_cert_sig_scheme->iana_value, TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA384); diff --git a/tests/unit/s2n_server_signature_algorithms_extension_test.c b/tests/unit/s2n_server_signature_algorithms_extension_test.c index 458e2664950..bd981dfb81d 100644 --- a/tests/unit/s2n_server_signature_algorithms_extension_test.c +++ b/tests/unit/s2n_server_signature_algorithms_extension_test.c @@ -44,7 +44,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_server_signature_algorithms_extension.recv(client_conn, &io)); EXPECT_EQUAL(s2n_stuffer_data_available(&io), 0); - EXPECT_TRUE(client_conn->handshake_params.server_sig_hash_algs.len > 0); + EXPECT_TRUE(client_conn->handshake_params.peer_sig_scheme_list.len > 0); s2n_stuffer_free(&io); EXPECT_SUCCESS(s2n_connection_free(server_conn)); diff --git a/tests/unit/s2n_signature_algorithms_test.c b/tests/unit/s2n_signature_algorithms_test.c index ebcfa015a00..fdbdf36c0f0 100644 --- a/tests/unit/s2n_signature_algorithms_test.c +++ b/tests/unit/s2n_signature_algorithms_test.c @@ -254,7 +254,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, test_schemes, s2n_array_len(test_schemes))); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.server_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, test_schemes, s2n_array_len(test_schemes))); /* Test: ECDSA */ @@ -301,7 +301,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, test_schemes, s2n_array_len(test_schemes))); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, test_schemes, s2n_array_len(test_schemes))); /* Test: ECDSA */ @@ -348,7 +348,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, &expected, 1)); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.server_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, &expected, 1)); EXPECT_OK(s2n_signature_algorithm_select(conn)); @@ -367,7 +367,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, &expected, 1)); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.server_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, &expected, 1)); EXPECT_OK(s2n_signature_algorithm_select(conn)); @@ -398,7 +398,7 @@ int main(int argc, char **argv) { EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, order, s2n_array_len(order))); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, reversed_order, s2n_array_len(reversed_order))); EXPECT_OK(s2n_signature_algorithm_select(conn)); @@ -409,7 +409,7 @@ int main(int argc, char **argv) { EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, reversed_order, s2n_array_len(reversed_order))); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, order, s2n_array_len(order))); EXPECT_OK(s2n_signature_algorithm_select(conn)); @@ -422,7 +422,7 @@ int main(int argc, char **argv) { EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, order, s2n_array_len(order))); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, order, s2n_array_len(order))); EXPECT_OK(s2n_signature_algorithm_select(conn)); @@ -444,7 +444,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, &invalid, 1)); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, &invalid, 1)); /* Fails for TLS1.3 */ @@ -471,7 +471,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, &invalid, 1)); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, &invalid, 1)); /* Fails for TLS1.2 */ @@ -505,7 +505,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, &invalid, 1)); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, &invalid, 1)); /* Fails with SHA1 */ @@ -536,7 +536,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, &invalid, 1)); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, &invalid, 1)); /* Fails for pkcs1 */ @@ -563,7 +563,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, &scheme, 1)); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.server_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, &scheme, 1)); /* Fails for default config with no certs */ @@ -594,7 +594,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, &scheme, 1)); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.server_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, &scheme, 1)); /* Fails for default config with no certs */ @@ -634,7 +634,7 @@ int main(int argc, char **argv) /* Fails with wrong curve (256) */ EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, &ecdsa256, 1)); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, &ecdsa256, 1)); EXPECT_ERROR_WITH_ERRNO( s2n_signature_algorithm_select(conn), @@ -643,7 +643,7 @@ int main(int argc, char **argv) /* Succeeds with right curve (384) */ EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, &ecdsa384, 1)); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, &ecdsa384, 1)); EXPECT_OK(s2n_signature_algorithm_select(conn)); }; @@ -673,7 +673,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, schemes, s2n_array_len(schemes))); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.server_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, schemes, s2n_array_len(schemes))); EXPECT_OK(s2n_signature_algorithm_select(conn)); @@ -702,7 +702,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, local_schemes, s2n_array_len(local_schemes))); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, peer_schemes, s2n_array_len(peer_schemes))); EXPECT_OK(s2n_signature_algorithm_select(conn)); @@ -852,7 +852,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, local_schemes, s2n_array_len(local_schemes))); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, peer_schemes, s2n_array_len(peer_schemes))); /* ECDSA */ @@ -893,7 +893,7 @@ int main(int argc, char **argv) struct s2n_local_sig_schemes_context local_context = { 0 }; EXPECT_OK(s2n_test_set_local_sig_schemes(conn, &local_context, local_schemes, s2n_array_len(local_schemes))); - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, peer_schemes, s2n_array_len(peer_schemes))); EXPECT_OK(s2n_signature_algorithm_select(conn)); @@ -1056,6 +1056,30 @@ int main(int argc, char **argv) }; }; + /* Test: Ensure that the maximum number of permitted signature schemes can be received. */ + const uint16_t max_sig_schemes = TLS_SIGNATURE_SCHEME_LIST_MAX_LEN; + for (uint16_t count = max_sig_schemes - 1; count <= max_sig_schemes + 1; count++) { + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + + DEFER_CLEANUP(struct s2n_stuffer input = { 0 }, s2n_stuffer_free); + EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&input, 0)); + + uint16_t sig_scheme_list_size = count * TLS_SIGNATURE_SCHEME_LEN; + EXPECT_SUCCESS(s2n_stuffer_write_uint16(&input, sig_scheme_list_size)); + for (size_t i = 0; i < count; i++) { + EXPECT_SUCCESS(s2n_stuffer_write_uint16(&input, s2n_rsa_pkcs1_sha256.iana_value)); + } + + int ret = s2n_recv_supported_sig_scheme_list(&input, &conn->handshake_params.peer_sig_scheme_list); + if (count <= max_sig_schemes) { + EXPECT_SUCCESS(ret); + } else { + EXPECT_FAILURE_WITH_ERRNO(ret, S2N_ERR_TOO_MANY_SIGNATURE_SCHEMES); + } + } + /* Test: send and receive default signature preferences */ for (size_t i = S2N_TLS10; i < S2N_TLS13; i++) { DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT), @@ -1162,7 +1186,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); const struct s2n_signature_scheme *schemes[] = { &s2n_rsa_pss_rsae_sha256 }; - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.server_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, schemes, s2n_array_len(schemes))); if (s2n_is_rsa_pss_signing_supported()) { @@ -1187,7 +1211,7 @@ int main(int argc, char **argv) /* Invalid (PKCS1 not allowed by TLS1.3) */ const struct s2n_signature_scheme *peer_schemes[] = { &s2n_rsa_pkcs1_sha224 }; - EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.client_sig_hash_algs, + EXPECT_OK(s2n_test_set_peer_sig_schemes(&conn->handshake_params.peer_sig_scheme_list, peer_schemes, s2n_array_len(peer_schemes))); /* Both PKCS1 and PSS supported */ diff --git a/tests/unit/s2n_tls13_cert_request_extensions_test.c b/tests/unit/s2n_tls13_cert_request_extensions_test.c index f4bb6e31496..970bb4152a9 100644 --- a/tests/unit/s2n_tls13_cert_request_extensions_test.c +++ b/tests/unit/s2n_tls13_cert_request_extensions_test.c @@ -37,10 +37,10 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->actual_protocol_version = S2N_TLS13; - EXPECT_EQUAL(conn->handshake_params.server_sig_hash_algs.len, 0); + EXPECT_EQUAL(conn->handshake_params.peer_sig_scheme_list.len, 0); EXPECT_SUCCESS(s2n_tls13_cert_req_send(conn)); EXPECT_SUCCESS(s2n_tls13_cert_req_recv(conn)); - EXPECT_NOT_EQUAL(conn->handshake_params.server_sig_hash_algs.len, 0); + EXPECT_NOT_EQUAL(conn->handshake_params.peer_sig_scheme_list.len, 0); EXPECT_SUCCESS(s2n_connection_free(conn)); } diff --git a/tests/unit/s2n_tls13_cert_request_test.c b/tests/unit/s2n_tls13_cert_request_test.c index aa8d1f8ccf7..c4da6d55181 100644 --- a/tests/unit/s2n_tls13_cert_request_test.c +++ b/tests/unit/s2n_tls13_cert_request_test.c @@ -69,7 +69,7 @@ int main(int argc, char **argv) EXPECT_TRUE(s2n_stuffer_data_available(&client_conn->handshake.io) > 0); EXPECT_SUCCESS(s2n_tls13_cert_req_recv(client_conn)); - EXPECT_TRUE(client_conn->handshake_params.server_sig_hash_algs.len > 0); + EXPECT_TRUE(client_conn->handshake_params.peer_sig_scheme_list.len > 0); EXPECT_SUCCESS(s2n_connection_free(client_conn)); EXPECT_SUCCESS(s2n_connection_free(server_conn)); diff --git a/tls/extensions/s2n_client_signature_algorithms.c b/tls/extensions/s2n_client_signature_algorithms.c index c1f06daf2e6..5cc74c7b4ca 100644 --- a/tls/extensions/s2n_client_signature_algorithms.c +++ b/tls/extensions/s2n_client_signature_algorithms.c @@ -49,5 +49,5 @@ static int s2n_client_signature_algorithms_send(struct s2n_connection *conn, str static int s2n_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) { - return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.client_sig_hash_algs); + return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.peer_sig_scheme_list); } diff --git a/tls/extensions/s2n_server_signature_algorithms.c b/tls/extensions/s2n_server_signature_algorithms.c index 7599a58a984..70651e33d6c 100644 --- a/tls/extensions/s2n_server_signature_algorithms.c +++ b/tls/extensions/s2n_server_signature_algorithms.c @@ -44,5 +44,5 @@ static int s2n_signature_algorithms_send(struct s2n_connection *conn, struct s2n static int s2n_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) { - return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.server_sig_hash_algs); + return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.peer_sig_scheme_list); } diff --git a/tls/s2n_handshake.h b/tls/s2n_handshake.h index d589eafc880..da2a121c576 100644 --- a/tls/s2n_handshake.h +++ b/tls/s2n_handshake.h @@ -104,13 +104,15 @@ struct s2n_handshake_parameters { struct s2n_blob client_cert_chain; s2n_pkey_type client_cert_pkey_type; - /* Signature/hash algorithm pairs offered by the client in the signature_algorithms extension */ - struct s2n_sig_scheme_list client_sig_hash_algs; + /* Signature/hash algorithm pairs offered by the peer. + * + * In the case of server connections, this list contains the client's supported signature + * schemes offered in the ClientHello. In the case of client connections, this list contains + * the server's supported signature schemes offered in the CertificateRequest. + */ + struct s2n_sig_scheme_list peer_sig_scheme_list; /* Signature scheme chosen by the server */ const struct s2n_signature_scheme *server_cert_sig_scheme; - - /* Signature/hash algorithm pairs offered by the server in the certificate request */ - struct s2n_sig_scheme_list server_sig_hash_algs; /* Signature scheme chosen by the client */ const struct s2n_signature_scheme *client_cert_sig_scheme; diff --git a/tls/s2n_server_cert_request.c b/tls/s2n_server_cert_request.c index ad36af6dd54..44b62b68e61 100644 --- a/tls/s2n_server_cert_request.c +++ b/tls/s2n_server_cert_request.c @@ -121,7 +121,7 @@ int s2n_cert_req_recv(struct s2n_connection *conn) POSIX_GUARD(s2n_recv_client_cert_preferences(in, &cert_type)); if (conn->actual_protocol_version == S2N_TLS12) { - POSIX_GUARD(s2n_recv_supported_sig_scheme_list(in, &conn->handshake_params.server_sig_hash_algs)); + POSIX_GUARD(s2n_recv_supported_sig_scheme_list(in, &conn->handshake_params.peer_sig_scheme_list)); } uint16_t cert_authorities_len = 0; diff --git a/tls/s2n_signature_algorithms.c b/tls/s2n_signature_algorithms.c index f805512a510..4f3cd8895a4 100644 --- a/tls/s2n_signature_algorithms.c +++ b/tls/s2n_signature_algorithms.c @@ -161,13 +161,7 @@ static S2N_RESULT s2n_signature_algorithms_validate_supported_by_peer( { RESULT_ENSURE_REF(conn); - const struct s2n_sig_scheme_list *peer_list = NULL; - if (conn->mode == S2N_CLIENT) { - peer_list = &conn->handshake_params.server_sig_hash_algs; - } else { - peer_list = &conn->handshake_params.client_sig_hash_algs; - } - + const struct s2n_sig_scheme_list *peer_list = &conn->handshake_params.peer_sig_scheme_list; for (size_t i = 0; i < peer_list->len; i++) { if (peer_list->iana_list[i] == iana) { return S2N_RESULT_OK; diff --git a/tls/s2n_tls_parameters.h b/tls/s2n_tls_parameters.h index 02a12211aca..cc34c33113a 100644 --- a/tls/s2n_tls_parameters.h +++ b/tls/s2n_tls_parameters.h @@ -157,7 +157,7 @@ #define TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA512 0x080B #define TLS_SIGNATURE_SCHEME_LEN 2 -#define TLS_SIGNATURE_SCHEME_LIST_MAX_LEN 64 +#define TLS_SIGNATURE_SCHEME_LIST_MAX_LEN 128 /* The TLS record types we support */ #define SSLv2_CLIENT_HELLO 1