File: s2n_policy_defaults_test.c

package info (click to toggle)
aws-crt-python 0.28.4%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 78,428 kB
  • sloc: ansic: 437,955; python: 27,657; makefile: 5,855; sh: 4,289; ruby: 208; java: 82; perl: 73; cpp: 25; xml: 11
file content (135 lines) | stat: -rw-r--r-- 6,120 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * 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 "tls/policy/s2n_policy_defaults.h"

#include "s2n_test.h"
#include "testlib/s2n_testlib.h"

S2N_RESULT s2n_test_strict_compatibility(uint64_t start, uint64_t end,
        struct s2n_test_cert_chain_list *cert_chains)
{
    for (size_t client_i = start; client_i <= end; client_i++) {
        for (size_t server_i = start; server_i <= end; server_i++) {
            for (size_t cert_i = 0; cert_i < cert_chains->count; cert_i++) {
                DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free);
                EXPECT_NOT_NULL(config);
                EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config));
                EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config,
                        cert_chains->chains[cert_i].chain));
                EXPECT_SUCCESS(s2n_config_set_client_auth_type(config, S2N_CERT_AUTH_REQUIRED));

                DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT),
                        s2n_connection_ptr_free);
                EXPECT_SUCCESS(s2n_connection_set_config(client, config));
                EXPECT_SUCCESS(s2n_connection_set_security_policy(client,
                        s2n_security_policy_get(S2N_POLICY_STRICT, client_i)));

                DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER),
                        s2n_connection_ptr_free);
                EXPECT_SUCCESS(s2n_connection_set_config(server, config));
                EXPECT_SUCCESS(s2n_connection_set_security_policy(server,
                        s2n_security_policy_get(S2N_POLICY_STRICT, server_i)));

                DEFER_CLEANUP(struct s2n_test_io_stuffer_pair io_pair, s2n_io_stuffer_pair_free);
                EXPECT_OK(s2n_io_stuffer_pair_init(&io_pair));
                EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &io_pair));
                EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client));

                /* For now, consider a HRR a potential breaking change.
                 * We can revisit later if necessary.
                 */
                EXPECT_FALSE(IS_HELLO_RETRY_HANDSHAKE(server));
            }
        }
    }
    return S2N_RESULT_OK;
}

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

    /* Test: s2n_security_policy_get */
    {
        /* Policies exist only for expected policy + version combinations */
        for (size_t policy_i = 0; policy_i < UINT8_MAX; policy_i++) {
            bool first_null_found = false;
            uint64_t versions_found = 0;

            for (size_t version_i = 0; version_i < UINT8_MAX; version_i++) {
                const struct s2n_security_policy *policy = s2n_security_policy_get(policy_i, version_i);

                /* Invalid policy or version values should be NULL */
                if (version_i == 0 || policy_i == 0) {
                    /* Versioning starts at 1 instead of 0.
                     * We may want to later assign 0 a special meaning, like "none".
                     */
                    EXPECT_NULL_WITH_ERRNO(policy, S2N_ERR_INVALID_SECURITY_POLICY);
                    continue;
                } else if (policy_i >= S2N_MAX_DEFAULT_POLICIES) {
                    EXPECT_NULL_WITH_ERRNO(policy, S2N_ERR_INVALID_SECURITY_POLICY);
                    continue;
                } else if (version_i >= S2N_MAX_POLICY_VERSIONS) {
                    EXPECT_NULL_WITH_ERRNO(policy, S2N_ERR_INVALID_SECURITY_POLICY);
                    continue;
                }

                if (policy) {
                    /* The policy exists because the version is valid.
                     * Versions should be contiguous. No previous gaps.
                     */
                    EXPECT_FALSE(first_null_found);
                    versions_found++;
                } else if (first_null_found) {
                    /* If we've already found the first invalid version, all later
                     * versions should be invalid too.
                     */
                    EXPECT_NULL_WITH_ERRNO(policy, S2N_ERR_INVALID_SECURITY_POLICY);
                } else {
                    /* We have found the first invalid version */
                    first_null_found = true;
                    EXPECT_NULL_WITH_ERRNO(policy, S2N_ERR_INVALID_SECURITY_POLICY);
                }
            }

            if (policy_i > 0 && policy_i < S2N_MAX_DEFAULT_POLICIES) {
                /* Each valid policy should have at least one valid version */
                EXPECT_TRUE(versions_found > 0);
                /* If we did't find the last valid version, we're not testing enough */
                EXPECT_TRUE(first_null_found);
            }
        };

        /* Check known good values.
         * Note: don't add EVERY new version to this test. We should only test
         * an interesting selection of inputs.
         */
        {
            EXPECT_NOT_NULL(s2n_security_policy_get(S2N_POLICY_STRICT, S2N_STRICT_2025_08_20));
            EXPECT_NOT_NULL(s2n_security_policy_get(S2N_POLICY_COMPATIBLE, S2N_COMPAT_2025_08_20));
        }
    };

    /* Test: S2N_POLICY_STRICT backwards compatibility promises enforced */
    if (s2n_is_tls13_fully_supported()) {
        DEFER_CLEANUP(struct s2n_test_cert_chain_list cert_chains = { 0 }, s2n_test_cert_chains_free);
        EXPECT_OK(s2n_test_cert_chains_init(&cert_chains));

        EXPECT_OK(s2n_test_strict_compatibility(1, S2N_STRICT_LATEST_1, &cert_chains));
    };

    END_TEST();
}