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
32/*
33 * The routines in this file deal with dynamically negotiating
34 * the data channel HMAC and cipher keys through a TLS session.
35 *
36 * Both the TLS session and the data channel are multiplexed
37 * over the same TCP/UDP port.
38 */
39#ifdef HAVE_CONFIG_H
40#include "config.h"
41#endif
42
43#include <string.h>
44
45#include "syshead.h"
46#include "win32.h"
47
48#include "error.h"
49#include "common.h"
50
51#include "ssl_ncp.h"
52#include "ssl_util.h"
53#include "openvpn.h"
54
59static int
60tls_peer_info_ncp_ver(const char *peer_info)
61{
62 const char *ncpstr = peer_info ? strstr(peer_info, "IV_NCP=") : NULL;
63 if (ncpstr)
64 {
65 int ncp = 0;
66 int r = sscanf(ncpstr, "IV_NCP=%d", &ncp);
67 if (r == 1)
68 {
69 return ncp;
70 }
71 }
72 return 0;
73}
74
79bool
80tls_peer_supports_ncp(const char *peer_info)
81{
82 if (!peer_info)
83 {
84 return false;
85 }
86 else if (tls_peer_info_ncp_ver(peer_info) >= 2
87 || strstr(peer_info, "IV_CIPHERS="))
88 {
89 return true;
90 }
91 else
92 {
93 return false;
94 }
95}
96
97char *
98mutate_ncp_cipher_list(const char *list, struct gc_arena *gc)
99{
100 bool error_found = false;
101
103
104 char *const tmp_ciphers = string_alloc(list, NULL);
105 const char *token = strtok(tmp_ciphers, ":");
106 while (token)
107 {
108 /*
109 * Going cipher_kt_name (and translate_cipher_name_from_openvpn/
110 * translate_cipher_name_to_openvpn) also normalises the cipher name,
111 * e.g. replacing AeS-128-gCm with AES-128-GCM
112 *
113 * ciphers that have ? in front of them are considered optional and
114 * OpenVPN will only warn if they are not found (and remove them from
115 * the list)
116 */
117 bool optional = false;
118 if (token[0] == '?')
119 {
120 token++;
121 optional = true;
122 }
123
124 const bool nonecipher = (strcmp(token, "none") == 0);
125 const char *optstr = optional ? "optional " : "";
126
127 if (nonecipher)
128 {
129 msg(M_WARN, "WARNING: cipher 'none' specified for --data-ciphers. "
130 "This allows negotiation of NO encryption and "
131 "tunnelled data WILL then be transmitted in clear text "
132 "over the network! "
133 "PLEASE DO RECONSIDER THIS SETTING!");
134 }
135 if (!nonecipher && !cipher_valid(token))
136 {
137 msg(M_WARN, "Unsupported %scipher in --data-ciphers: %s", optstr, token);
139 }
143 {
144 msg(M_WARN, "Unsupported %scipher algorithm '%s'. It does not use "
145 "CFB, OFB, CBC, or a supported AEAD mode", optstr, token);
147 }
148 else
149 {
151 if (nonecipher)
152 {
153 /* NULL resolves to [null-cipher] but we need none for
154 * data-ciphers */
155 ovpn_cipher_name = "none";
156 }
157
158 if (buf_len(&new_list)> 0)
159 {
160 /* The next if condition ensure there is always space for
161 * a :
162 */
163 buf_puts(&new_list, ":");
164 }
165
166 /* Ensure buffer has capacity for cipher name + : + \0 */
169 {
170 msg(M_WARN, "Length of --data-ciphers is over the "
171 "limit of 127 chars");
172 error_found = true;
173 }
174 else
175 {
177 }
178 }
179 token = strtok(NULL, ":");
180 }
181
182
183
184 char *ret = NULL;
185 if (!error_found && buf_len(&new_list) > 0)
186 {
189 }
190 free(tmp_ciphers);
192
193 return ret;
194}
195
196
197void
198append_cipher_to_ncp_list(struct options *o, const char *ciphername)
199{
200 /* Append the --cipher to ncp_ciphers to allow it in NCP */
201 size_t newlen = strlen(o->ncp_ciphers) + 1 + strlen(ciphername) + 1;
202 char *ncp_ciphers = gc_malloc(newlen, false, &o->gc);
203
204 ASSERT(snprintf(ncp_ciphers, newlen, "%s:%s", o->ncp_ciphers,
205 ciphername));
206 o->ncp_ciphers = ncp_ciphers;
207}
208
209bool
210tls_item_in_cipher_list(const char *item, const char *list)
211{
212 char *tmp_ciphers = string_alloc(list, NULL);
214
215 const char *token = strtok(tmp_ciphers, ":");
216 while (token)
217 {
218 if (0 == strcmp(token, item))
219 {
220 break;
221 }
222 token = strtok(NULL, ":");
223 }
224 free(tmp_ciphers_orig);
225
226 return token != NULL;
227}
228const char *
229tls_peer_ncp_list(const char *peer_info, struct gc_arena *gc)
230{
231 /* Check if the peer sends the IV_CIPHERS list */
232 const char *iv_ciphers = extract_var_peer_info(peer_info, "IV_CIPHERS=", gc);
233 if (iv_ciphers)
234 {
235 return iv_ciphers;
236 }
237 else if (tls_peer_info_ncp_ver(peer_info)>=2)
238 {
239 /* If the peer announces IV_NCP=2 then it supports the AES GCM
240 * ciphers */
241 return "AES-256-GCM:AES-128-GCM";
242 }
243 else
244 {
245 return "";
246 }
247}
248
249char *
250ncp_get_best_cipher(const char *server_list, const char *peer_info,
251 const char *remote_cipher, struct gc_arena *gc)
252{
253 /*
254 * The gc of the parameter is tied to the VPN session, create a
255 * short lived gc arena that is only valid for the duration of
256 * this function
257 */
258
259 struct gc_arena gc_tmp = gc_new();
260
261 const char *peer_ncp_list = tls_peer_ncp_list(peer_info, &gc_tmp);
262
263 /* non-NCP clients without OCC? "assume nothing" */
264 /* For client doing the newer version of NCP (that send IV_CIPHERS)
265 * we cannot assume that they will accept remote_cipher */
266 if (remote_cipher == NULL
267 || (peer_info && strstr(peer_info, "IV_CIPHERS=")))
268 {
269 remote_cipher = "";
270 }
271
272 char *tmp_ciphers = string_alloc(server_list, &gc_tmp);
273
274 const char *token;
275 while ((token = strsep(&tmp_ciphers, ":")))
276 {
277 if (tls_item_in_cipher_list(token, peer_ncp_list)
278 || streq(token, remote_cipher))
279 {
280 break;
281 }
282 }
283
284 char *ret = NULL;
285 if (token != NULL)
286 {
287 ret = string_alloc(token, gc);
288 }
289
290 gc_free(&gc_tmp);
291 return ret;
292}
293
303static bool
304tls_poor_mans_ncp(struct options *o, const char *remote_ciphername)
305{
306 if (remote_ciphername
307 && tls_item_in_cipher_list(remote_ciphername, o->ncp_ciphers))
308 {
309 o->ciphername = string_alloc(remote_ciphername, &o->gc);
310 msg(D_TLS_DEBUG_LOW, "Using peer cipher '%s'", o->ciphername);
311 return true;
312 }
313 return false;
314}
315
316bool
317check_pull_client_ncp(struct context *c, const int found)
318{
319 if (found & OPT_P_NCP)
320 {
321 msg(D_PUSH_DEBUG, "OPTIONS IMPORT: data channel crypto options modified");
322 return true;
323 }
324
325 /* If the server did not push a --cipher, we will switch to the
326 * remote cipher if it is in our ncp-ciphers list */
328 {
329 return true;
330 }
331
332 /* We could not figure out the peer's cipher but we have fallback
333 * enabled */
335 {
336 return true;
337 }
338
339 /* We failed negotiation, give appropriate error message */
341 {
342 msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to negotiate "
343 "cipher with server. Add the server's "
344 "cipher ('%s') to --data-ciphers (currently '%s'), e.g."
345 "--data-ciphers %s:%s if you want to connect to this server.",
349 return false;
350
351 }
352 else
353 {
354 msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to negotiate "
355 "cipher with server. Configure "
356 "--data-ciphers-fallback if you want to connect "
357 "to this server.");
358 return false;
359 }
360}
361
362const char *
363get_p2p_ncp_cipher(struct tls_session *session, const char *peer_info,
364 struct gc_arena *gc)
365{
366 /* we use a local gc arena to keep the temporary strings needed by strsep */
367 struct gc_arena gc_local = gc_new();
368 const char *peer_ciphers = extract_var_peer_info(peer_info, "IV_CIPHERS=", &gc_local);
369
370 if (!peer_ciphers)
371 {
372 gc_free(&gc_local);
373 return NULL;
374 }
375
376 const char *server_ciphers;
377 const char *client_ciphers;
378
379 if (session->opt->server)
380 {
381 server_ciphers = session->opt->config_ncp_ciphers;
382 client_ciphers = peer_ciphers;
383 }
384 else
385 {
386 client_ciphers = session->opt->config_ncp_ciphers;
387 server_ciphers = peer_ciphers;
388 }
389
390 /* Find the first common cipher from TLS server and TLS client. We
391 * use the preference of the server here to make it deterministic */
392 char *tmp_ciphers = string_alloc(server_ciphers, &gc_local);
393
394 const char *token;
395 while ((token = strsep(&tmp_ciphers, ":")))
396 {
397 if (tls_item_in_cipher_list(token, client_ciphers))
398 {
399 break;
400 }
401 }
402
403 const char *ret = NULL;
404 if (token != NULL)
405 {
406 ret = string_alloc(token, gc);
407 }
408 gc_free(&gc_local);
409
410 return ret;
411}
412
413static void
415 const char *common_cipher)
416{
417 /* will return 0 if peer_info is null */
418 const unsigned int iv_proto_peer = extract_iv_proto(multi->peer_info);
419
420 /* The other peer does not support P2P NCP */
421 if (!(iv_proto_peer & IV_PROTO_NCP_P2P))
422 {
423 return;
424 }
425
426 if (iv_proto_peer & IV_PROTO_DATA_V2)
427 {
428 multi->use_peer_id = true;
429 multi->peer_id = 0x76706e; /* 'v' 'p' 'n' */
430 }
431
432 if (iv_proto_peer & IV_PROTO_CC_EXIT_NOTIFY)
433 {
434 session->opt->crypto_flags |= CO_USE_CC_EXIT_NOTIFY;
435 }
436
437 if (session->opt->data_epoch_supported && (iv_proto_peer & IV_PROTO_DATA_EPOCH)
438 && common_cipher && cipher_kt_mode_aead(common_cipher))
439 {
440 session->opt->crypto_flags |= CO_EPOCH_DATA_KEY_FORMAT;
441 }
442 else
443 {
444 /* The peer might have changed its ciphers options during reconnect,
445 * ensure we clear the flag if we previously had it enabled */
446 session->opt->crypto_flags &= ~CO_EPOCH_DATA_KEY_FORMAT;
447 }
448
449#if defined(HAVE_EXPORT_KEYING_MATERIAL)
450 if (iv_proto_peer & IV_PROTO_TLS_KEY_EXPORT)
451 {
452 session->opt->crypto_flags |= CO_USE_TLS_KEY_MATERIAL_EXPORT;
453
454 if (multi->use_peer_id)
455 {
456 /* Using a non hardcoded peer-id makes a tiny bit harder to
457 * fingerprint packets and also gives each connection a unique
458 * peer-id that can be useful for NAT tracking etc. */
459
460 uint8_t peerid[3];
463 &peerid, 3))
464 {
465 /* Non DCO setup might still work but also this should never
466 * happen or very likely the TLS encryption key exporter will
467 * also fail */
468 msg(M_NONFATAL, "TLS key export for P2P peer id failed. "
469 "Continuing anyway, expect problems");
470 }
471 else
472 {
473 multi->peer_id = (peerid[0] << 16) + (peerid[1] << 8) + peerid[2];
474 }
475
476 }
477 }
478 if (iv_proto_peer & IV_PROTO_DYN_TLS_CRYPT)
479 {
480 session->opt->crypto_flags |= CO_USE_DYNAMIC_TLS_CRYPT;
481 }
482#endif /* if defined(HAVE_EXPORT_KEYING_MATERIAL) */
483}
484
485void
487{
488 struct gc_arena gc = gc_new();
489
490 /* Query the common cipher here to log it as part of our message.
491 * We postpone switching the cipher to do_up */
492 const char *common_cipher = get_p2p_ncp_cipher(session, multi->peer_info, &gc);
493
494 /* Set the common options */
495 p2p_ncp_set_options(multi, session, common_cipher);
496
497 if (!common_cipher)
498 {
499 struct buffer out = alloc_buf_gc(128, &gc);
500 /* at this point we do not really know if our fallback is
501 * not enabled or if we use 'none' cipher as fallback, so
502 * keep this ambiguity here and print fallback-cipher: none
503 */
504
505 const char *fallback_name = "none";
506 const char *ciphername = session->opt->key_type.cipher;
507
508 if (cipher_defined(ciphername))
509 {
510 fallback_name = cipher_kt_name(ciphername);
511 }
512
513 buf_printf(&out, "(not negotiated, fallback-cipher: %s)", fallback_name);
514 common_cipher = BSTR(&out);
515 }
516
517 msg(D_TLS_DEBUG_LOW, "P2P mode NCP negotiation result: "
518 "TLS_export=%d, DATA_v2=%d, peer-id %d, epoch=%d, cipher=%s",
519 (bool)(session->opt->crypto_flags & CO_USE_TLS_KEY_MATERIAL_EXPORT),
520 multi->use_peer_id,
521 multi->peer_id,
522 (bool)(session->opt->crypto_flags & CO_EPOCH_DATA_KEY_FORMAT),
524
525 gc_free(&gc);
526}
527
528
529bool
531{
533 && streq(options->ciphername, session->opt->config_ciphername);
534
535 if (!session->opt->server && !cipher_allowed_as_fallback
537 {
538 struct gc_arena gc = gc_new();
539 msg(D_TLS_ERRORS, "Error: negotiated cipher not allowed - %s not in %s%s",
542 /* undo cipher push, abort connection setup */
543 options->ciphername = session->opt->config_ciphername;
544 gc_free(&gc);
545 return false;
546 }
547 else
548 {
549 return true;
550 }
551}
552
559static void
560replace_default_in_ncp_ciphers_option(struct options *o, const char *replace)
561{
562 const char *search = "DEFAULT";
563 const int ncp_ciphers_len = strlen(o->ncp_ciphers) + strlen(replace) - strlen(search) + 1;
564
565 uint8_t *ncp_ciphers = gc_malloc(ncp_ciphers_len, true, &o->gc);
566
567 struct buffer ncp_ciphers_buf;
569
570 const char *def = strstr(o->ncp_ciphers, search);
571
572 /* Copy everything before the DEFAULT string */
573 buf_write(&ncp_ciphers_buf, o->ncp_ciphers, def - o->ncp_ciphers);
574
575 /* copy the default string. */
577
578 /* copy the rest of the ncp cipher string */
579 const char *after_default = def + strlen(search);
581
582 o->ncp_ciphers = (char *) ncp_ciphers;
583}
584
590void
592{
593 bool default_in_cipher_list = o->ncp_ciphers
594 && tls_item_in_cipher_list("DEFAULT", o->ncp_ciphers);
595
596 /* preserve the values that the user put into the configuration */
597 o->ncp_ciphers_conf = o->ncp_ciphers;
598
599 /* check if crypto library supports chacha */
600 bool can_do_chacha = cipher_valid("CHACHA20-POLY1305");
601
603 {
604 /* also make sure that dco supports chacha */
606 }
607
608 const char *default_ciphers = "AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305";
609
610 if (!can_do_chacha)
611 {
612 default_ciphers = "AES-256-GCM:AES-128-GCM";
613 }
614
615 /* want to rather print DEFAULT instead of a manually set default list */
616 if (!o->ncp_ciphers_conf || !strcmp(default_ciphers, o->ncp_ciphers_conf))
617 {
618 o->ncp_ciphers = default_ciphers;
619 o->ncp_ciphers_conf = "DEFAULT";
620 }
621 else if (!default_in_cipher_list)
622 {
623 /* custom cipher list without DEFAULT string in it,
624 * nothing to replace/mutate */
625 return;
626 }
627 else
628 {
630 }
631}
632
633const char *
635{
636 if (!strcmp(o->ncp_ciphers, o->ncp_ciphers_conf))
637 {
638 /* expanded ciphers and user set ciphers are identical, no need to
639 * add an expanded version */
640 return "";
641 }
642
643 /* two extra brackets, one space, NUL byte */
644 struct buffer expanded_ciphers_buf = alloc_buf_gc(strlen(o->ncp_ciphers) + 4, gc);
645
646 buf_printf(&expanded_ciphers_buf, " (%s)", o->ncp_ciphers);
647 return BSTR(&expanded_ciphers_buf);
648}
void free_buf(struct buffer *buf)
Definition buffer.c:183
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:240
bool buf_puts(struct buffer *buf, const char *str)
Definition buffer.c:267
void buf_null_terminate(struct buffer *buf)
Definition buffer.c:533
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:336
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:88
struct buffer alloc_buf(size_t size)
Definition buffer.c:62
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:649
#define BSTR(buf)
Definition buffer.h:129
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Definition buffer.h:331
static int buf_len(const struct buffer *buf)
Definition buffer.h:253
static int buf_forward_capacity(const struct buffer *buf)
Definition buffer.h:541
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:668
static void gc_free(struct gc_arena *a)
Definition buffer.h:1033
static char * buf_str(const struct buffer *buf)
Definition buffer.h:297
static struct gc_arena gc_new(void)
Definition buffer.h:1025
char * strsep(char **stringp, const char *delim)
#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:356
#define CO_USE_DYNAMIC_TLS_CRYPT
Bit-flag indicating that renegotiations are using tls-crypt with a TLS-EKM derived key.
Definition crypto.h:372
#define CO_EPOCH_DATA_KEY_FORMAT
Bit-flag indicating the epoch the data format.
Definition crypto.h:376
#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:368
bool cipher_kt_mode_cbc(const char *ciphername)
Check if the supplied cipher is a supported CBC mode cipher.
static bool cipher_defined(const char *ciphername)
Checks if the cipher is defined and is not the null (none) cipher.
bool cipher_kt_mode_aead(const char *ciphername)
Check if the supplied cipher is a supported AEAD mode cipher.
bool cipher_kt_mode_ofb_cfb(const char *ciphername)
Check if the supplied cipher is a supported OFB or CFB mode cipher.
static bool cipher_valid(const char *ciphername)
Returns if the cipher is valid, based on the given cipher name.
const char * cipher_kt_name(const char *ciphername)
Retrieve a normalised string describing the cipher (e.g.
static const char * dco_get_supported_ciphers(void)
Definition dco.h:392
#define D_TLS_DEBUG_LOW
Definition errlevel.h:77
#define D_PUSH_DEBUG
Definition errlevel.h:150
#define D_TLS_ERRORS
Definition errlevel.h:59
#define M_NONFATAL
Definition error.h:90
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
#define M_WARN
Definition error.h:91
#define OPT_P_NCP
Negotiable crypto parameters.
Definition options.h:742
#define streq(x, y)
Definition options.h:725
static bool dco_enabled(const struct options *o)
Returns whether the current configuration has dco enabled.
Definition options.h:929
#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:102
#define IV_PROTO_DATA_EPOCH
Support the extended packet id and epoch format for data channel packets.
Definition ssl.h:111
#define IV_PROTO_DATA_V2
Support P_DATA_V2.
Definition ssl.h:80
#define IV_PROTO_TLS_KEY_EXPORT
Supports key derivation via TLS key material exporter [RFC5705].
Definition ssl.h:87
#define IV_PROTO_DYN_TLS_CRYPT
Support to dynamic tls-crypt (renegotiation with TLS-EKM derived tls-crypt key)
Definition ssl.h:108
#define IV_PROTO_NCP_P2P
Support doing NCP in P2P mode.
Definition ssl.h:95
#define EXPORT_P2P_PEERID_LABEL
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...
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:250
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:229
void options_postprocess_setdefault_ncpciphers(struct options *o)
Checks for availibility of Chacha20-Poly1305 and sets the ncp_cipher to either AES-256-GCM:AES-128-GC...
Definition ssl_ncp.c:591
const char * ncp_expanded_ciphers(struct options *o, struct gc_arena *gc)
returns the o->ncp_ciphers in brackets, e.g.
Definition ssl_ncp.c:634
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:530
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:486
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:60
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:317
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:210
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:198
static void p2p_ncp_set_options(struct tls_multi *multi, struct tls_session *session, const char *common_cipher)
Definition ssl_ncp.c:414
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:80
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:304
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:98
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:363
static void replace_default_in_ncp_ciphers_option(struct options *o, const char *replace)
Replaces the string DEFAULT with the string replace.
Definition ssl_ncp.c:560
Control Channel SSL/Data dynamic negotiation Module This file is split from ssl.h to be able to unit ...
#define MAX_NCP_CIPHERS_LENGTH
The maximum length of a ncp-cipher string that is accepted.
Definition ssl_ncp.h:126
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
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
SSL utility functions.
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
struct tls_multi * tls_multi
TLS state structure for this VPN tunnel.
Definition openvpn.h:323
Contains all state information for one tunnel.
Definition openvpn.h:474
struct context_2 c2
Level 2 context.
Definition openvpn.h:514
struct options options
Options loaded from command line or configuration file.
Definition openvpn.h:475
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
const char * ncp_ciphers_conf
The original ncp_ciphers specified by the user in the configuration.
Definition options.h:576
const char * ncp_ciphers
Definition options.h:577
const char * ciphername
Definition options.h:572
bool enable_ncp_fallback
If defined fall back to ciphername if NCP fails.
Definition options.h:573
struct gc_arena gc
Definition options.h:251
Security parameter state for a single VPN tunnel.
Definition ssl_common.h:597
char * peer_info
Definition ssl_common.h:649
char * remote_ciphername
cipher specified in peer's config file
Definition ssl_common.h:675
uint32_t peer_id
Definition ssl_common.h:672
bool use_peer_id
Definition ssl_common.h:673
Security parameter state of a single session within a VPN tunnel.
Definition ssl_common.h:480
struct gc_arena gc
Definition test_ssl.c:155