Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/hello_ext.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
3
 * Copyright (C) 2015-2018 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_HELLO_EXT_H
25
# define GNUTLS_LIB_HELLO_EXT_H
26
27
# include "gnutls_int.h"
28
# include <gnutls/gnutls.h>
29
# include "str.h"
30
31
/* Functions for hello extension parsing.
32
 */
33
int _gnutls_parse_hello_extensions(gnutls_session_t session,
34
           gnutls_ext_flags_t msg,
35
           gnutls_ext_parse_type_t parse_type,
36
           const uint8_t * data, int data_size);
37
int _gnutls_gen_hello_extensions(gnutls_session_t session,
38
         gnutls_buffer_st * extdata,
39
         gnutls_ext_flags_t msg,
40
         gnutls_ext_parse_type_t);
41
int _gnutls_hello_ext_init(void);
42
void _gnutls_hello_ext_deinit(void);
43
44
void _gnutls_hello_ext_priv_deinit(gnutls_session_t session);
45
46
/* functions to be used by extensions internally
47
 */
48
void _gnutls_hello_ext_unset_priv(gnutls_session_t session, extensions_t ext);
49
void _gnutls_hello_ext_set_priv(gnutls_session_t session, extensions_t ext,
50
        gnutls_ext_priv_data_t);
51
int _gnutls_hello_ext_get_priv(gnutls_session_t session, extensions_t ext,
52
             gnutls_ext_priv_data_t *);
53
int _gnutls_hello_ext_get_resumed_priv(gnutls_session_t session,
54
               extensions_t ext,
55
               gnutls_ext_priv_data_t * data);
56
57
# define GNUTLS_EXT_FLAG_MSG_MASK (GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO| \
58
     GNUTLS_EXT_FLAG_TLS13_SERVER_HELLO | GNUTLS_EXT_FLAG_EE | GNUTLS_EXT_FLAG_HRR)
59
60
/* these flags can only be set in the extensions, but cannot be requested;
61
 * they are handled internally by the hello parsing/generating functions. */
62
# define GNUTLS_EXT_FLAG_SET_ONLY_FLAGS_MASK ~(GNUTLS_EXT_FLAG_DTLS | GNUTLS_EXT_FLAG_TLS)
63
64
/* obtain the message this extension was received at */
65
inline static gnutls_ext_flags_t _gnutls_ext_get_msg(gnutls_session_t session)
66
0
{
67
0
  return session->internals.ext_msg & GNUTLS_EXT_FLAG_MSG_MASK;
68
0
}
69
70
inline static void _gnutls_ext_set_msg(gnutls_session_t session,
71
               gnutls_ext_flags_t msg)
72
0
{
73
0
  session->internals.ext_msg = msg;
74
0
}
75
76
inline static void _gnutls_ext_set_extensions_offset(gnutls_session_t session,
77
                 int offset)
78
0
{
79
0
  session->internals.extensions_offset = offset;
80
0
}
81
82
inline static int _gnutls_ext_get_extensions_offset(gnutls_session_t session)
83
0
{
84
0
  return session->internals.extensions_offset;
85
0
}
86
87
int _gnutls_ext_set_full_client_hello(gnutls_session_t session,
88
              handshake_buffer_st * recv_buf);
89
unsigned _gnutls_ext_get_full_client_hello(gnutls_session_t session,
90
             gnutls_datum_t * datum);
91
92
/* for session packing */
93
int _gnutls_hello_ext_pack(gnutls_session_t session, gnutls_buffer_st * packed);
94
int _gnutls_hello_ext_unpack(gnutls_session_t session,
95
           gnutls_buffer_st * packed);
96
97
inline static const char *ext_msg_validity_to_str(gnutls_ext_flags_t msg)
98
0
{
99
0
  msg &= GNUTLS_EXT_FLAG_MSG_MASK;
100
0
101
0
  switch (msg) {
102
0
  case GNUTLS_EXT_FLAG_CLIENT_HELLO:
103
0
    return "client hello";
104
0
  case GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO:
105
0
    return "TLS 1.2 server hello";
106
0
  case GNUTLS_EXT_FLAG_TLS13_SERVER_HELLO:
107
0
    return "TLS 1.3 server hello";
108
0
  case GNUTLS_EXT_FLAG_EE:
109
0
    return "encrypted extensions";
110
0
  case GNUTLS_EXT_FLAG_HRR:
111
0
    return "hello retry request";
112
0
  default:
113
0
    return "(unknown)";
114
0
  }
115
0
}
116
117
typedef struct hello_ext_entry_st {
118
  const char *name; /* const overridden when free_struct is set */
119
  unsigned free_struct;
120
121
  uint16_t tls_id;
122
  unsigned gid;   /* gnutls internal ID */
123
124
  gnutls_ext_parse_type_t client_parse_point;
125
  gnutls_ext_parse_type_t server_parse_point;
126
  unsigned validity;  /* multiple items of gnutls_ext_flags_t */
127
128
  /* this function must return 0 when Not Applicable
129
   * size of extension data if ok
130
   * < 0 on other error.
131
   */
132
  gnutls_ext_recv_func recv_func;
133
134
  /* this function must return 0 when Not Applicable
135
   * size of extension data if ok
136
   * GNUTLS_E_INT_RET_0 if extension data size is zero
137
   * < 0 on other error.
138
   */
139
  gnutls_ext_send_func send_func;
140
141
  gnutls_ext_deinit_data_func deinit_func;  /* this will be called to deinitialize
142
               * internal data
143
               */
144
  gnutls_ext_pack_func pack_func; /* packs internal data to machine independent format */
145
  gnutls_ext_unpack_func unpack_func; /* unpacks internal data */
146
147
  /* non-zero if that extension cannot be overridden by the applications.
148
   * That should be set to extensions which allocate data early, e.g., on
149
   * gnutls_init(), or modify the TLS protocol in a way that the application
150
   * cannot control. */
151
  unsigned cannot_be_overriden;
152
} hello_ext_entry_st;
153
154
/* Checks if the extension @id provided has been requested
155
 * by us (in client side).In server side it checks whether this
156
 * extension was advertized by the client.
157
 *
158
 * It returns non-zero for true, otherwise zero.
159
 */
160
inline static unsigned
161
_gnutls_hello_ext_is_present(gnutls_session_t session, extensions_t id)
162
0
{
163
0
  if (session->internals.used_exts & ((ext_track_t) 1 << id))
164
0
    return 1;
165
0
166
0
  return 0;
167
0
}
168
169
/* Adds the extension we want to send in the extensions list.
170
 * This list is used in client side to check whether the (later) received
171
 * extensions are the ones we requested.
172
 *
173
 * In server side, this list is used to ensure we don't send
174
 * extensions that we didn't receive a corresponding value.
175
 *
176
 * Returns zero if failed, non-zero on success.
177
 */
178
inline static
179
unsigned _gnutls_hello_ext_save(gnutls_session_t session,
180
        extensions_t id, unsigned check_dup)
181
0
{
182
0
  if (check_dup && _gnutls_hello_ext_is_present(session, id)) {
183
0
    return 0;
184
0
  }
185
0
186
0
  session->internals.used_exts |= ((ext_track_t) 1 << id);
187
0
188
0
  return 1;
189
0
}
190
191
inline static
192
void _gnutls_hello_ext_save_sr(gnutls_session_t session)
193
0
{
194
0
  _gnutls_hello_ext_save(session, GNUTLS_EXTENSION_SAFE_RENEGOTIATION, 1);
195
0
}
196
197
#endif        /* GNUTLS_LIB_HELLO_EXT_H */