aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/s2n/tls/s2n_handshake.h
blob: cb871889e42084843ba9fcf3d27b25268a656e96 (plain) (blame)
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*
 * 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.
 */

#pragma once

#include <stdint.h>
#include <s2n.h>

#include "tls/s2n_crypto.h"
#include "tls/s2n_signature_algorithms.h"
#include "tls/s2n_tls_parameters.h"

#include "stuffer/s2n_stuffer.h"

#include "crypto/s2n_certificate.h"
#include "crypto/s2n_hash.h"

/* From RFC 8446: https://tools.ietf.org/html/rfc8446#appendix-B.3 */
#define TLS_HELLO_REQUEST              0
#define TLS_CLIENT_HELLO               1
#define TLS_SERVER_HELLO               2
#define TLS_SERVER_NEW_SESSION_TICKET  4
#define TLS_ENCRYPTED_EXTENSIONS       8
#define TLS_CERTIFICATE               11
#define TLS_SERVER_KEY                12
#define TLS_CERT_REQ                  13
#define TLS_SERVER_HELLO_DONE         14
#define TLS_CERT_VERIFY               15
#define TLS_CLIENT_KEY                16
#define TLS_FINISHED                  20
#define TLS_SERVER_CERT_STATUS        22
#define TLS_SERVER_SESSION_LOOKUP     23
#define TLS_KEY_UPDATE                24
#define TLS_MESSAGE_HASH             254

/* This is the list of message types that we support */
typedef enum {
    CLIENT_HELLO=0,
    SERVER_HELLO,
    SERVER_CERT,
    SERVER_NEW_SESSION_TICKET,
    SERVER_CERT_STATUS,
    SERVER_KEY,
    SERVER_CERT_REQ,
    SERVER_HELLO_DONE,
    CLIENT_CERT,
    CLIENT_KEY,
    CLIENT_CERT_VERIFY,
    CLIENT_CHANGE_CIPHER_SPEC,
    CLIENT_FINISHED,
    SERVER_CHANGE_CIPHER_SPEC,
    SERVER_FINISHED,

    /* TLS1.3 message types. Defined: https://tools.ietf.org/html/rfc8446#appendix-B.3 */
    ENCRYPTED_EXTENSIONS,
    SERVER_CERT_VERIFY,
    HELLO_RETRY_MSG,

    APPLICATION_DATA,
} message_type_t;

typedef enum {
    S2N_ASYNC_NOT_INVOKED = 0,
    S2N_ASYNC_INVOKING_CALLBACK,
    S2N_ASYNC_INVOKED_WAITING,
    S2N_ASYNC_INVOKED_COMPLETE,
} s2n_async_state;

struct s2n_handshake_parameters {
    /* 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 server in the certificate request */
    struct s2n_sig_scheme_list server_sig_hash_algs;

    /* The cert chain we will send the peer. */
    struct s2n_cert_chain_and_key *our_chain_and_key;

    /* The subset of certificates that match the server_name presented in the ClientHello.
     * In the case of multiple certificates matching a server_name, s2n will prefer certificates
     * in FIFO order based on calls to s2n_config_add_cert_chain_and_key_to_store
     *
     * Note that in addition to domain matching, the key type for the certificate must also be
     * suitable for a negotiation in order to be selected. The set of matching certs here are indexed
     * by s2n_authentication_method.
     *
     * Example:
     *    - Assume certA is added to s2n_config via s2n_config_add_cert_chain_and_key_to_store
     *    - Next certB is added.
     *    - if certA matches www.foo.com and certB matches www.foo.com, s2n will prefer certA
     *
     * Note that in addition to domain matching, the key type for the certificate must also be
     * suitable for a negotiation in order to be selected.
     *
     * Example:
     *    - Assume certA and certB match server_name www.foo.com
     *    - certA is ECDSA and certB is RSA.
     *    - Client only supports RSA ciphers
     *    - certB will be selected.
     */
    struct s2n_cert_chain_and_key *exact_sni_matches[S2N_CERT_TYPE_COUNT];
    struct s2n_cert_chain_and_key *wc_sni_matches[S2N_CERT_TYPE_COUNT];
    uint8_t exact_sni_match_exists;
    uint8_t wc_sni_match_exists;
};

struct s2n_handshake {
    struct s2n_stuffer io;

    struct s2n_hash_state md5;
    struct s2n_hash_state sha1;
    struct s2n_hash_state sha224;
    struct s2n_hash_state sha256;
    struct s2n_hash_state sha384;
    struct s2n_hash_state sha512;
    struct s2n_hash_state md5_sha1;

    /* A copy of the handshake messages hash used to validate the CertificateVerify message */
    struct s2n_hash_state ccv_hash_copy;

    /* Used for SSLv3, TLS 1.0, and TLS 1.1 PRFs */
    struct s2n_hash_state prf_md5_hash_copy;
    struct s2n_hash_state prf_sha1_hash_copy;
    /*Used for TLS 1.2 PRF */
    struct s2n_hash_state prf_tls12_hash_copy;
    struct s2n_hash_state server_finished_copy;

