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