File: s2n_handshake_hashes_test.c

package info (click to toggle)
aws-crt-python 0.20.4%2Bdfsg-1~bpo12%2B1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-backports
  • size: 72,656 kB
  • sloc: ansic: 381,805; python: 23,008; makefile: 6,251; sh: 4,536; cpp: 699; ruby: 208; java: 77; perl: 73; javascript: 46; xml: 11
file content (154 lines) | stat: -rw-r--r-- 5,750 bytes parent folder | download | duplicates (2)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
 * 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/s2n_handshake_hashes.h"

#include "s2n_test.h"
#include "tls/s2n_connection.h"

/* Needed for s2n_handshake_get_hash_state_ptr */
#include "tls/s2n_handshake.c"

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

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

        /* Allocates a new s2n_handshake_hashes struct */
        {
            /* Allocates the struct */
            struct s2n_connection conn = { 0 };
            EXPECT_NULL(conn.handshake.hashes);
            EXPECT_OK(s2n_handshake_hashes_new(&conn.handshake.hashes));
            EXPECT_NOT_NULL(conn.handshake.hashes);

            uint8_t data[100] = { 0 };

            /* Allocates all hashes */
            for (s2n_hash_algorithm alg = 0; alg < S2N_HASH_SENTINEL; alg++) {
                if (alg == S2N_HASH_NONE) {
                    continue;
                }

                uint8_t size = 0;
                EXPECT_SUCCESS(s2n_hash_digest_size(alg, &size));
                EXPECT_TRUE(size < sizeof(data));

                struct s2n_hash_state *hash_state = NULL;
                EXPECT_SUCCESS(s2n_handshake_get_hash_state_ptr(&conn, alg, &hash_state));

                /* Hash is setup / useable */
                EXPECT_SUCCESS(s2n_hash_digest(hash_state, data, size));
            }

            s2n_handshake_hashes_free(&conn.handshake.hashes);
        };
    };

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

        /* Resets all hashes */
        {
            struct s2n_connection conn = { 0 };
            EXPECT_OK(s2n_handshake_hashes_new(&conn.handshake.hashes));
            EXPECT_NOT_NULL(conn.handshake.hashes);

            uint8_t data[100] = { 0 };

            for (s2n_hash_algorithm alg = 0; alg < S2N_HASH_SENTINEL; alg++) {
                if (alg == S2N_HASH_NONE) {
                    continue;
                }

                uint8_t size = 0;
                EXPECT_SUCCESS(s2n_hash_digest_size(alg, &size));
                EXPECT_TRUE(size < sizeof(data));

                struct s2n_hash_state *hash_state = NULL;
                EXPECT_SUCCESS(s2n_handshake_get_hash_state_ptr(&conn, alg, &hash_state));
                EXPECT_SUCCESS(s2n_hash_digest(hash_state, data, size));

                /* Can't calculate the digest again: only one digest allowed per hash */
                EXPECT_FAILURE_WITH_ERRNO(s2n_hash_digest(hash_state, data, size), S2N_ERR_HASH_NOT_READY);

                /* Wiping the hashes allows them to be successfully reused */
                EXPECT_OK(s2n_handshake_hashes_wipe(conn.handshake.hashes));
                EXPECT_SUCCESS(s2n_hash_digest(hash_state, data, size));
            }

            s2n_handshake_hashes_free(&conn.handshake.hashes);
        };
    };

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

        /* Frees the hashes with no memory leaks */
        {
            struct s2n_handshake_hashes *hashes = NULL;
            EXPECT_OK(s2n_handshake_hashes_new(&hashes));
            EXPECT_NOT_NULL(hashes);

            EXPECT_OK(s2n_handshake_hashes_free(&hashes));
            EXPECT_NULL(hashes);
        };
    };

    /* Test s2n_handshake_hashes connection lifecycle */
    {
        uint8_t digest[SHA256_DIGEST_LENGTH] = { 0 };

        /* A new connection's hashes are properly set up and can be used. */
        struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT);
        EXPECT_NOT_NULL(conn);

        struct s2n_hash_state *hash_state = NULL;
        EXPECT_SUCCESS(s2n_handshake_get_hash_state_ptr(conn, S2N_HASH_SHA256, &hash_state));
        EXPECT_NOT_NULL(hash_state);
        EXPECT_SUCCESS(s2n_hash_digest(hash_state, digest, SHA256_DIGEST_LENGTH));
        EXPECT_FAILURE_WITH_ERRNO(s2n_hash_digest(hash_state, digest, SHA256_DIGEST_LENGTH), S2N_ERR_HASH_NOT_READY);

        /* A wiped connection's hashes can be reused. */
        EXPECT_SUCCESS(s2n_connection_wipe(conn));
        EXPECT_SUCCESS(s2n_handshake_get_hash_state_ptr(conn, S2N_HASH_SHA256, &hash_state));
        EXPECT_NOT_NULL(hash_state);
        EXPECT_SUCCESS(s2n_hash_digest(hash_state, digest, SHA256_DIGEST_LENGTH));

        /* Freeing the handshake frees the hashes */
        EXPECT_SUCCESS(s2n_connection_free_handshake(conn));
        EXPECT_FAILURE_WITH_ERRNO(s2n_handshake_get_hash_state_ptr(conn, S2N_HASH_SHA256, &hash_state), S2N_ERR_NULL);
        EXPECT_NULL(conn->handshake.hashes);

        /* Wiping the connection should restore the freed hashes */
        EXPECT_SUCCESS(s2n_connection_wipe(conn));
        EXPECT_SUCCESS(s2n_handshake_get_hash_state_ptr(conn, S2N_HASH_SHA256, &hash_state));
        EXPECT_NOT_NULL(hash_state);
        EXPECT_SUCCESS(s2n_hash_digest(hash_state, digest, SHA256_DIGEST_LENGTH));

        /* Freeing the connection should free the hashes */
        EXPECT_SUCCESS(s2n_connection_free(conn));
    };

    END_TEST();
}