Branch data Line data Source code
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/s2n_signature_algorithms.h"
17 : :
18 : : #include "crypto/s2n_fips.h"
19 : : #include "crypto/s2n_rsa_pss.h"
20 : : #include "error/s2n_errno.h"
21 : : #include "tls/s2n_auth_selection.h"
22 : : #include "tls/s2n_cipher_suites.h"
23 : : #include "tls/s2n_connection.h"
24 : : #include "tls/s2n_kex.h"
25 : : #include "tls/s2n_security_policies.h"
26 : : #include "tls/s2n_signature_scheme.h"
27 : : #include "utils/s2n_safety.h"
28 : :
29 : : static S2N_RESULT s2n_signature_scheme_validate_for_send(struct s2n_connection *conn,
30 : : const struct s2n_signature_scheme *scheme)
31 : 149578 : {
32 [ - + ][ # # ]: 149578 : RESULT_ENSURE_REF(conn);
33 : :
34 : : /* If no protocol has been negotiated yet, the actual_protocol_version will
35 : : * be equivalent to the client_protocol_version and represent the highest
36 : : * version supported.
37 : : */
38 [ + - ][ + + ]: 149578 : RESULT_ENSURE_GTE(conn->actual_protocol_version, scheme->minimum_protocol_version);
39 : :
40 : : /* QUIC only supports TLS1.3 */
41 [ + + ][ + + ]: 145427 : if (s2n_connection_is_quic_enabled(conn) && scheme->maximum_protocol_version) {
42 [ + - ][ + - ]: 96 : RESULT_ENSURE_GTE(scheme->maximum_protocol_version, S2N_TLS13);
43 : 96 : }
44 : :
45 [ - + ]: 145331 : if (!s2n_is_rsa_pss_signing_supported()) {
46 [ # # ][ # # ]: 0 : RESULT_ENSURE_NE(scheme->sig_alg, S2N_SIGNATURE_RSA_PSS_RSAE);
47 : 0 : }
48 : :
49 [ - + ]: 145331 : if (!s2n_is_rsa_pss_certs_supported()) {
50 [ # # ][ # # ]: 0 : RESULT_ENSURE_NE(scheme->sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
51 : 0 : }
52 : :
53 : 145331 : return S2N_RESULT_OK;
54 : 145331 : }
55 : :
56 : : static bool s2n_signature_scheme_is_valid_for_send(struct s2n_connection *conn,
57 : : const struct s2n_signature_scheme *scheme)
58 : 113532 : {
59 : 113532 : return s2n_result_is_ok(s2n_signature_scheme_validate_for_send(conn, scheme));
60 : 113532 : }
61 : :
62 : : static S2N_RESULT s2n_signature_scheme_validate_for_recv(struct s2n_connection *conn,
63 : : const struct s2n_signature_scheme *scheme)
64 : 36046 : {
65 [ # # ][ - + ]: 36046 : RESULT_ENSURE_REF(scheme);
66 [ # # ][ - + ]: 36046 : RESULT_ENSURE_REF(conn);
67 : :
68 [ + + ]: 36046 : RESULT_GUARD(s2n_signature_scheme_validate_for_send(conn, scheme));
69 : :
70 [ + + ]: 36022 : if (scheme->maximum_protocol_version != S2N_UNKNOWN_PROTOCOL_VERSION) {
71 [ + - ][ + + ]: 3298 : RESULT_ENSURE_LTE(conn->actual_protocol_version, scheme->maximum_protocol_version);
72 : 3298 : }
73 : :
74 [ - + ][ # # ]: 35353 : RESULT_ENSURE_NE(conn->actual_protocol_version, S2N_UNKNOWN_PROTOCOL_VERSION);
75 [ + + ]: 35353 : if (conn->actual_protocol_version >= S2N_TLS13) {
76 [ + - ][ + + ]: 28546 : RESULT_ENSURE_NE(scheme->hash_alg, S2N_HASH_SHA1);
77 [ + + ][ + - ]: 28545 : RESULT_ENSURE_NE(scheme->sig_alg, S2N_SIGNATURE_RSA);
78 : 28545 : }
79 : :
80 : 35351 : return S2N_RESULT_OK;
81 : 35353 : }
82 : :
83 : : static bool s2n_signature_scheme_is_valid_for_recv(struct s2n_connection *conn,
84 : : const struct s2n_signature_scheme *scheme)
85 : 36046 : {
86 : 36046 : return s2n_result_is_ok(s2n_signature_scheme_validate_for_recv(conn, scheme));
87 : 36046 : }
88 : :
89 : : static S2N_RESULT s2n_signature_algorithms_get_legacy_default(struct s2n_connection *conn,
90 : : s2n_mode signer, const struct s2n_signature_scheme **default_sig_scheme)
91 : 356 : {
92 [ - + ][ # # ]: 356 : RESULT_ENSURE_REF(conn);
93 [ - + ][ # # ]: 356 : RESULT_ENSURE_REF(default_sig_scheme);
94 : :
95 : 356 : s2n_authentication_method auth_method = 0;
96 [ + + ]: 356 : if (signer == S2N_CLIENT) {
97 [ - + ]: 5 : RESULT_GUARD_POSIX(s2n_get_auth_method_for_cert_type(
98 : 5 : conn->handshake_params.client_cert_pkey_type, &auth_method));
99 : 351 : } else {
100 [ # # ][ - + ]: 351 : RESULT_ENSURE_REF(conn->secure);
101 [ - + ][ # # ]: 351 : RESULT_ENSURE_REF(conn->secure->cipher_suite);
102 : 351 : auth_method = conn->secure->cipher_suite->auth_method;
103 : 351 : }
104 : :
105 [ + + ]: 356 : if (auth_method == S2N_AUTHENTICATION_ECDSA) {
106 : 142 : *default_sig_scheme = &s2n_ecdsa_sha1;
107 : 214 : } else {
108 : 214 : *default_sig_scheme = &s2n_rsa_pkcs1_md5_sha1;
109 : 214 : }
110 : 356 : return S2N_RESULT_OK;
111 : 356 : }
112 : :
113 : : S2N_RESULT s2n_signature_algorithm_recv(struct s2n_connection *conn, struct s2n_stuffer *in)
114 : 3386 : {
115 [ # # ][ - + ]: 3386 : RESULT_ENSURE_REF(conn);
116 : :
117 : 3386 : const struct s2n_signature_scheme **chosen_sig_scheme = NULL;
118 : 3386 : s2n_mode peer_mode = S2N_PEER_MODE(conn->mode);
119 [ + + ]: 3386 : if (peer_mode == S2N_CLIENT) {
120 : 167 : chosen_sig_scheme = &conn->handshake_params.client_cert_sig_scheme;
121 : 3219 : } else {
122 : 3219 : chosen_sig_scheme = &conn->handshake_params.server_cert_sig_scheme;
123 : 3219 : }
124 : :
125 : : /* Before TLS1.2, signature algorithms were fixed instead of negotiated */
126 [ + + ]: 3386 : if (conn->actual_protocol_version < S2N_TLS12) {
127 : 175 : return s2n_signature_algorithms_get_legacy_default(conn, peer_mode, chosen_sig_scheme);
128 : 175 : }
129 : :
130 : 3211 : uint16_t iana_value = 0;
131 [ + - ][ + + ]: 3211 : RESULT_ENSURE(s2n_stuffer_read_uint16(in, &iana_value) == S2N_SUCCESS,
132 : 3210 : S2N_ERR_BAD_MESSAGE);
133 : :
134 : 3210 : const struct s2n_signature_preferences *signature_preferences = NULL;
135 [ - + ]: 3210 : RESULT_GUARD_POSIX(s2n_connection_get_signature_preferences(conn, &signature_preferences));
136 [ - + ][ # # ]: 3210 : RESULT_ENSURE_REF(signature_preferences);
137 : :
138 [ + + ]: 19996 : for (size_t i = 0; i < signature_preferences->count; i++) {
139 : 19987 : const struct s2n_signature_scheme *candidate = signature_preferences->signature_schemes[i];
140 : :
141 [ + + ]: 19987 : if (candidate->iana_value != iana_value) {
142 : 16785 : continue;
143 : 16785 : }
144 : :
145 [ + + ]: 3202 : if (!s2n_signature_scheme_is_valid_for_recv(conn, candidate)) {
146 : 1 : continue;
147 : 1 : }
148 : :
149 : 3201 : *chosen_sig_scheme = candidate;
150 : 3201 : return S2N_RESULT_OK;
151 : 3202 : }
152 : :
153 [ + - ]: 9 : RESULT_BAIL(S2N_ERR_INVALID_SIGNATURE_SCHEME);
154 : 9 : }
155 : :
156 : : static S2N_RESULT s2n_signature_algorithms_validate_supported_by_peer(
157 : : struct s2n_connection *conn, uint16_t iana)
158 : 6414 : {
159 [ # # ][ - + ]: 6414 : RESULT_ENSURE_REF(conn);
160 : :
161 : 6414 : const struct s2n_sig_scheme_list *peer_list = &conn->handshake_params.peer_sig_scheme_list;
162 [ + + ]: 35782 : for (size_t i = 0; i < peer_list->len; i++) {
163 [ + + ]: 35680 : if (peer_list->iana_list[i] == iana) {
164 : 6312 : return S2N_RESULT_OK;
165 : 6312 : }
166 : 35680 : }
167 : :
168 [ + - ]: 102 : RESULT_BAIL(S2N_ERR_NO_VALID_SIGNATURE_SCHEME);
169 : 102 : }
170 : :
171 : : static bool s2n_signature_algorithm_is_supported_by_peer(
172 : : struct s2n_connection *conn, uint16_t iana)
173 : 6414 : {
174 : 6414 : return s2n_result_is_ok(s2n_signature_algorithms_validate_supported_by_peer(conn, iana));
175 : 6414 : }
176 : :
177 : : S2N_RESULT s2n_signature_algorithm_select(struct s2n_connection *conn)
178 : 6870 : {
179 [ # # ][ - + ]: 6870 : RESULT_ENSURE_REF(conn);
180 [ # # ][ - + ]: 6870 : RESULT_ENSURE_REF(conn->secure);
181 : 6870 : struct s2n_cipher_suite *cipher_suite = conn->secure->cipher_suite;
182 [ - + ][ # # ]: 6870 : RESULT_ENSURE_REF(cipher_suite);
183 : :
184 : 6870 : const struct s2n_signature_scheme **chosen_sig_scheme = NULL;
185 [ + + ]: 6870 : if (conn->mode == S2N_CLIENT) {
186 : 193 : chosen_sig_scheme = &conn->handshake_params.client_cert_sig_scheme;
187 : 6677 : } else {
188 : 6677 : chosen_sig_scheme = &conn->handshake_params.server_cert_sig_scheme;
189 : 6677 : }
190 : :
191 : : /* No server signature is needed for RSA kex */
192 [ + + ][ + + ]: 6870 : if (conn->mode == S2N_SERVER && cipher_suite->key_exchange_alg == &s2n_rsa) {
193 [ - + ][ # # ]: 339 : RESULT_ENSURE_EQ(*chosen_sig_scheme, &s2n_null_sig_scheme);
194 : 339 : return S2N_RESULT_OK;
195 : 339 : }
196 : :
197 : : /* Before TLS1.2, signature algorithms were fixed instead of negotiated */
198 [ + + ]: 6531 : if (conn->actual_protocol_version < S2N_TLS12) {
199 [ - + ]: 181 : RESULT_GUARD(s2n_signature_algorithms_get_legacy_default(conn, conn->mode, chosen_sig_scheme));
200 : 181 : return S2N_RESULT_OK;
201 : 181 : }
202 : :
203 : 6350 : const struct s2n_signature_preferences *signature_preferences = NULL;
204 [ - + ]: 6350 : RESULT_GUARD_POSIX(s2n_connection_get_signature_preferences(conn, &signature_preferences));
205 [ # # ][ - + ]: 6350 : RESULT_ENSURE_REF(signature_preferences);
206 : :
207 : 6350 : const struct s2n_signature_scheme *fallback_candidate = NULL;
208 : :
209 : : /* We use local preference order, not peer preference order, so we iterate
210 : : * over the local preferences instead of over the options offered by the peer.
211 : : */
212 [ + + ]: 32882 : for (size_t i = 0; i < signature_preferences->count; i++) {
213 : 32844 : const struct s2n_signature_scheme *candidate = signature_preferences->signature_schemes[i];
214 : :
215 : : /* Validates that a signature is valid to choose,
216 : : * including that it's allowed by the current protocol version.
217 : : */
218 [ + + ]: 32844 : if (!s2n_signature_scheme_is_valid_for_recv(conn, candidate)) {
219 : 694 : continue;
220 : 694 : }
221 : :
222 [ + + ]: 32150 : if (s2n_is_sig_scheme_valid_for_auth(conn, candidate) != S2N_SUCCESS) {
223 : 25736 : continue;
224 : 25736 : }
225 : :
226 : : /* s2n-tls first attempts to choose a signature algorithm offered by the peer.
227 : : * However, if that is not possible, we will attempt to continue the handshake
228 : : * anyway with an algorithm not offered by the peer. This fallback behavior
229 : : * is allowed by the RFC for TLS1.3 servers and partially allowed for TLS1.2
230 : : * servers that don't receive the signature_algorithms extension, but is
231 : : * otherwise an intentional deviation from the RFC.
232 : : *
233 : : * TLS1.3 servers:
234 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.4.3
235 : : *# If the CertificateVerify message is sent by a server, the signature
236 : : *# algorithm MUST be one offered in the client's "signature_algorithms"
237 : : *# extension unless no valid certificate chain can be produced without
238 : : *# unsupported algorithms
239 : : *
240 : : * TLS1.3 clients:
241 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.4.3
242 : : *= type=exception
243 : : *= reason=Compatibility with hypothetical faulty peers
244 : : *# If sent by a client, the signature algorithm used in the signature
245 : : *# MUST be one of those present in the supported_signature_algorithms
246 : : *# field of the "signature_algorithms" extension in the
247 : : *# CertificateRequest message.
248 : : *
249 : : * TLS1.2 servers:
250 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-7.4.3
251 : : *= type=exception
252 : : *= reason=Compatibility with known faulty peers
253 : : *# If the client has offered the "signature_algorithms" extension, the
254 : : *# signature algorithm and hash algorithm MUST be a pair listed in that
255 : : *# extension.
256 : : *
257 : : * TLS1.2 clients:
258 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-7.4.8
259 : : *= type=exception
260 : : *= reason=Compatibility with hypothetical faulty peers
261 : : *# The hash and signature algorithms used in the signature MUST be
262 : : *# one of those present in the supported_signature_algorithms field
263 : : *# of the CertificateRequest message.
264 : : */
265 : 6414 : bool is_peer_supported = s2n_signature_algorithm_is_supported_by_peer(
266 : 6414 : conn, candidate->iana_value);
267 [ + + ]: 6414 : if (is_peer_supported) {
268 : 6312 : *chosen_sig_scheme = candidate;
269 : 6312 : return S2N_RESULT_OK;
270 : 6312 : }
271 : :
272 : : /**
273 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-7.4.1.4.1
274 : : *# If the client does not send the signature_algorithms extension, the
275 : : *# server MUST do the following:
276 : : *#
277 : : *# - If the negotiated key exchange algorithm is one of (RSA, DHE_RSA,
278 : : *# DH_RSA, RSA_PSK, ECDH_RSA, ECDHE_RSA), behave as if client had
279 : : *# sent the value {sha1,rsa}.
280 : : *#
281 : : *# - If the negotiated key exchange algorithm is one of (DHE_DSS,
282 : : *# DH_DSS), behave as if the client had sent the value {sha1,dsa}.
283 : : *#
284 : : *# - If the negotiated key exchange algorithm is one of (ECDH_ECDSA,
285 : : *# ECDHE_ECDSA), behave as if the client had sent value {sha1,ecdsa}.
286 : : *
287 : : * The default scheme for DSA is not used because s2n-tls does not support DSA certificates.
288 : : *
289 : : * These defaults are only relevant for TLS1.2, since TLS1.3 does not allow SHA1.
290 : : */
291 [ + + ][ + + ]: 102 : bool is_default = (candidate == &s2n_ecdsa_sha1 || candidate == &s2n_rsa_pkcs1_sha1);
292 : :
293 : : /* If we ultimately cannot choose any algorithm offered by the peer,
294 : : * we will attempt negotiation with an algorithm not offered by the peer.
295 : : *
296 : : * The TLS1.2 RFC specifies default algorithms for use when no signature_algorithms
297 : : * extension is sent-- see the definition of is_default above.
298 : : *
299 : : * s2n-tls has encountered clients in the wild that support the TLS1.2
300 : : * default algorithms but do not include them in their signature_algorithms
301 : : * extension, likely due to a misreading of the RFC. So s2n-tls attempts
302 : : * to use the TLS1.2 defaults even when the client sends the signature_algorithms
303 : : * extension, and always treats them as the most preferred fallback option.
304 : : *
305 : : * If the TLS1.2 defaults are not possible-- for example, because TLS1.3
306 : : * or the security policy forbids SHA1-- we fallback to our own most
307 : : * preferred algorithm. In most cases a correctly implemented peer will reject
308 : : * this fallback, but the only alternative is to kill the connection here.
309 : : */
310 [ + + ]: 102 : if (is_default) {
311 : 9 : fallback_candidate = candidate;
312 [ + + ]: 93 : } else if (fallback_candidate == NULL) {
313 : 38 : fallback_candidate = candidate;
314 : 38 : }
315 : 102 : }
316 : :
317 [ + + ]: 38 : if (fallback_candidate) {
318 : 25 : *chosen_sig_scheme = fallback_candidate;
319 : 25 : } else {
320 [ + - ]: 13 : RESULT_BAIL(S2N_ERR_NO_VALID_SIGNATURE_SCHEME);
321 : 13 : }
322 : 25 : return S2N_RESULT_OK;
323 : 38 : }
324 : :
325 : : S2N_RESULT s2n_signature_algorithms_supported_list_send(struct s2n_connection *conn, struct s2n_stuffer *out)
326 : 7838 : {
327 : 7838 : const struct s2n_signature_preferences *signature_preferences = NULL;
328 [ - + ]: 7838 : RESULT_GUARD_POSIX(s2n_connection_get_signature_preferences(conn, &signature_preferences));
329 [ # # ][ - + ]: 7838 : RESULT_ENSURE_REF(signature_preferences);
330 : :
331 : 7838 : struct s2n_stuffer_reservation size = { 0 };
332 [ - + ]: 7838 : RESULT_GUARD_POSIX(s2n_stuffer_reserve_uint16(out, &size));
333 : :
334 [ + + ]: 121370 : for (size_t i = 0; i < signature_preferences->count; i++) {
335 : 113532 : const struct s2n_signature_scheme *const scheme = signature_preferences->signature_schemes[i];
336 [ - + ][ # # ]: 113532 : RESULT_ENSURE_REF(scheme);
337 [ + + ]: 113532 : if (s2n_signature_scheme_is_valid_for_send(conn, scheme)) {
338 [ - + ]: 109309 : RESULT_GUARD_POSIX(s2n_stuffer_write_uint16(out, scheme->iana_value));
339 : 109309 : }
340 : 113532 : }
341 [ - + ]: 7838 : RESULT_GUARD_POSIX(s2n_stuffer_write_vector_size(&size));
342 : :
343 : 7838 : return S2N_RESULT_OK;
344 : 7838 : }
345 : :
346 : : int s2n_recv_supported_sig_scheme_list(struct s2n_stuffer *in, struct s2n_sig_scheme_list *sig_hash_algs)
347 : 7824 : {
348 : 7824 : uint16_t length_of_all_pairs = 0;
349 [ - + ]: 7824 : POSIX_GUARD(s2n_stuffer_read_uint16(in, &length_of_all_pairs));
350 [ - + ]: 7824 : if (length_of_all_pairs > s2n_stuffer_data_available(in)) {
351 : : /* Malformed length, ignore the extension */
352 : 0 : return 0;
353 : 0 : }
354 : :
355 [ - + ]: 7824 : if (length_of_all_pairs % 2) {
356 : : /* Pairs occur in two byte lengths. Malformed length, ignore the extension and skip ahead */
357 [ # # ]: 0 : POSIX_GUARD(s2n_stuffer_skip_read(in, length_of_all_pairs));
358 : 0 : return 0;
359 : 0 : }
360 : :
361 : 7824 : int pairs_available = length_of_all_pairs / 2;
362 : :
363 [ + + ]: 7824 : if (pairs_available > TLS_SIGNATURE_SCHEME_LIST_MAX_LEN) {
364 [ + - ]: 1 : POSIX_BAIL(S2N_ERR_TOO_MANY_SIGNATURE_SCHEMES);
365 : 1 : }
366 : :
367 : 7823 : sig_hash_algs->len = 0;
368 : :
369 [ + + ]: 117375 : for (size_t i = 0; i < (size_t) pairs_available; i++) {
370 : 109552 : uint16_t sig_scheme = 0;
371 [ - + ]: 109552 : POSIX_GUARD(s2n_stuffer_read_uint16(in, &sig_scheme));
372 : :
373 : 109552 : sig_hash_algs->iana_list[sig_hash_algs->len] = sig_scheme;
374 : 109552 : sig_hash_algs->len += 1;
375 : 109552 : }
376 : :
377 : 7823 : return 0;
378 : 7823 : }
379 : :
380 : : S2N_RESULT s2n_signature_algorithm_get_pkey_type(s2n_signature_algorithm sig_alg, s2n_pkey_type *pkey_type)
381 : 49627 : {
382 [ - + ][ # # ]: 49627 : RESULT_ENSURE_REF(pkey_type);
383 : 49627 : *pkey_type = S2N_PKEY_TYPE_UNKNOWN;
384 : :
385 : 49627 : switch (sig_alg) {
386 [ + + ]: 6407 : case S2N_SIGNATURE_RSA:
387 [ + + ]: 20331 : case S2N_SIGNATURE_RSA_PSS_RSAE:
388 : 20331 : *pkey_type = S2N_PKEY_TYPE_RSA;
389 : 20331 : break;
390 [ + + ]: 11943 : case S2N_SIGNATURE_RSA_PSS_PSS:
391 : 11943 : *pkey_type = S2N_PKEY_TYPE_RSA_PSS;
392 : 11943 : break;
393 [ + + ]: 16807 : case S2N_SIGNATURE_ECDSA:
394 : 16807 : *pkey_type = S2N_PKEY_TYPE_ECDSA;
395 : 16807 : break;
396 [ + + ]: 546 : case S2N_SIGNATURE_MLDSA:
397 : 546 : *pkey_type = S2N_PKEY_TYPE_MLDSA;
398 : 546 : break;
399 [ - + ]: 0 : default:
400 [ # # ]: 0 : RESULT_BAIL(S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
401 : 49627 : }
402 : :
403 : 49627 : return S2N_RESULT_OK;
404 : 49627 : }
405 : :
406 : : DEFINE_POINTER_CLEANUP_FUNC(EC_KEY *, EC_KEY_free);
407 : :
408 : : /**
409 : : * Ensure that the cryptographic signatures match the parameters expected from the TLS protocol.
410 : : *
411 : : * The TLS Protocol definition of signatures differs from the "cryptographic"
412 : : * definition of signatures, so we have to do additional verification to ensure
413 : : * that the signature's parameters (curve, etc) match what was negotiated
414 : : * at the TLS protocol layer. We parse the peer's public key to get these parameters
415 : : * since the signature verification is completely delegated to the libcrypto.
416 : : *
417 : : * In TLS 1.2 we check to ensure that the signature params were one of the
418 : : * items included in our supported_curves extension, which is internally the
419 : : * security policy `ecc_preferences`.
420 : : *
421 : : * In TLS 1.3, the negotiated signature scheme directly encodes the signature
422 : : * parameters (e.g. `ecdsa_secp256r1_sha256`) so we check to ensure that
423 : : * the signature params actually use that curve.
424 : : **/
425 : : S2N_RESULT s2n_signature_scheme_params_match(struct s2n_connection *conn, const struct s2n_pkey *pub_key, const struct s2n_signature_scheme *wire_scheme)
426 : 3364 : {
427 [ - + ][ # # ]: 3364 : RESULT_ENSURE_REF(pub_key);
428 [ - + ][ # # ]: 3364 : RESULT_ENSURE_REF(wire_scheme);
429 : :
430 : 3364 : s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN;
431 : 3364 : EVP_PKEY *evp_key = pub_key->pkey;
432 [ - + ][ # # ]: 3364 : RESULT_ENSURE_REF(evp_key);
433 : :
434 [ - + ]: 3364 : RESULT_GUARD(s2n_pkey_get_type(evp_key, &pkey_type));
435 : :
436 [ + + ]: 3364 : if (pkey_type == S2N_PKEY_TYPE_ECDSA) {
437 : : /* Get the curve that the key is using */
438 : 909 : DEFER_CLEANUP(EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(evp_key), EC_KEY_free_pointer);
439 [ - + ][ # # ]: 909 : RESULT_ENSURE_REF(ec_key);
440 : 909 : const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
441 [ - + ][ # # ]: 909 : RESULT_ENSURE_REF(ec_group);
442 : 909 : int pub_key_curve_nid = EC_GROUP_get_curve_name(ec_group);
443 : :
444 : : /* In TLS1.2, signature algorithms contained no information about which curve should be used.
445 : : * The supported curves extension advertises to the peer which curves were supported. */
446 [ + + ]: 909 : if (conn->actual_protocol_version < S2N_TLS13) {
447 : 257 : const struct s2n_ecc_preferences *ecc_preferences = NULL;
448 [ - + ]: 257 : RESULT_GUARD_POSIX(s2n_connection_get_ecc_preferences(conn, &ecc_preferences));
449 [ # # ][ - + ]: 257 : RESULT_ENSURE_REF(ecc_preferences);
450 : :
451 [ + + ]: 722 : for (size_t i = 0; i < ecc_preferences->count; i++) {
452 : 720 : const struct s2n_ecc_named_curve *supported_curve = ecc_preferences->ecc_curves[i];
453 [ + + ]: 720 : if (supported_curve->libcrypto_nid == pub_key_curve_nid) {
454 : 255 : return S2N_RESULT_OK;
455 : 255 : }
456 : 720 : }
457 [ + - ]: 2 : RESULT_BAIL(S2N_ERR_ECDSA_UNSUPPORTED_CURVE);
458 : :
459 : 652 : } else {
460 : : /* In TLS1.3, the signature algorithm definition also specifies a curve.
461 : : * Therefore we can simply check the wire signature algorithm curve matches the one on the key. */
462 [ + + ][ + - ]: 652 : RESULT_ENSURE_REF(wire_scheme->signature_curve);
463 [ + + ][ + - ]: 650 : RESULT_ENSURE(wire_scheme->signature_curve->libcrypto_nid == pub_key_curve_nid, S2N_ERR_ECDSA_UNSUPPORTED_CURVE);
464 : 650 : }
465 [ - + ]: 2455 : } else if (pkey_type == S2N_PKEY_TYPE_MLDSA) {
466 : : /* TODO: https://github.com/aws/s2n-tls/issues/5740 */
467 : 0 : return S2N_RESULT_OK;
468 [ + + ][ + - ]: 2455 : } else if ((pkey_type == S2N_PKEY_TYPE_RSA) || (pkey_type == S2N_PKEY_TYPE_RSA_PSS)) {
469 : 2455 : return S2N_RESULT_OK;
470 : 2455 : } else {
471 [ # # ]: 0 : RESULT_BAIL(S2N_ERR_UNIMPLEMENTED);
472 : 0 : }
473 : :
474 : 646 : return S2N_RESULT_OK;
475 : 3364 : }
|