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 "api/s2n.h"
17 : : #include "error/s2n_errno.h"
18 : : #include "stuffer/s2n_stuffer.h"
19 : : #include "tls/s2n_async_pkey.h"
20 : : #include "tls/s2n_config.h"
21 : : #include "tls/s2n_connection.h"
22 : : #include "tls/s2n_signature_algorithms.h"
23 : : #include "tls/s2n_tls.h"
24 : : #include "utils/s2n_safety.h"
25 : :
26 : : static int s2n_client_cert_verify_send_complete(struct s2n_connection *conn, struct s2n_blob *signature);
27 : :
28 : : int s2n_client_cert_verify_recv(struct s2n_connection *conn)
29 : 64 : {
30 [ - + ][ # # ]: 64 : POSIX_ENSURE_REF(conn);
31 : 64 : struct s2n_handshake_hashes *hashes = conn->handshake.hashes;
32 [ # # ][ - + ]: 64 : POSIX_ENSURE_REF(hashes);
33 : :
34 : 64 : struct s2n_stuffer *in = &conn->handshake.io;
35 : :
36 [ - + ][ - + ]: 126 : S2N_ASYNC_OFFLOAD_POSIX_GUARD(conn, {
[ # # ][ - + ]
[ - + ][ + + ]
[ # # ][ - + ]
[ + + ][ # # ]
[ - + ][ - + ]
[ + + ][ + - ]
37 : 62 : POSIX_GUARD_RESULT(s2n_signature_algorithm_recv(conn, in));
38 : 62 : const struct s2n_signature_scheme *chosen_sig_scheme = conn->handshake_params.client_cert_sig_scheme;
39 : 62 : POSIX_ENSURE_REF(chosen_sig_scheme);
40 : :
41 : 62 : uint16_t signature_size = 0;
42 : 62 : struct s2n_blob signature = { 0 };
43 : 62 : POSIX_GUARD(s2n_stuffer_read_uint16(in, &signature_size));
44 : 62 : signature.size = signature_size;
45 : 62 : signature.data = s2n_stuffer_raw_read(in, signature.size);
46 : 62 : POSIX_ENSURE_REF(signature.data);
47 : :
48 : : /* Use a copy of the hash state since the verify digest computation may modify the running hash state we need later. */
49 : 62 : struct s2n_hash_state *hash_state = &hashes->hash_workspace;
50 : 62 : POSIX_GUARD_RESULT(s2n_handshake_copy_hash_state(conn, chosen_sig_scheme->hash_alg, hash_state));
51 : :
52 : : /* Verify the signature */
53 : 62 : POSIX_GUARD(s2n_async_pkey_verify(conn, chosen_sig_scheme->sig_alg, hash_state, &signature));
54 : 62 : });
55 : :
56 : : /* Client certificate has been verified. Minimize required handshake hash algs */
57 [ - + ]: 62 : POSIX_GUARD(s2n_conn_update_required_handshake_hashes(conn));
58 : :
59 : 62 : return S2N_SUCCESS;
60 : 62 : }
61 : :
62 : : int s2n_client_cert_verify_send(struct s2n_connection *conn)
63 : 81 : {
64 [ - + ][ # # ]: 81 : POSIX_ENSURE_REF(conn);
65 : 81 : struct s2n_handshake_hashes *hashes = conn->handshake.hashes;
66 [ - + ][ # # ]: 81 : POSIX_ENSURE_REF(hashes);
67 : :
68 [ - + ][ + + ]: 81 : S2N_ASYNC_PKEY_GUARD(conn);
[ - + ][ + + ]
[ - + ][ # # ]
69 : 76 : struct s2n_stuffer *out = &conn->handshake.io;
70 : :
71 [ + - ]: 76 : if (conn->actual_protocol_version >= S2N_TLS12) {
72 [ - + ]: 76 : POSIX_GUARD(s2n_stuffer_write_uint16(out, conn->handshake_params.client_cert_sig_scheme->iana_value));
73 : 76 : }
74 : 76 : const struct s2n_signature_scheme *chosen_sig_scheme = conn->handshake_params.client_cert_sig_scheme;
75 [ # # ][ - + ]: 76 : POSIX_ENSURE_REF(chosen_sig_scheme);
76 : :
77 : : /* Use a copy of the hash state since the verify digest computation may modify the running hash state we need later. */
78 : 76 : struct s2n_hash_state *hash_state = &hashes->hash_workspace;
79 [ - + ]: 76 : POSIX_GUARD_RESULT(s2n_handshake_copy_hash_state(conn, chosen_sig_scheme->hash_alg, hash_state));
80 : :
81 [ + + ]: 76 : S2N_ASYNC_PKEY_SIGN(conn, chosen_sig_scheme->sig_alg, hash_state, s2n_client_cert_verify_send_complete);
82 : 0 : }
83 : :
84 : : static int s2n_client_cert_verify_send_complete(struct s2n_connection *conn, struct s2n_blob *signature)
85 : 76 : {
86 : 76 : struct s2n_stuffer *out = &conn->handshake.io;
87 : :
88 [ - + ]: 76 : POSIX_GUARD(s2n_stuffer_write_uint16(out, signature->size));
89 [ - + ]: 76 : POSIX_GUARD(s2n_stuffer_write(out, signature));
90 : :
91 : : /* Client certificate has been verified. Minimize required handshake hash algs */
92 [ - + ]: 76 : POSIX_GUARD(s2n_conn_update_required_handshake_hashes(conn));
93 : :
94 : 76 : return S2N_SUCCESS;
95 : 76 : }
|