/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 | | #define IMED_RET(str, ret, allow_alert) \ |
37 | 0 | do { \ |
38 | 0 | if (ret < 0) { \ |
39 | 0 | /* EAGAIN and INTERRUPTED are always non-fatal */ \ |
40 | 0 | if (ret == GNUTLS_E_AGAIN || \ |
41 | 0 | ret == GNUTLS_E_INTERRUPTED) \ |
42 | 0 | return ret; \ |
43 | 0 | if (ret == GNUTLS_E_GOT_APPLICATION_DATA && \ |
44 | 0 | session->internals.initial_negotiation_completed != \ |
45 | 0 | 0) \ |
46 | 0 | return ret; \ |
47 | 0 | if (session->internals.handshake_suspicious_loops < \ |
48 | 0 | 16) { \ |
49 | 0 | if (ret == GNUTLS_E_LARGE_PACKET) { \ |
50 | 0 | session->internals \ |
51 | 0 | .handshake_suspicious_loops++; \ |
52 | 0 | return ret; \ |
53 | 0 | } \ |
54 | 0 | /* a warning alert might interrupt handshake */ \ |
55 | 0 | if (allow_alert != 0 && \ |
56 | 0 | ret == GNUTLS_E_WARNING_ALERT_RECEIVED) { \ |
57 | 0 | session->internals \ |
58 | 0 | .handshake_suspicious_loops++; \ |
59 | 0 | return ret; \ |
60 | 0 | } \ |
61 | 0 | } \ |
62 | 0 | gnutls_assert(); \ |
63 | 0 | /* do not allow non-fatal errors at this point */ \ |
64 | 0 | if (gnutls_error_is_fatal(ret) == 0) \ |
65 | 0 | ret = gnutls_assert_val( \ |
66 | 0 | GNUTLS_E_INTERNAL_ERROR); \ |
67 | 0 | session_invalidate(session); \ |
68 | 0 | _gnutls_handshake_hash_buffers_clear(session); \ |
69 | 0 | return ret; \ |
70 | 0 | } \ |
71 | 0 | } while (0) |
72 | | |
73 | | #define IMED_RET_FATAL(str, ret, allow_alert) \ |
74 | 0 | do { \ |
75 | 0 | if (ret < 0) { \ |
76 | 0 | gnutls_assert(); \ |
77 | 0 | if (gnutls_error_is_fatal(ret) == 0) \ |
78 | 0 | ret = gnutls_assert_val( \ |
79 | 0 | GNUTLS_E_INTERNAL_ERROR); \ |
80 | 0 | session_invalidate(session); \ |
81 | 0 | _gnutls_handshake_hash_buffers_clear(session); \ |
82 | 0 | return ret; \ |
83 | 0 | } \ |
84 | 0 | } while (0) |
85 | | |
86 | | int _gnutls_send_handshake(gnutls_session_t session, mbuffer_st *bufel, |
87 | | gnutls_handshake_description_t type); |
88 | | int _gnutls_recv_handshake(gnutls_session_t session, |
89 | | gnutls_handshake_description_t type, |
90 | | unsigned int optional, gnutls_buffer_st *buf); |
91 | | |
92 | | int _gnutls_send_handshake2(gnutls_session_t session, mbuffer_st *bufel, |
93 | | gnutls_handshake_description_t type, |
94 | | unsigned queue_only); |
95 | | |
96 | | int _gnutls_generate_session_id(uint8_t *session_id, uint8_t *len); |
97 | | int _gnutls_gen_server_random(gnutls_session_t session, int version); |
98 | | void _gnutls_set_client_random(gnutls_session_t session, uint8_t *rnd); |
99 | | |
100 | | ssize_t _gnutls_send_change_cipher_spec(gnutls_session_t session, int again); |
101 | | |
102 | | int _gnutls_send_server_hello(gnutls_session_t session, int again); |
103 | | |
104 | | int _gnutls_find_pk_algos_in_ciphersuites(uint8_t *data, int datalen); |
105 | | int _gnutls_server_select_suite(gnutls_session_t session, uint8_t *data, |
106 | | unsigned int datalen, unsigned int scsv_only); |
107 | | |
108 | | int _gnutls_negotiate_version(gnutls_session_t session, uint8_t major, |
109 | | uint8_t minor, unsigned allow_tls13); |
110 | | int _gnutls_user_hello_func(gnutls_session_t session, uint8_t major, |
111 | | uint8_t minor); |
112 | | |
113 | | void _gnutls_handshake_hash_buffers_clear(gnutls_session_t session); |
114 | | |
115 | | int _gnutls13_handshake_hash_buffers_synth(gnutls_session_t session, |
116 | | const mac_entry_st *prf, |
117 | | unsigned client); |
118 | | |
119 | 0 | #define STATE session->internals.handshake_state |
120 | 0 | #define FINAL_STATE session->internals.handshake_final_state |
121 | | /* This returns true if we have got there |
122 | | * before (and not finished due to an interrupt). |
123 | | */ |
124 | 0 | #define AGAIN(target) (STATE == target ? 1 : 0) |
125 | 0 | #define FAGAIN(target) (FINAL_STATE == target ? 1 : 0) |
126 | | #define AGAIN2(state, target) (state == target ? 1 : 0) |
127 | | |
128 | | /* return the remaining time in ms */ |
129 | | inline static int handshake_remaining_time(gnutls_session_t session) |
130 | 0 | { |
131 | 0 | struct timespec *end = &session->internals.handshake_abs_timeout; |
132 | |
|
133 | 0 | if (end->tv_sec || end->tv_nsec) { |
134 | 0 | struct timespec now; |
135 | 0 | gnutls_gettime(&now); |
136 | |
|
137 | 0 | if (now.tv_sec < end->tv_sec || |
138 | 0 | (now.tv_sec == end->tv_sec && now.tv_nsec < end->tv_nsec)) { |
139 | 0 | long long now_ms = |
140 | 0 | now.tv_sec * 1000LL + now.tv_nsec / 1000000; |
141 | 0 | long long end_ms = |
142 | 0 | end->tv_sec * 1000LL + end->tv_nsec / 1000000; |
143 | |
|
144 | 0 | return end_ms - now_ms; |
145 | 0 | } else |
146 | 0 | return gnutls_assert_val(GNUTLS_E_TIMEDOUT); |
147 | 0 | } |
148 | 0 | return 0; |
149 | 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 Unexecuted instantiation: key_share.c:handshake_remaining_time Unexecuted instantiation: pre_shared_key.c:handshake_remaining_time Unexecuted instantiation: status_request.c:handshake_remaining_time Unexecuted instantiation: supported_versions.c:handshake_remaining_time |
150 | | |
151 | | /* Returns non-zero if the present credentials are sufficient for TLS1.3 negotiation. |
152 | | * This is to be used in client side only. On server side, it is allowed to start |
153 | | * without credentials. |
154 | | */ |
155 | | inline static unsigned have_creds_for_tls13(gnutls_session_t session) |
156 | 0 | { |
157 | 0 | assert(session->security_parameters.entity == GNUTLS_CLIENT); |
158 | 0 | if (_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) != NULL || |
159 | 0 | _gnutls_get_cred(session, GNUTLS_CRD_PSK) != NULL) |
160 | 0 | return 1; |
161 | | |
162 | 0 | return 0; |
163 | 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 Unexecuted instantiation: key_share.c:have_creds_for_tls13 Unexecuted instantiation: pre_shared_key.c:have_creds_for_tls13 Unexecuted instantiation: status_request.c:have_creds_for_tls13 Unexecuted instantiation: supported_versions.c:have_creds_for_tls13 |
164 | | |
165 | | int _gnutls_handshake_get_session_hash(gnutls_session_t session, |
166 | | gnutls_datum_t *shash); |
167 | | |
168 | | int _gnutls_check_id_for_change(gnutls_session_t session); |
169 | | int _gnutls_check_if_cert_hash_is_same(gnutls_session_t session, |
170 | | gnutls_certificate_credentials_t cred); |
171 | | |
172 | | #include "handshake-defs.h" |
173 | | |
174 | | int _gnutls_call_hook_func(gnutls_session_t session, |
175 | | gnutls_handshake_description_t type, int post, |
176 | | unsigned incoming, const uint8_t *data, |
177 | | unsigned data_size); |
178 | | |
179 | | int _gnutls_run_verify_callback(gnutls_session_t session, unsigned int side); |
180 | | int _gnutls_recv_finished(gnutls_session_t session); |
181 | | int _gnutls_send_finished(gnutls_session_t session, int again); |
182 | | |
183 | | int _gnutls13_handshake_client(gnutls_session_t session); |
184 | | int _gnutls13_handshake_server(gnutls_session_t session); |
185 | | |
186 | | int _gnutls13_recv_hello_retry_request(gnutls_session_t session, |
187 | | gnutls_buffer_st *buf); |
188 | | |
189 | | int _gnutls13_recv_async_handshake(gnutls_session_t session); |
190 | | |
191 | | #endif /* GNUTLS_LIB_HANDSHAKE_H */ |