/src/gnutls/lib/handshake.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2000-2012 Free Software Foundation, Inc. |
3 | | * Copyright (C) 2017 Red Hat, Inc. |
4 | | * |
5 | | * Author: Nikos Mavrogiannopoulos |
6 | | * |
7 | | * This file is part of GnuTLS. |
8 | | * |
9 | | * The GnuTLS is free software; you can redistribute it and/or |
10 | | * modify it under the terms of the GNU Lesser General Public License |
11 | | * as published by the Free Software Foundation; either version 2.1 of |
12 | | * the License, or (at your option) any later version. |
13 | | * |
14 | | * This library is distributed in the hope that it will be useful, but |
15 | | * WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | | * Lesser General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU Lesser General Public License |
20 | | * along with this program. If not, see <https://www.gnu.org/licenses/> |
21 | | * |
22 | | */ |
23 | | |
24 | | #ifndef GNUTLS_LIB_HANDSHAKE_H |
25 | | # define GNUTLS_LIB_HANDSHAKE_H |
26 | | |
27 | | # include "errors.h" |
28 | | # include "record.h" |
29 | | # include <assert.h> |
30 | | |
31 | | /* The following two macros are used in the handshake state machines; the first |
32 | | * (IMED_RET) accounts for non-fatal errors and re-entry to current state, while |
33 | | * the latter invalidates the handshake on any error (to be used by functions |
34 | | * that are not expected to return non-fatal errors). |
35 | | */ |
36 | 0 | # define IMED_RET( str, ret, allow_alert) do { \ |
37 | 0 | if (ret < 0) { \ |
38 | 0 | /* EAGAIN and INTERRUPTED are always non-fatal */ \ |
39 | 0 | if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) \ |
40 | 0 | return ret; \ |
41 | 0 | if (ret == GNUTLS_E_GOT_APPLICATION_DATA && session->internals.initial_negotiation_completed != 0) \ |
42 | 0 | return ret; \ |
43 | 0 | if (session->internals.handshake_suspicious_loops < 16) { \ |
44 | 0 | if (ret == GNUTLS_E_LARGE_PACKET) { \ |
45 | 0 | session->internals.handshake_suspicious_loops++; \ |
46 | 0 | return ret; \ |
47 | 0 | } \ |
48 | 0 | /* a warning alert might interrupt handshake */ \ |
49 | 0 | if (allow_alert != 0 && ret==GNUTLS_E_WARNING_ALERT_RECEIVED) { \ |
50 | 0 | session->internals.handshake_suspicious_loops++; \ |
51 | 0 | return ret; \ |
52 | 0 | } \ |
53 | 0 | } \ |
54 | 0 | gnutls_assert(); \ |
55 | 0 | /* do not allow non-fatal errors at this point */ \ |
56 | 0 | if (gnutls_error_is_fatal(ret) == 0) ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); \ |
57 | 0 | session_invalidate(session); \ |
58 | 0 | _gnutls_handshake_hash_buffers_clear(session); \ |
59 | 0 | return ret; \ |
60 | 0 | } } while (0) |
61 | | |
62 | 0 | # define IMED_RET_FATAL( str, ret, allow_alert) do { \ |
63 | 0 | if (ret < 0) { \ |
64 | 0 | gnutls_assert(); \ |
65 | 0 | if (gnutls_error_is_fatal(ret) == 0) \ |
66 | 0 | ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); \ |
67 | 0 | session_invalidate(session); \ |
68 | 0 | _gnutls_handshake_hash_buffers_clear(session); \ |
69 | 0 | return ret; \ |
70 | 0 | } } while (0) |
71 | | |
72 | | int _gnutls_send_handshake(gnutls_session_t session, mbuffer_st * bufel, |
73 | | gnutls_handshake_description_t type); |
74 | | int _gnutls_recv_handshake(gnutls_session_t session, |
75 | | gnutls_handshake_description_t type, |
76 | | unsigned int optional, gnutls_buffer_st * buf); |
77 | | |
78 | | int |
79 | | _gnutls_send_handshake2(gnutls_session_t session, mbuffer_st * bufel, |
80 | | gnutls_handshake_description_t type, |
81 | | unsigned queue_only); |
82 | | |
83 | | int _gnutls_generate_session_id(uint8_t * session_id, uint8_t * len); |
84 | | int _gnutls_gen_server_random(gnutls_session_t session, int version); |
85 | | void _gnutls_set_client_random(gnutls_session_t session, uint8_t * rnd); |
86 | | |
87 | | ssize_t _gnutls_send_change_cipher_spec(gnutls_session_t session, int again); |
88 | | |
89 | | int _gnutls_send_server_hello(gnutls_session_t session, int again); |
90 | | |
91 | | int _gnutls_find_pk_algos_in_ciphersuites(uint8_t * data, int datalen); |
92 | | int _gnutls_server_select_suite(gnutls_session_t session, uint8_t * data, |
93 | | unsigned int datalen, unsigned int scsv_only); |
94 | | |
95 | | int _gnutls_negotiate_version(gnutls_session_t session, |
96 | | uint8_t major, uint8_t minor, |
97 | | unsigned allow_tls13); |
98 | | int _gnutls_user_hello_func(gnutls_session_t session, |
99 | | uint8_t major, uint8_t minor); |
100 | | |
101 | | void _gnutls_handshake_hash_buffers_clear(gnutls_session_t session); |
102 | | |
103 | | int _gnutls13_handshake_hash_buffers_synth(gnutls_session_t session, |
104 | | const mac_entry_st * prf, |
105 | | unsigned client); |
106 | | |
107 | 0 | # define STATE session->internals.handshake_state |
108 | 0 | # define FINAL_STATE session->internals.handshake_final_state |
109 | | /* This returns true if we have got there |
110 | | * before (and not finished due to an interrupt). |
111 | | */ |
112 | 0 | # define AGAIN(target) (STATE==target?1:0) |
113 | 0 | # define FAGAIN(target) (FINAL_STATE==target?1:0) |
114 | | # define AGAIN2(state, target) (state==target?1:0) |
115 | | |
116 | | /* return the remaining time in ms */ |
117 | | inline static int handshake_remaining_time(gnutls_session_t session) |
118 | 0 | { |
119 | 0 | struct timespec *end = &session->internals.handshake_abs_timeout; |
120 | |
|
121 | 0 | if (end->tv_sec || end->tv_nsec) { |
122 | 0 | struct timespec now; |
123 | 0 | gnutls_gettime(&now); |
124 | |
|
125 | 0 | if (now.tv_sec < end->tv_sec || |
126 | 0 | (now.tv_sec == end->tv_sec && now.tv_nsec < end->tv_nsec)) { |
127 | 0 | long long now_ms = |
128 | 0 | now.tv_sec * 1000LL + now.tv_nsec / 1000000; |
129 | 0 | long long end_ms = |
130 | 0 | end->tv_sec * 1000LL + end->tv_nsec / 1000000; |
131 | |
|
132 | 0 | return end_ms - now_ms; |
133 | 0 | } else |
134 | 0 | return gnutls_assert_val(GNUTLS_E_TIMEDOUT); |
135 | 0 | } |
136 | 0 | return 0; |
137 | 0 | } Unexecuted instantiation: record.c:handshake_remaining_time Unexecuted instantiation: handshake-tls13.c:handshake_remaining_time Unexecuted instantiation: buffers.c:handshake_remaining_time Unexecuted instantiation: handshake.c:handshake_remaining_time Unexecuted instantiation: kx.c:handshake_remaining_time Unexecuted instantiation: sslv2_compat.c:handshake_remaining_time Unexecuted instantiation: constate.c:handshake_remaining_time Unexecuted instantiation: state.c:handshake_remaining_time Unexecuted instantiation: prf.c:handshake_remaining_time Unexecuted instantiation: handshake-checks.c:handshake_remaining_time Unexecuted instantiation: ocsp-api.c:handshake_remaining_time Unexecuted instantiation: encrypted_extensions.c:handshake_remaining_time Unexecuted instantiation: certificate_request.c:handshake_remaining_time Unexecuted instantiation: certificate_verify.c:handshake_remaining_time Unexecuted instantiation: finished.c:handshake_remaining_time Unexecuted instantiation: key_update.c:handshake_remaining_time Unexecuted instantiation: hello_retry.c:handshake_remaining_time Unexecuted instantiation: session_ticket.c:handshake_remaining_time Unexecuted instantiation: certificate.c:handshake_remaining_time Unexecuted instantiation: early_data.c:handshake_remaining_time Unexecuted instantiation: post_handshake.c:handshake_remaining_time |
138 | | |
139 | | /* Returns non-zero if the present credentials are sufficient for TLS1.3 negotiation. |
140 | | * This is to be used in client side only. On server side, it is allowed to start |
141 | | * without credentials. |
142 | | */ |
143 | | inline static unsigned have_creds_for_tls13(gnutls_session_t session) |
144 | 0 | { |
145 | 0 | assert(session->security_parameters.entity == GNUTLS_CLIENT); |
146 | 0 | if (_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) != NULL || |
147 | 0 | _gnutls_get_cred(session, GNUTLS_CRD_PSK) != NULL) |
148 | 0 | return 1; |
149 | | |
150 | 0 | return 0; |
151 | 0 | } Unexecuted instantiation: record.c:have_creds_for_tls13 Unexecuted instantiation: handshake-tls13.c:have_creds_for_tls13 Unexecuted instantiation: buffers.c:have_creds_for_tls13 Unexecuted instantiation: handshake.c:have_creds_for_tls13 Unexecuted instantiation: kx.c:have_creds_for_tls13 Unexecuted instantiation: sslv2_compat.c:have_creds_for_tls13 Unexecuted instantiation: constate.c:have_creds_for_tls13 Unexecuted instantiation: state.c:have_creds_for_tls13 Unexecuted instantiation: prf.c:have_creds_for_tls13 Unexecuted instantiation: handshake-checks.c:have_creds_for_tls13 Unexecuted instantiation: ocsp-api.c:have_creds_for_tls13 Unexecuted instantiation: encrypted_extensions.c:have_creds_for_tls13 Unexecuted instantiation: certificate_request.c:have_creds_for_tls13 Unexecuted instantiation: certificate_verify.c:have_creds_for_tls13 Unexecuted instantiation: finished.c:have_creds_for_tls13 Unexecuted instantiation: key_update.c:have_creds_for_tls13 Unexecuted instantiation: hello_retry.c:have_creds_for_tls13 Unexecuted instantiation: session_ticket.c:have_creds_for_tls13 Unexecuted instantiation: certificate.c:have_creds_for_tls13 Unexecuted instantiation: early_data.c:have_creds_for_tls13 Unexecuted instantiation: post_handshake.c:have_creds_for_tls13 |
152 | | |
153 | | int _gnutls_handshake_get_session_hash(gnutls_session_t session, |
154 | | gnutls_datum_t * shash); |
155 | | |
156 | | int _gnutls_check_id_for_change(gnutls_session_t session); |
157 | | int _gnutls_check_if_cert_hash_is_same(gnutls_session_t session, |
158 | | gnutls_certificate_credentials_t cred); |
159 | | |
160 | | # include "handshake-defs.h" |
161 | | |
162 | | int _gnutls_call_hook_func(gnutls_session_t session, |
163 | | gnutls_handshake_description_t type, |
164 | | int post, unsigned incoming, |
165 | | const uint8_t * data, unsigned data_size); |
166 | | |
167 | | int _gnutls_run_verify_callback(gnutls_session_t session, unsigned int side); |
168 | | int _gnutls_recv_finished(gnutls_session_t session); |
169 | | int _gnutls_send_finished(gnutls_session_t session, int again); |
170 | | |
171 | | int _gnutls13_handshake_client(gnutls_session_t session); |
172 | | int _gnutls13_handshake_server(gnutls_session_t session); |
173 | | |
174 | | int |
175 | | _gnutls13_recv_hello_retry_request(gnutls_session_t session, |
176 | | gnutls_buffer_st * buf); |
177 | | |
178 | | int _gnutls13_recv_async_handshake(gnutls_session_t session); |
179 | | |
180 | | #endif /* GNUTLS_LIB_HANDSHAKE_H */ |