    /* Hash algorithms required for this handshake. The set of required hashes can be reduced as session parameters are
     * negotiated, i.e. cipher suite and protocol version.
     */
    uint8_t required_hash_algs[S2N_HASH_SENTINEL];

    uint8_t server_finished[S2N_TLS_SECRET_LEN];
    uint8_t client_finished[S2N_TLS_SECRET_LEN];

    /* Handshake type is a bitset, with the following
       bit positions */
    uint32_t handshake_type;

/* Has the handshake been negotiated yet? */
#define INITIAL                     0x00
#define NEGOTIATED                  0x01
#define IS_NEGOTIATED( type ) ( (type) & NEGOTIATED )

/* Handshake is a full handshake  */
#define FULL_HANDSHAKE              0x02
#define IS_FULL_HANDSHAKE( type )   ( (type) & FULL_HANDSHAKE )
#define IS_RESUMPTION_HANDSHAKE( type ) ( !IS_FULL_HANDSHAKE( (type) ) && IS_NEGOTIATED ( (type) ) )

/* Handshake uses perfect forward secrecy */
#define TLS12_PERFECT_FORWARD_SECRECY 0x04

/* Handshake needs OCSP status message */
#define OCSP_STATUS                 0x08
#define IS_OCSP_STAPLED( type ) ( ( (type) & OCSP_STATUS ) != 0 )

/* Handshake should request a Client Certificate */
#define CLIENT_AUTH                 0x10
#define IS_CLIENT_AUTH_HANDSHAKE( type )   ( (type) & CLIENT_AUTH )

/* Session Resumption via session-tickets */
#define WITH_SESSION_TICKET         0x20
#define IS_ISSUING_NEW_SESSION_TICKET( type )   ( (type) & WITH_SESSION_TICKET )

/* Handshake requested a Client Certificate but did not get one */
#define NO_CLIENT_CERT              0x40
#define IS_CLIENT_AUTH_NO_CERT( type )   ( IS_CLIENT_AUTH_HANDSHAKE( (type) ) && ( (type) & NO_CLIENT_CERT) )

/* A HelloRetryRequest was needed to proceed with the handshake */
#define HELLO_RETRY_REQUEST         0x80

/* Disguise a TLS1.3 handshake as a TLS1.2 handshake for backwards compatibility
 * with some middleboxes: https://tools.ietf.org/html/rfc8446#appendix-D.4 */
#define MIDDLEBOX_COMPAT            0x100
#define IS_MIDDLEBOX_COMPAT_MODE( type ) ( (type) & MIDDLEBOX_COMPAT )

    /* Which handshake message number are we processing */
    int message_number;

    /* State of the async pkey operation during handshake */
    s2n_async_state async_state;

    /* Indicates the CLIENT_HELLO message has been completely received */
    unsigned client_hello_received:1;

    /* Indicates the handshake blocked while trying to read or write data, and has been paused */
    unsigned paused:1;

    /* Set to 1 if the RSA verification failed */
    unsigned rsa_failed:1;
};

extern message_type_t s2n_conn_get_current_message_type(struct s2n_connection *conn);
extern int s2n_conn_set_handshake_type(struct s2n_connection *conn);
extern int s2n_conn_set_handshake_no_client_cert(struct s2n_connection *conn);
extern int s2n_conn_set_handshake_read_block(struct s2n_connection *conn);
extern int s2n_conn_clear_handshake_read_block(struct s2n_connection *conn);
extern int s2n_handshake_require_all_hashes(struct s2n_handshake *handshake);
extern uint8_t s2n_handshake_is_hash_required(struct s2n_handshake *handshake, s2n_hash_algorithm hash_alg);
extern int s2n_conn_update_required_handshake_hashes(struct s2n_connection *conn);
extern int s2n_handshake_get_hash_state(struct s2n_connection *conn, s2n_hash_algorithm hash_alg, struct s2n_hash_state *hash_state);
extern int s2n_handshake_reset_hash_state(struct s2n_connection *conn, s2n_hash_algorithm hash_alg);
extern int s2n_conn_find_name_matching_certs(struct s2n_connection *conn);
extern int s2n_create_wildcard_hostname(struct s2n_stuffer *hostname, struct s2n_stuffer *output);
struct s2n_cert_chain_and_key *s2n_get_compatible_cert_chain_and_key(struct s2n_connection *conn, const s2n_pkey_type cert_type);
int s2n_conn_update_handshake_hashes(struct s2n_connection *conn, struct s2n_blob *data);
S2N_RESULT s2n_quic_read_handshake_message(struct s2n_connection *conn, uint8_t *message_type);
S2N_RESULT s2n_quic_write_handshake_message(struct s2n_connection *conn, struct s2n_blob *in);