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

feat: TLS1.2 support for RSA-PSS certificates #4927

Merged
merged 3 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions tests/unit/s2n_security_policies_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,12 @@ int main(int argc, char **argv)
for (size_t i = 0; i < security_policy->signature_preferences->count; i++) {
int min = security_policy->signature_preferences->signature_schemes[i]->minimum_protocol_version;
int max = security_policy->signature_preferences->signature_schemes[i]->maximum_protocol_version;
if (max == S2N_UNKNOWN_PROTOCOL_VERSION) {
max = S2N_TLS13;
}
s2n_signature_algorithm sig_alg = security_policy->signature_preferences->signature_schemes[i]->sig_alg;

if (min == S2N_TLS13 || max >= S2N_TLS13) {
if (min <= S2N_TLS13 && max >= S2N_TLS13) {
has_tls_13_sig_alg = true;
}

Expand Down Expand Up @@ -825,8 +828,8 @@ int main(int argc, char **argv)
}
}

/* If scheme will be used for pre-tls1.3 */
if (min_version < S2N_TLS13) {
/* If scheme will be used for legacy versions */
if (min_version < S2N_TLS12) {
EXPECT_NOT_EQUAL(scheme->sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
}
}
Expand Down
141 changes: 141 additions & 0 deletions tests/unit/s2n_self_talk_certificates_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* 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 "crypto/s2n_rsa_pss.h"
#include "s2n_test.h"
#include "testlib/s2n_testlib.h"
#include "tls/s2n_tls.h"

static uint8_t s2n_noop_verify_host_fn(const char *name, size_t len, void *data)
{
return 1;
}

static S2N_RESULT s2n_test_load_certificate(struct s2n_cert_chain_and_key **chain_out,
char *chain_pem_out, const char *chain_pem_path, const char *key_pem_path)
{
RESULT_ENSURE_REF(chain_out);

char key_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 };
RESULT_GUARD_POSIX(s2n_read_test_pem(chain_pem_path, chain_pem_out, S2N_MAX_TEST_PEM_SIZE));
RESULT_GUARD_POSIX(s2n_read_test_pem(key_pem_path, key_pem, S2N_MAX_TEST_PEM_SIZE));

*chain_out = s2n_cert_chain_and_key_new();
RESULT_ENSURE_REF(*chain_out);
RESULT_GUARD_POSIX(s2n_cert_chain_and_key_load_pem(*chain_out, chain_pem_out, key_pem));

return S2N_RESULT_OK;
}

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

if (!s2n_is_rsa_pss_certs_supported() || !s2n_is_tls13_fully_supported()) {
END_TEST();
}

const uint8_t test_versions[] = { S2N_TLS13, S2N_TLS12, S2N_TLS11, S2N_TLS10 };
struct {
const char *cert;
const char *key;
uint8_t min_version;
} test_certs[] = {
{
.cert = S2N_RSA_2048_PKCS1_SHA256_CERT_CHAIN,
.key = S2N_RSA_2048_PKCS1_SHA256_CERT_KEY,
},
{
.cert = S2N_ECDSA_P384_PKCS1_CERT_CHAIN,
.key = S2N_ECDSA_P384_PKCS1_KEY,
},
{
.cert = S2N_ECDSA_P512_CERT_CHAIN,
.key = S2N_ECDSA_P512_KEY,
},
{
.cert = S2N_RSA_PSS_2048_SHA256_LEAF_CERT,
.key = S2N_RSA_PSS_2048_SHA256_LEAF_KEY,
.min_version = S2N_TLS12,
},
};

for (size_t cert_i = 0; cert_i < s2n_array_len(test_certs); cert_i++) {
DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain = NULL,
s2n_cert_chain_and_key_ptr_free);
char pem[S2N_MAX_TEST_PEM_SIZE] = { 0 };
EXPECT_OK(s2n_test_load_certificate(&chain, pem,
test_certs[cert_i].cert, test_certs[cert_i].key));

for (size_t version_i = 0; version_i < s2n_array_len(test_versions); version_i++) {
uint8_t version = test_versions[version_i];
bool expect_success = (version >= test_certs[cert_i].min_version);

/* We intentionally use the default policies.
* The default policies should support all certificate types.
*/
const char *security_policy = "default";
if (version >= S2N_TLS13) {
security_policy = "default_tls13";
} else if (version < S2N_TLS12) {
/* The default policies don't support legacy versions */
security_policy = "test_all";
}

DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free);
EXPECT_NOT_NULL(config);
EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain));
EXPECT_SUCCESS(s2n_config_add_pem_to_trust_store(config, pem));
EXPECT_SUCCESS(s2n_config_set_verify_host_callback(config, s2n_noop_verify_host_fn, NULL));
EXPECT_SUCCESS(s2n_config_set_max_blinding_delay(config, 0));
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, security_policy));

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, config));
server->server_protocol_version = version;

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, config));
client->client_protocol_version = version;

DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
EXPECT_SUCCESS(s2n_connections_set_io_pair(client, server, &io_pair));

bool handshake_success =
(s2n_negotiate_test_server_and_client(server, client) == S2N_SUCCESS);
if (handshake_success) {
EXPECT_EQUAL(server->actual_protocol_version, version);
EXPECT_EQUAL(client->actual_protocol_version, version);
}

const char *error_message = "Handshake failed";
if (!expect_success) {
error_message = "Handshake unexpectedly succeeded";
}
if (handshake_success != expect_success) {
fprintf(stderr, "%s version=%i cert=%s\n",
error_message, version, test_certs[cert_i].cert);
FAIL_MSG(error_message);
}
}
}

END_TEST();
}
2 changes: 0 additions & 2 deletions tls/s2n_signature_algorithms.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ static S2N_RESULT s2n_signature_scheme_validate_for_recv(struct s2n_connection *
if (conn->actual_protocol_version >= S2N_TLS13) {
RESULT_ENSURE_NE(scheme->hash_alg, S2N_HASH_SHA1);
RESULT_ENSURE_NE(scheme->sig_alg, S2N_SIGNATURE_RSA);
} else {
RESULT_ENSURE_NE(scheme->sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
goatgoose marked this conversation as resolved.
Show resolved Hide resolved
}

return S2N_RESULT_OK;
Expand Down
6 changes: 3 additions & 3 deletions tls/s2n_signature_scheme.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ const struct s2n_signature_scheme s2n_rsa_pss_pss_sha256 = {
.sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
.libcrypto_nid = NID_rsassaPss,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.minimum_protocol_version = S2N_TLS13,
.minimum_protocol_version = S2N_TLS12,
};

const struct s2n_signature_scheme s2n_rsa_pss_pss_sha384 = {
Expand All @@ -191,7 +191,7 @@ const struct s2n_signature_scheme s2n_rsa_pss_pss_sha384 = {
.sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
.libcrypto_nid = NID_rsassaPss,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.minimum_protocol_version = S2N_TLS13,
.minimum_protocol_version = S2N_TLS12,
};

const struct s2n_signature_scheme s2n_rsa_pss_pss_sha512 = {
Expand All @@ -201,7 +201,7 @@ const struct s2n_signature_scheme s2n_rsa_pss_pss_sha512 = {
.sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
.libcrypto_nid = NID_rsassaPss,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.minimum_protocol_version = S2N_TLS13,
.minimum_protocol_version = S2N_TLS12,
};

/* Chosen based on AWS server recommendations as of 05/24.
Expand Down
Loading