Skip to content

Commit f7aebf6

Browse files
authored
refactor: setup replacement default policies (#5464)
1 parent e8042c0 commit f7aebf6

File tree

8 files changed

+440
-10
lines changed

8 files changed

+440
-10
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
#include "tls/policy/s2n_policy_builder.h"
17+
18+
#include "s2n_test.h"
19+
#include "testlib/s2n_testlib.h"
20+
21+
int main(int argc, char **argv)
22+
{
23+
BEGIN_TEST();
24+
25+
/* Test: s2n_security_policy_get */
26+
{
27+
/* Policies exist only for expected policy + version combinations */
28+
for (size_t policy_i = 0; policy_i < UINT8_MAX; policy_i++) {
29+
bool first_null_found = false;
30+
uint64_t versions_found = 0;
31+
32+
for (size_t version_i = 0; version_i < UINT8_MAX; version_i++) {
33+
const struct s2n_security_policy *policy = s2n_security_policy_get(policy_i, version_i);
34+
35+
/* Invalid policy or version values should be NULL */
36+
if (version_i == 0 || policy_i == 0) {
37+
/* Versioning starts at 1 instead of 0.
38+
* We may want to later assign 0 a special meaning, like "none".
39+
*/
40+
EXPECT_NULL_WITH_ERRNO(policy, S2N_ERR_INVALID_SECURITY_POLICY);
41+
continue;
42+
} else if (policy_i >= S2N_MAX_DEFAULT_POLICIES) {
43+
EXPECT_NULL_WITH_ERRNO(policy, S2N_ERR_INVALID_SECURITY_POLICY);
44+
continue;
45+
} else if (version_i >= S2N_MAX_POLICY_VERSIONS) {
46+
EXPECT_NULL_WITH_ERRNO(policy, S2N_ERR_INVALID_SECURITY_POLICY);
47+
continue;
48+
}
49+
50+
if (policy) {
51+
/* The policy exists because the version is valid.
52+
* Versions should be contiguous. No previous gaps.
53+
*/
54+
EXPECT_FALSE(first_null_found);
55+
versions_found++;
56+
} else if (first_null_found) {
57+
/* If we've already found the first invalid version, all later
58+
* versions should be invalid too.
59+
*/
60+
EXPECT_NULL_WITH_ERRNO(policy, S2N_ERR_INVALID_SECURITY_POLICY);
61+
} else {
62+
/* We have found the first invalid version */
63+
first_null_found = true;
64+
EXPECT_NULL_WITH_ERRNO(policy, S2N_ERR_INVALID_SECURITY_POLICY);
65+
}
66+
}
67+
68+
if (policy_i > 0 && policy_i < S2N_MAX_DEFAULT_POLICIES) {
69+
/* Each valid policy should have at least one valid version */
70+
EXPECT_TRUE(versions_found > 0);
71+
/* If we did't find the last valid version, we're not testing enough */
72+
EXPECT_TRUE(first_null_found);
73+
}
74+
};
75+
76+
/* Check known good values.
77+
* Note: don't add EVERY new version to this test. We should only test
78+
* an interesting selection of inputs.
79+
*/
80+
{
81+
EXPECT_NOT_NULL(s2n_security_policy_get(S2N_POLICY_STRICT, S2N_STRICT_2025_08_20));
82+
EXPECT_NOT_NULL(s2n_security_policy_get(S2N_POLICY_COMPATIBLE, S2N_COMPAT_2025_08_20));
83+
}
84+
};
85+
86+
END_TEST();
87+
}

tls/Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,22 @@ BCS=$(addprefix $(BITCODE_DIR), $(BCS_1))
2525

2626
.PHONY : all
2727
all: $(OBJS)
28-
$(foreach subfolder, $(SUB_BUILDS), $(MAKE) -C $(subfolder))
28+
$(foreach subfolder, $(SUB_BUILDS), $(MAKE) -C $(subfolder);)
2929

3030
.PHONY : bc
3131
bc: $(BCS)
32-
$(foreach subfolder, $(SUB_BUILDS), $(MAKE) -C $(subfolder) bc)
32+
$(foreach subfolder, $(SUB_BUILDS), $(MAKE) -C $(subfolder) bc;)
3333

3434
.PHONY : run-lcov
3535
run-lcov: lcov
36-
$(foreach subfolder, $(SUB_BUILDS), $(MAKE) -C $(subfolder) lcov)
36+
$(foreach subfolder, $(SUB_BUILDS), $(MAKE) -C $(subfolder) lcov;)
3737

3838
.PHONY : indent
3939
indent: indentsource
40-
$(foreach subfolder, $(SUB_BUILDS), ${MAKE} -C $(subfolder) indentsource)
40+
$(foreach subfolder, $(SUB_BUILDS), ${MAKE} -C $(subfolder) indentsource;)
4141

4242
.PHONY : clean
4343
clean: decruft
44-
$(foreach subfolder, $(SUB_BUILDS), ${MAKE} -C $(subfolder) decruft)
44+
$(foreach subfolder, $(SUB_BUILDS), ${MAKE} -C $(subfolder) decruft;)
4545

4646
include ../s2n.mk

tls/policy/Makefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#
2+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License").
5+
# You may not use this file except in compliance with the License.
6+
# A copy of the License is located at
7+
#
8+
# http://aws.amazon.com/apache2.0
9+
#
10+
# or in the "license" file accompanying this file. This file is distributed
11+
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
# express or implied. See the License for the specific language governing
13+
# permissions and limitations under the License.
14+
#
15+
16+
SRCS=$(wildcard *.c)
17+
OBJS=$(SRCS:.c=.o)
18+
19+
# We currently don't need any of these files
20+
# Update this list as necessary. See tls/Makefile.
21+
BCS=
22+
23+
.PHONY : all
24+
all: $(OBJS)
25+
26+
.PHONY : bc
27+
bc: $(BCS)
28+
29+
include ../../s2n.mk

tls/policy/s2n_policy_builder.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
#include "tls/policy/s2n_policy_builder.h"
17+
18+
#include "tls/s2n_security_policies.h"
19+
20+
/* clang-format off */
21+
S2N_INLINE_SECURITY_POLICY_V1(
22+
default_policy_strict,
23+
S2N_TLS13,
24+
S2N_CIPHER_PREF_LIST(
25+
&s2n_tls13_aes_128_gcm_sha256,
26+
&s2n_tls13_aes_256_gcm_sha384,
27+
),
28+
S2N_SIG_PREF_LIST(
29+
&s2n_mldsa44,
30+
&s2n_mldsa65,
31+
&s2n_mldsa87,
32+
&s2n_ecdsa_sha256,
33+
&s2n_ecdsa_sha384,
34+
&s2n_ecdsa_sha512,
35+
&s2n_rsa_pss_pss_sha256,
36+
&s2n_rsa_pss_pss_sha384,
37+
&s2n_rsa_pss_pss_sha512,
38+
&s2n_rsa_pss_rsae_sha256,
39+
&s2n_rsa_pss_rsae_sha384,
40+
&s2n_rsa_pss_rsae_sha512,
41+
),
42+
S2N_CURVE_PREF_LIST(
43+
&s2n_ecc_curve_secp256r1,
44+
&s2n_ecc_curve_secp384r1,
45+
&s2n_ecc_curve_secp521r1,
46+
),
47+
S2N_KEM_PREF_LIST(
48+
&s2n_secp256r1_mlkem_768,
49+
&s2n_x25519_mlkem_768,
50+
&s2n_secp384r1_mlkem_1024,
51+
)
52+
);
53+
/* clang-format on */
54+
55+
/* clang-format off */
56+
S2N_INLINE_SECURITY_POLICY_V1(
57+
default_policy_compat,
58+
S2N_TLS12,
59+
S2N_CIPHER_PREF_LIST(
60+
&s2n_tls13_aes_128_gcm_sha256,
61+
&s2n_tls13_aes_256_gcm_sha384,
62+
&s2n_tls13_chacha20_poly1305_sha256,
63+
&s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
64+
&s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
65+
&s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
66+
&s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
67+
&s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256,
68+
&s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
69+
&s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
70+
&s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
71+
&s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
72+
&s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
73+
),
74+
S2N_SIG_PREF_LIST(
75+
&s2n_mldsa44,
76+
&s2n_mldsa65,
77+
&s2n_mldsa87,
78+
&s2n_ecdsa_sha256,
79+
&s2n_ecdsa_sha384,
80+
&s2n_ecdsa_sha512,
81+
&s2n_rsa_pss_pss_sha256,
82+
&s2n_rsa_pss_pss_sha384,
83+
&s2n_rsa_pss_pss_sha512,
84+
&s2n_rsa_pss_rsae_sha256,
85+
&s2n_rsa_pss_rsae_sha384,
86+
&s2n_rsa_pss_rsae_sha512,
87+
&s2n_rsa_pkcs1_sha256,
88+
&s2n_rsa_pkcs1_sha384,
89+
&s2n_rsa_pkcs1_sha512,
90+
),
91+
S2N_CURVE_PREF_LIST(
92+
&s2n_ecc_curve_secp256r1,
93+
&s2n_ecc_curve_x25519,
94+
&s2n_ecc_curve_secp384r1,
95+
&s2n_ecc_curve_secp521r1,
96+
),
97+
S2N_KEM_PREF_LIST(
98+
&s2n_secp256r1_mlkem_768,
99+
&s2n_x25519_mlkem_768,
100+
&s2n_secp384r1_mlkem_1024,
101+
)
102+
);
103+
/* clang-format on */
104+
105+
const struct s2n_security_policy *default_policies[S2N_MAX_DEFAULT_POLICIES][S2N_MAX_POLICY_VERSIONS] = {
106+
[S2N_POLICY_STRICT] = {
107+
[S2N_STRICT_2025_08_20] = &default_policy_strict,
108+
},
109+
[S2N_POLICY_COMPATIBLE] = {
110+
[S2N_COMPAT_2025_08_20] = &default_policy_compat,
111+
},
112+
};
113+
114+
const struct s2n_security_policy *s2n_security_policy_get(s2n_policy_name policy, uint64_t version)
115+
{
116+
/* The uint64_t cast here is required for some older compilers to avoid a
117+
* "tautological-constant-out-of-range-compare" error. That error assumes
118+
* "policy" will be a valid s2n_default_policy, but that is not guaranteed by
119+
* the standard.
120+
*/
121+
PTR_ENSURE((uint64_t) policy < S2N_MAX_DEFAULT_POLICIES, S2N_ERR_INVALID_SECURITY_POLICY);
122+
PTR_ENSURE(version < S2N_MAX_POLICY_VERSIONS, S2N_ERR_INVALID_SECURITY_POLICY);
123+
124+
const struct s2n_security_policy *match = default_policies[policy][version];
125+
PTR_ENSURE(match, S2N_ERR_INVALID_SECURITY_POLICY);
126+
127+
return match;
128+
}

tls/policy/s2n_policy_builder.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
#pragma once
17+
18+
#include "tls/policy/s2n_policy_feature.h"
19+
20+
#define S2N_MAX_DEFAULT_POLICIES 3
21+
#define S2N_MAX_POLICY_VERSIONS 10

tls/policy/s2n_policy_feature.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
#pragma once
17+
18+
#include <s2n.h>
19+
20+
struct s2n_security_policy;
21+
22+
/**
23+
* Security policy definitions for common use cases.
24+
* These policies are versioned, with updates added as new versions.
25+
*/
26+
typedef enum {
27+
/**
28+
* A security policy that supports a wide variety of common options.
29+
* It is intended for use cases where the peer in a connection is unknown,
30+
* but assumed reasonably modern and standard.
31+
* If you are unsure which policy to choose, this is a safe choice.
32+
*/
33+
S2N_POLICY_COMPATIBLE = 1,
34+
/**
35+
* A security policy that supports a narrow selection of the most preferred options.
36+
* It is intended for use cases where the peer is known to support that narrow
37+
* selection of options, usually because the same owner maintains both the clients
38+
* and servers involved in connections.
39+
*/
40+
S2N_POLICY_STRICT,
41+
} s2n_policy_name;
42+
43+
typedef enum {
44+
/**
45+
* Supports only TLS1.3.
46+
* Supports post-quantum key exchange (MLKEM) and signatures (MLDSA).
47+
* Supports MLDSA, EC, and RSA certificates.
48+
* Supports only AES-GCM encryption.
49+
* Supports p256, p384, and p521 named groups.
50+
* Supports only SHA256 and higher signatures.
51+
* Supports only RSA-PSS padding for RSA signatures.
52+
* Supports forward secrecy.
53+
*/
54+
S2N_STRICT_2025_08_20 = 1,
55+
} s2n_strict_policy_version;
56+
57+
typedef enum {
58+
/**
59+
* Supports TLS1.2 and TLS1.3.
60+
* Supports post-quantum key exchange (MLKEM) and signatures (MLDSA).
61+
* Supports MLDSA, EC, and RSA certificates.
62+
* Supports AES-GCM, AES-CBC, and ChaChaPoly encryption.
63+
* Supports p256, x25519, p384, and p521 named groups.
64+
* Supports only SHA256 and higher signatures.
65+
* Supports forward secrecy.
66+
*/
67+
S2N_COMPAT_2025_08_20 = 1,
68+
} s2n_compat_policy_version;
69+
70+
/**
71+
* Retrieves a security policy by name and version.
72+
*
73+
* @param policy The s2n_policy_name defining a policy.
74+
* @param version The specific version of the policy.
75+
* @returns A static library security policy
76+
*/
77+
const struct s2n_security_policy *s2n_security_policy_get(s2n_policy_name policy, uint64_t version);
78+
79+
/**
80+
* Sets the security policy on the config.
81+
*
82+
* "security policies" were previously known as "cipher preferences".
83+
* See `s2n_config_set_cipher_preferences`.
84+
*
85+
* @param config The config object being updated
86+
* @param policy The security policy being set
87+
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure
88+
*/
89+
int s2n_config_set_security_policy(struct s2n_config *config, const struct s2n_security_policy *policy);
90+
91+
/**
92+
* Sets an override security policy on the connection.
93+
*
94+
* "security policies" were previously known as "cipher preferences".
95+
* See `s2n_connection_set_cipher_preferences`.
96+
*
97+
* @param conn The connection object being updated
98+
* @param policy The security policy being set
99+
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure
100+
*/
101+
int s2n_connection_set_security_policy(struct s2n_connection *conn, const struct s2n_security_policy *policy);

0 commit comments

Comments
 (0)