Coverage Report

Created: 2025-03-18 06:55

/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 */