OpenVPN
ssl_ncp.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
9  * Copyright (C) 2010-2021 Fox Crypto B.V. <openvpn@foxcrypto.com>
10  * Copyright (C) 2008-2024 David Sommerseth <dazo@eurephia.org>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2
14  * as published by the Free Software Foundation.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
31 /*
32  * The routines in this file deal with dynamically negotiating
33  * the data channel HMAC and cipher keys through a TLS session.
34  *
35  * Both the TLS session and the data channel are multiplexed
36  * over the same TCP/UDP port.
37  */
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41 
42 #include "syshead.h"
43 #include "win32.h"
44 
45 #include "error.h"
46 #include "common.h"
47 
48 #include "ssl_ncp.h"
49 #include "ssl_util.h"
50 #include "openvpn.h"
51 
56 static int
57 tls_peer_info_ncp_ver(const char *peer_info)
58 {
59  const char *ncpstr = peer_info ? strstr(peer_info, "IV_NCP=") : NULL;
60  if (ncpstr)
61  {
62  int ncp = 0;
63  int r = sscanf(ncpstr, "IV_NCP=%d", &ncp);
64  if (r == 1)
65  {
66  return ncp;
67  }
68  }
69  return 0;
70 }
71 
76 bool
77 tls_peer_supports_ncp(const char *peer_info)
78 {
79  if (!peer_info)
80  {
81  return false;
82  }
83  else if (tls_peer_info_ncp_ver(peer_info) >= 2
84  || strstr(peer_info, "IV_CIPHERS="))
85  {
86  return true;
87  }
88  else
89  {
90  return false;
91  }
92 }
93 
94 char *
95 mutate_ncp_cipher_list(const char *list, struct gc_arena *gc)
96 {
97  bool error_found = false;
98 
99  struct buffer new_list = alloc_buf(MAX_NCP_CIPHERS_LENGTH);
100 
101  char *const tmp_ciphers = string_alloc(list, NULL);
102  const char *token = strtok(tmp_ciphers, ":");
103  while (token)
104  {
105  /*
106  * Going cipher_kt_name (and translate_cipher_name_from_openvpn/
107  * translate_cipher_name_to_openvpn) also normalises the cipher name,
108  * e.g. replacing AeS-128-gCm with AES-128-GCM
109  *
110  * ciphers that have ? in front of them are considered optional and
111  * OpenVPN will only warn if they are not found (and remove them from
112  * the list)
113  */
114  bool optional = false;
115  if (token[0] == '?')
116  {
117  token++;
118  optional = true;
119  }
120 
121  const bool nonecipher = (strcmp(token, "none") == 0);
122  const char *optstr = optional ? "optional " : "";
123 
124  if (nonecipher)
125  {
126  msg(M_WARN, "WARNING: cipher 'none' specified for --data-ciphers. "
127  "This allows negotiation of NO encryption and "
128  "tunnelled data WILL then be transmitted in clear text "
129  "over the network! "
130  "PLEASE DO RECONSIDER THIS SETTING!");
131  }
132  if (!nonecipher && !cipher_valid(token))
133  {
134  msg(M_WARN, "Unsupported %scipher in --data-ciphers: %s", optstr, token);
135  error_found = error_found || !optional;
136  }
137  else if (!nonecipher && !cipher_kt_mode_aead(token)
138  && !cipher_kt_mode_cbc(token)
139  && !cipher_kt_mode_ofb_cfb(token))
140  {
141  msg(M_WARN, "Unsupported %scipher algorithm '%s'. It does not use "
142  "CFB, OFB, CBC, or a supported AEAD mode", optstr, token);
143  error_found = error_found || !optional;
144  }
145  else
146  {
147  const char *ovpn_cipher_name = cipher_kt_name(token);
148  if (nonecipher)
149  {
150  /* NULL resolves to [null-cipher] but we need none for
151  * data-ciphers */
152  ovpn_cipher_name = "none";
153  }
154 
155  if (buf_len(&new_list)> 0)
156  {
157  /* The next if condition ensure there is always space for
158  * a :
159  */
160  buf_puts(&new_list, ":");
161  }
162 
163  /* Ensure buffer has capacity for cipher name + : + \0 */
164  if (!(buf_forward_capacity(&new_list) >
165  strlen(ovpn_cipher_name) + 2))
166  {
167  msg(M_WARN, "Length of --data-ciphers is over the "
168  "limit of 127 chars");
169  error_found = true;
170  }
171  else
172  {
173  buf_puts(&new_list, ovpn_cipher_name);
174  }
175  }
176  token = strtok(NULL, ":");
177  }
178 
179 
180 
181  char *ret = NULL;
182  if (!error_found && buf_len(&new_list) > 0)
183  {
184  buf_null_terminate(&new_list);
185  ret = string_alloc(buf_str(&new_list), gc);
186  }
187  free(tmp_ciphers);
188  free_buf(&new_list);
189 
190  return ret;
191 }
192 
193 
194 void
195 append_cipher_to_ncp_list(struct options *o, const char *ciphername)
196 {
197  /* Append the --cipher to ncp_ciphers to allow it in NCP */
198  size_t newlen = strlen(o->ncp_ciphers) + 1 + strlen(ciphername) + 1;
199  char *ncp_ciphers = gc_malloc(newlen, false, &o->gc);
200 
201  ASSERT(snprintf(ncp_ciphers, newlen, "%s:%s", o->ncp_ciphers,
202  ciphername));
203  o->ncp_ciphers = ncp_ciphers;
204 }
205 
206 bool
207 tls_item_in_cipher_list(const char *item, const char *list)
208 {
209  char *tmp_ciphers = string_alloc(list, NULL);
210  char *tmp_ciphers_orig = tmp_ciphers;
211 
212  const char *token = strtok(tmp_ciphers, ":");
213  while (token)
214  {
215  if (0 == strcmp(token, item))
216  {
217  break;
218  }
219  token = strtok(NULL, ":");
220  }
221  free(tmp_ciphers_orig);
222 
223  return token != NULL;
224 }
225 
226 const char *
227 tls_peer_ncp_list(const char *peer_info, struct gc_arena *gc)
228 {
229  /* Check if the peer sends the IV_CIPHERS list */
230  const char *iv_ciphers = extract_var_peer_info(peer_info, "IV_CIPHERS=", gc);
231  if (iv_ciphers)
232  {
233  return iv_ciphers;
234  }
235  else if (tls_peer_info_ncp_ver(peer_info)>=2)
236  {
237  /* If the peer announces IV_NCP=2 then it supports the AES GCM
238  * ciphers */
239  return "AES-256-GCM:AES-128-GCM";
240  }
241  else
242  {
243  return "";
244  }
245 }
246 
247 char *
248 ncp_get_best_cipher(const char *server_list, const char *peer_info,
249  const char *remote_cipher, struct gc_arena *gc)
250 {
251  /*
252  * The gc of the parameter is tied to the VPN session, create a
253  * short lived gc arena that is only valid for the duration of
254  * this function
255  */
256 
257  struct gc_arena gc_tmp = gc_new();
258 
259  const char *peer_ncp_list = tls_peer_ncp_list(peer_info, &gc_tmp);
260 
261  /* non-NCP clients without OCC? "assume nothing" */
262  /* For client doing the newer version of NCP (that send IV_CIPHERS)
263  * we cannot assume that they will accept remote_cipher */
264  if (remote_cipher == NULL
265  || (peer_info && strstr(peer_info, "IV_CIPHERS=")))
266  {
267  remote_cipher = "";
268  }
269 
270  char *tmp_ciphers = string_alloc(server_list, &gc_tmp);
271 
272  const char *token;
273  while ((token = strsep(&tmp_ciphers, ":")))
274  {
275  if (tls_item_in_cipher_list(token, peer_ncp_list)
276  || streq(token, remote_cipher))
277  {
278  break;
279  }
280  }
281 
282  char *ret = NULL;
283  if (token != NULL)
284  {
285  ret = string_alloc(token, gc);
286  }
287 
288  gc_free(&gc_tmp);
289  return ret;
290 }
291 
301 static bool
302 tls_poor_mans_ncp(struct options *o, const char *remote_ciphername)
303 {
304  if (remote_ciphername
305  && tls_item_in_cipher_list(remote_ciphername, o->ncp_ciphers))
306  {
307  o->ciphername = string_alloc(remote_ciphername, &o->gc);
308  msg(D_TLS_DEBUG_LOW, "Using peer cipher '%s'", o->ciphername);
309  return true;
310  }
311  return false;
312 }
313 
314 bool
315 check_pull_client_ncp(struct context *c, const int found)
316 {
317  if (found & OPT_P_NCP)
318  {
319  msg(D_PUSH_DEBUG, "OPTIONS IMPORT: data channel crypto options modified");
320  return true;
321  }
322 
323  /* If the server did not push a --cipher, we will switch to the
324  * remote cipher if it is in our ncp-ciphers list */
326  {
327  return true;
328  }
329 
330  /* We could not figure out the peer's cipher but we have fallback
331  * enabled */
333  {
334  return true;
335  }
336 
337  /* We failed negotiation, give appropiate error message */
339  {
340  msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to negotiate "
341  "cipher with server. Add the server's "
342  "cipher ('%s') to --data-ciphers (currently '%s') if "
343  "you want to connect to this server.",
345  c->options.ncp_ciphers);
346  return false;
347 
348  }
349  else
350  {
351  msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to negotiate "
352  "cipher with server. Configure "
353  "--data-ciphers-fallback if you want to connect "
354  "to this server.");
355  return false;
356  }
357 }
358 
359 const char *
360 get_p2p_ncp_cipher(struct tls_session *session, const char *peer_info,
361  struct gc_arena *gc)
362 {
363  /* we use a local gc arena to keep the temporary strings needed by strsep */
364  struct gc_arena gc_local = gc_new();
365  const char *peer_ciphers = extract_var_peer_info(peer_info, "IV_CIPHERS=", &gc_local);
366 
367  if (!peer_ciphers)
368  {
369  gc_free(&gc_local);
370  return NULL;
371  }
372 
373  const char *server_ciphers;
374  const char *client_ciphers;
375 
376  if (session->opt->server)
377  {
378  server_ciphers = session->opt->config_ncp_ciphers;
379  client_ciphers = peer_ciphers;
380  }
381  else
382  {
383  client_ciphers = session->opt->config_ncp_ciphers;
384  server_ciphers = peer_ciphers;
385  }
386 
387  /* Find the first common cipher from TLS server and TLS client. We
388  * use the preference of the server here to make it deterministic */
389  char *tmp_ciphers = string_alloc(server_ciphers, &gc_local);
390 
391  const char *token;
392  while ((token = strsep(&tmp_ciphers, ":")))
393  {
394  if (tls_item_in_cipher_list(token, client_ciphers))
395  {
396  break;
397  }
398  }
399 
400  const char *ret = NULL;
401  if (token != NULL)
402  {
403  ret = string_alloc(token, gc);
404  }
405  gc_free(&gc_local);
406 
407  return ret;
408 }
409 
410 static void
412 {
413  /* will return 0 if peer_info is null */
414  const unsigned int iv_proto_peer = extract_iv_proto(multi->peer_info);
415 
416  /* The other peer does not support P2P NCP */
417  if (!(iv_proto_peer & IV_PROTO_NCP_P2P))
418  {
419  return;
420  }
421 
422  if (iv_proto_peer & IV_PROTO_DATA_V2)
423  {
424  multi->use_peer_id = true;
425  multi->peer_id = 0x76706e; /* 'v' 'p' 'n' */
426  }
427 
428  if (iv_proto_peer & IV_PROTO_CC_EXIT_NOTIFY)
429  {
430  session->opt->crypto_flags |= CO_USE_CC_EXIT_NOTIFY;
431  }
432 
433 #if defined(HAVE_EXPORT_KEYING_MATERIAL)
434  if (iv_proto_peer & IV_PROTO_TLS_KEY_EXPORT)
435  {
436  session->opt->crypto_flags |= CO_USE_TLS_KEY_MATERIAL_EXPORT;
437 
438  if (multi->use_peer_id)
439  {
440  /* Using a non hardcoded peer-id makes a tiny bit harder to
441  * fingerprint packets and also gives each connection a unique
442  * peer-id that can be useful for NAT tracking etc. */
443 
444  uint8_t peerid[3];
446  strlen(EXPORT_P2P_PEERID_LABEL),
447  &peerid, 3))
448  {
449  /* Non DCO setup might still work but also this should never
450  * happen or very likely the TLS encryption key exporter will
451  * also fail */
452  msg(M_NONFATAL, "TLS key export for P2P peer id failed. "
453  "Continuing anyway, expect problems");
454  }
455  else
456  {
457  multi->peer_id = (peerid[0] << 16) + (peerid[1] << 8) + peerid[2];
458  }
459 
460  }
461  }
462  if (iv_proto_peer & IV_PROTO_DYN_TLS_CRYPT)
463  {
464  session->opt->crypto_flags |= CO_USE_DYNAMIC_TLS_CRYPT;
465  }
466 #endif /* if defined(HAVE_EXPORT_KEYING_MATERIAL) */
467 }
468 
469 void
470 p2p_mode_ncp(struct tls_multi *multi, struct tls_session *session)
471 {
472  /* Set the common options */
474 
475  struct gc_arena gc = gc_new();
476 
477  /* Query the common cipher here to log it as part of our message.
478  * We postpone switching the cipher to do_up */
479  const char *common_cipher = get_p2p_ncp_cipher(session, multi->peer_info, &gc);
480 
481  if (!common_cipher)
482  {
483  struct buffer out = alloc_buf_gc(128, &gc);
484  /* at this point we do not really know if our fallback is
485  * not enabled or if we use 'none' cipher as fallback, so
486  * keep this ambiguity here and print fallback-cipher: none
487  */
488 
489  const char *fallback_name = "none";
490  const char *ciphername = session->opt->key_type.cipher;
491 
492  if (cipher_defined(ciphername))
493  {
494  fallback_name = cipher_kt_name(ciphername);
495  }
496 
497  buf_printf(&out, "(not negotiated, fallback-cipher: %s)", fallback_name);
498  common_cipher = BSTR(&out);
499  }
500 
501  msg(D_TLS_DEBUG_LOW, "P2P mode NCP negotiation result: "
502  "TLS_export=%d, DATA_v2=%d, peer-id %d, cipher=%s",
503  (bool)(session->opt->crypto_flags & CO_USE_TLS_KEY_MATERIAL_EXPORT),
504  multi->use_peer_id, multi->peer_id, common_cipher);
505 
506  gc_free(&gc);
507 }
508 
509 
510 bool
512 {
513  bool cipher_allowed_as_fallback = options->enable_ncp_fallback
514  && streq(options->ciphername, session->opt->config_ciphername);
515 
516  if (!session->opt->server && !cipher_allowed_as_fallback
518  {
519  msg(D_TLS_ERRORS, "Error: negotiated cipher not allowed - %s not in %s",
521  /* undo cipher push, abort connection setup */
522  options->ciphername = session->opt->config_ciphername;
523  return false;
524  }
525  else
526  {
527  return true;
528  }
529 }
tls_poor_mans_ncp
static bool tls_poor_mans_ncp(struct options *o, const char *remote_ciphername)
"Poor man's NCP": Use peer cipher if it is an allowed (NCP) cipher.
Definition: ssl_ncp.c:302
cipher_valid
static bool cipher_valid(const char *ciphername)
Returns if the cipher is valid, based on the given cipher name.
Definition: crypto_backend.h:204
tls_peer_info_ncp_ver
static int tls_peer_info_ncp_ver(const char *peer_info)
Return the Negotiable Crypto Parameters version advertised in the peer info string,...
Definition: ssl_ncp.c:57
error.h
options::enable_ncp_fallback
bool enable_ncp_fallback
If defined fall back to ciphername if NCP fails.
Definition: options.h:557
gc_new
static struct gc_arena gc_new(void)
Definition: buffer.h:1030
IV_PROTO_DATA_V2
#define IV_PROTO_DATA_V2
Support P_DATA_V2.
Definition: ssl.h:79
context_2::tls_multi
struct tls_multi * tls_multi
TLS state structure for this VPN tunnel.
Definition: openvpn.h:326
tls_item_in_cipher_list
bool tls_item_in_cipher_list(const char *item, const char *list)
Return true iff item is present in the colon-separated zero-terminated cipher list.
Definition: ssl_ncp.c:207
win32.h
cipher_defined
static bool cipher_defined(const char *ciphername)
Checks if the cipher is defined and is not the null (none) cipher.
Definition: crypto_backend.h:218
streq
#define streq(x, y)
Definition: options.h:707
M_NONFATAL
#define M_NONFATAL
Definition: error.h:90
context
Contains all state information for one tunnel.
Definition: openvpn.h:476
D_TLS_DEBUG_LOW
#define D_TLS_DEBUG_LOW
Definition: errlevel.h:77
p2p_mode_ncp
void p2p_mode_ncp(struct tls_multi *multi, struct tls_session *session)
Determines if there is common cipher of both peer by looking at the IV_CIPHER peer info.
Definition: ssl_ncp.c:470
BSTR
#define BSTR(buf)
Definition: buffer.h:129
alloc_buf_gc
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
buf_null_terminate
void buf_null_terminate(struct buffer *buf)
Definition: buffer.c:551
openvpn.h
IV_PROTO_TLS_KEY_EXPORT
#define IV_PROTO_TLS_KEY_EXPORT
Supports key derivation via TLS key material exporter [RFC5705].
Definition: ssl.h:86
mutate_ncp_cipher_list
char * mutate_ncp_cipher_list(const char *list, struct gc_arena *gc)
Check whether the ciphers in the supplied list are supported.
Definition: ssl_ncp.c:95
cipher_kt_name
const char * cipher_kt_name(const char *ciphername)
Retrieve a normalised string describing the cipher (e.g.
Definition: crypto_openssl.c:659
tls_multi
Security parameter state for a single VPN tunnel.
Definition: ssl_common.h:590
check_session_cipher
bool check_session_cipher(struct tls_session *session, struct options *options)
Checks if the cipher is allowed, otherwise returns false and reset the cipher to the config cipher.
Definition: ssl_ncp.c:511
ssl_util.h
context::c2
struct context_2 c2
Level 2 context.
Definition: openvpn.h:517
string_alloc
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:667
ASSERT
#define ASSERT(x)
Definition: error.h:195
p2p_ncp_set_options
static void p2p_ncp_set_options(struct tls_multi *multi, struct tls_session *session)
Definition: ssl_ncp.c:411
tls_peer_ncp_list
const char * tls_peer_ncp_list(const char *peer_info, struct gc_arena *gc)
Returns the support cipher list from the peer according to the IV_NCP and IV_CIPHER values in peer_in...
Definition: ssl_ncp.c:227
options::ncp_ciphers
const char * ncp_ciphers
Definition: options.h:559
OPT_P_NCP
#define OPT_P_NCP
Negotiable crypto parameters.
Definition: options.h:724
M_WARN
#define M_WARN
Definition: error.h:91
context::options
struct options options
Options loaded from command line or configuration file.
Definition: openvpn.h:478
tls_peer_supports_ncp
bool tls_peer_supports_ncp(const char *peer_info)
Returns whether the client supports NCP either by announcing IV_NCP>=2 or the IV_CIPHERS list.
Definition: ssl_ncp.c:77
options
Definition: options.h:236
options::gc
struct gc_arena gc
Definition: options.h:238
MAX_NCP_CIPHERS_LENGTH
#define MAX_NCP_CIPHERS_LENGTH
The maximum length of a ncp-cipher string that is accepted.
Definition: ssl_ncp.h:125
cipher_kt_mode_aead
bool cipher_kt_mode_aead(const char *ciphername)
Check if the supplied cipher is a supported AEAD mode cipher.
Definition: crypto_openssl.c:816
key_state_export_keying_material
bool key_state_export_keying_material(struct tls_session *session, const char *label, size_t label_size, void *ekm, size_t ekm_size)
Keying Material Exporters [RFC 5705] allows additional keying material to be derived from existing TL...
Definition: ssl_openssl.c:149
tls_multi::peer_info
char * peer_info
Definition: ssl_common.h:643
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
CO_USE_DYNAMIC_TLS_CRYPT
#define CO_USE_DYNAMIC_TLS_CRYPT
Bit-flag indicating that renegotiations are using tls-crypt with a TLS-EKM derived key.
Definition: crypto.h:278
D_TLS_ERRORS
#define D_TLS_ERRORS
Definition: errlevel.h:59
tls_session
Security parameter state of a single session within a VPN tunnel.
Definition: ssl_common.h:471
syshead.h
cipher_kt_mode_ofb_cfb
bool cipher_kt_mode_ofb_cfb(const char *ciphername)
Check if the supplied cipher is a supported OFB or CFB mode cipher.
Definition: crypto_openssl.c:804
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
IV_PROTO_DYN_TLS_CRYPT
#define IV_PROTO_DYN_TLS_CRYPT
Support to dynamic tls-crypt (renegotiation with TLS-EKM derived tls-crypt key)
Definition: ssl.h:107
buf_puts
bool buf_puts(struct buffer *buf, const char *str)
Definition: buffer.c:267
free_buf
void free_buf(struct buffer *buf)
Definition: buffer.c:183
common.h
tls_multi::use_peer_id
bool use_peer_id
Definition: ssl_common.h:667
ncp_get_best_cipher
char * ncp_get_best_cipher(const char *server_list, const char *peer_info, const char *remote_cipher, struct gc_arena *gc)
Iterates through the ciphers in server_list and return the first cipher that is also supported by the...
Definition: ssl_ncp.c:248
buf_len
static int buf_len(const struct buffer *buf)
Definition: buffer.h:253
IV_PROTO_NCP_P2P
#define IV_PROTO_NCP_P2P
Support doing NCP in P2P mode.
Definition: ssl.h:94
gc_malloc
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition: buffer.c:354
gc_free
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1038
check_pull_client_ncp
bool check_pull_client_ncp(struct context *c, const int found)
Checks whether the cipher negotiation is in an acceptable state and we continue to connect or should ...
Definition: ssl_ncp.c:315
extract_iv_proto
unsigned int extract_iv_proto(const char *peer_info)
Extracts the IV_PROTO variable and returns its value or 0 if it cannot be extracted.
Definition: ssl_util.c:62
cipher_kt_mode_cbc
bool cipher_kt_mode_cbc(const char *ciphername)
Check if the supplied cipher is a supported CBC mode cipher.
Definition: crypto_openssl.c:789
EXPORT_P2P_PEERID_LABEL
#define EXPORT_P2P_PEERID_LABEL
Definition: ssl_backend.h:391
append_cipher_to_ncp_list
void append_cipher_to_ncp_list(struct options *o, const char *ciphername)
Appends the cipher specified by the ciphernamer parameter to to the o->ncp_ciphers list.
Definition: ssl_ncp.c:195
strsep
char * strsep(char **stringp, const char *delim)
Definition: compat-strsep.c:36
config.h
D_PUSH_DEBUG
#define D_PUSH_DEBUG
Definition: errlevel.h:150
ssl_ncp.h
tls_multi::remote_ciphername
char * remote_ciphername
cipher specified in peer's config file
Definition: ssl_common.h:669
tls_multi::peer_id
uint32_t peer_id
Definition: ssl_common.h:666
buf_str
static char * buf_str(const struct buffer *buf)
Definition: buffer.h:297
session
Definition: keyingmaterialexporter.c:56
buf_forward_capacity
static int buf_forward_capacity(const struct buffer *buf)
Definition: buffer.h:546
extract_var_peer_info
char * extract_var_peer_info(const char *peer_info, const char *var, struct gc_arena *gc)
Extracts a variable from peer info, the returned string will be allocated using the supplied gc_arena...
Definition: ssl_util.c:32
CO_USE_TLS_KEY_MATERIAL_EXPORT
#define CO_USE_TLS_KEY_MATERIAL_EXPORT
Bit-flag indicating that data channel key derivation is done using TLS keying material export [RFC570...
Definition: crypto.h:262
alloc_buf
struct buffer alloc_buf(size_t size)
Definition: buffer.c:62
options::ciphername
const char * ciphername
Definition: options.h:556
get_p2p_ncp_cipher
const char * get_p2p_ncp_cipher(struct tls_session *session, const char *peer_info, struct gc_arena *gc)
Determines the best common cipher from both peers IV_CIPHER lists.
Definition: ssl_ncp.c:360
CO_USE_CC_EXIT_NOTIFY
#define CO_USE_CC_EXIT_NOTIFY
Bit-flag indicating that explicit exit notifies should be sent via the control channel instead of usi...
Definition: crypto.h:274
msg
#define msg(flags,...)
Definition: error.h:144
IV_PROTO_CC_EXIT_NOTIFY
#define IV_PROTO_CC_EXIT_NOTIFY
Support for explicit exit notify via control channel This also includes support for the protocol-flag...
Definition: ssl.h:101
buf_printf
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:240