Coverage Report

Created: 2023-03-26 07:33

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