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-2026 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2010-2026 Sentyron B.V. <openvpn@sentyron.com>
10 * Copyright (C) 2008-2026 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, see <https://www.gnu.org/licenses/>.
23 */
24
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 <string.h>
43
44#include "syshead.h"
45#include "win32.h"
46
47#include "error.h"
48#include "common.h"
49
50#include "ssl_ncp.h"
51#include "ssl_util.h"
52#include "openvpn.h"
53
58static int
59tls_peer_info_ncp_ver(const char *peer_info)
60{
61 const char *ncpstr = peer_info ? strstr(peer_info, "IV_NCP=") : NULL;
62 if (ncpstr)
63 {
64 int ncp = 0;
65 int r = sscanf(ncpstr, "IV_NCP=%d", &ncp);
66 if (r == 1)
67 {
68 return ncp;
69 }
70 }
71 return 0;
72}
73
78bool
79tls_peer_supports_ncp(const char *peer_info)
80{
81 if (!peer_info)
82 {
83 return false;
84 }
85 else if (tls_peer_info_ncp_ver(peer_info) >= 2 || strstr(peer_info, "IV_CIPHERS="))
86 {
87 return true;
88 }
89 else
90 {
91 return false;
92 }
93}
94
95char *
96mutate_ncp_cipher_list(const char *list, struct gc_arena *gc)
97{
98 bool error_found = false;
99
101
102 char *const tmp_ciphers = string_alloc(list, NULL);
103 char *lasts = NULL;
104 const char *token = strtok_r(tmp_ciphers, ":", &lasts);
105 while (token)
106 {
107 /*
108 * Going cipher_kt_name (and translate_cipher_name_from_openvpn/
109 * translate_cipher_name_to_openvpn) also normalises the cipher name,
110 * e.g. replacing AeS-128-gCm with AES-128-GCM
111 *
112 * ciphers that have ? in front of them are considered optional and
113 * OpenVPN will only warn if they are not found (and remove them from
114 * the list)
115 */
116 bool optional = false;
117 if (token[0] == '?')
118 {
119 token++;
120 optional = true;
121 }
122
123 const bool nonecipher = (strcmp(token, "none") == 0);
124 const char *optstr = optional ? "optional " : "";
125
126 if (nonecipher)
127 {
128 msg(M_WARN, "WARNING: cipher 'none' specified for --data-ciphers. "
129 "This allows negotiation of NO encryption and "
130 "tunnelled data WILL then be transmitted in clear text "
131 "over the network! "
132 "PLEASE DO RECONSIDER THIS SETTING!");
133 }
134 if (!nonecipher && !cipher_valid(token))
135 {
136 msg(M_WARN, "Unsupported %scipher in --data-ciphers: %s", optstr, token);
138 }
141 {
142 msg(M_WARN,
143 "Unsupported %scipher algorithm '%s'. It does not use "
144 "CFB, OFB, CBC, or a supported AEAD mode",
145 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 */
168 {
169 msg(M_WARN, "Length of --data-ciphers is over the "
170 "limit of 127 chars");
171 error_found = true;
172 }
173 else
174 {
176 }
177 }
178 token = strtok_r(NULL, ":", &lasts);
179 }
180
181
182 char *ret = NULL;
183 if (!error_found && buf_len(&new_list) > 0)
184 {
187 }
188 free(tmp_ciphers);
190
191 return ret;
192}
193
194
195void
196append_cipher_to_ncp_list(struct options *o, const char *ciphername)
197{
198 /* Append the --cipher to ncp_ciphers to allow it in NCP */
199 size_t newlen = strlen(o->ncp_ciphers) + 1 + strlen(ciphername) + 1;
200 char *ncp_ciphers = gc_malloc(newlen, false, &o->gc);
201
202 ASSERT(checked_snprintf(ncp_ciphers, newlen, "%s:%s", o->ncp_ciphers, ciphername));
203 o->ncp_ciphers = ncp_ciphers;
204}
205
206bool
207tls_item_in_cipher_list(const char *item, const char *list)
208{
209 char *tmp_ciphers = string_alloc(list, NULL);
211 char *lasts = NULL;
212
213 const char *token = strtok_r(tmp_ciphers, ":", &lasts);
214 while (token)
215 {
216 if (0 == strcmp(token, item))
217 {
218 break;
219 }
220 token = strtok_r(NULL, ":", &lasts);
221 }
222 free(tmp_ciphers_orig);
223
224 return token != NULL;
225}
226const char *
227tls_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
247char *
248ncp_get_best_cipher(const char *server_list, const char *peer_info, const char *remote_cipher,
249 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 || (peer_info && strstr(peer_info, "IV_CIPHERS=")))
265 {
266 remote_cipher = "";
267 }
268
269 char *tmp_ciphers = string_alloc(server_list, &gc_tmp);
270
271 const char *token;
272 while ((token = strsep(&tmp_ciphers, ":")))
273 {
274 if (tls_item_in_cipher_list(token, peer_ncp_list) || streq(token, remote_cipher))
275 {
276 break;
277 }
278 }
279
280 char *ret = NULL;
281 if (token != NULL)
282 {
283 ret = string_alloc(token, gc);
284 }
285
286 gc_free(&gc_tmp);
287 return ret;
288}
289
299static bool
300tls_poor_mans_ncp(struct options *o, const char *remote_ciphername)
301{
302 if (remote_ciphername && tls_item_in_cipher_list(remote_ciphername, o->ncp_ciphers))
303 {
304 o->ciphername = string_alloc(remote_ciphername, &o->gc);
305 msg(D_TLS_DEBUG_LOW, "Using peer cipher '%s'", o->ciphername);
306 return true;
307 }
308 return false;
309}
310
311bool
312check_pull_client_ncp(struct context *c, const uint64_t found)
313{
314 if (found & OPT_P_NCP)
315 {
316 msg(D_PUSH_DEBUG, "OPTIONS IMPORT: data channel crypto options modified");
317 return true;
318 }
319
320 /* If the server did not push a --cipher, we will switch to the
321 * remote cipher if it is in our ncp-ciphers list */
323 {
324 return true;
325 }
326
327 /* We could not figure out the peer's cipher but we have fallback
328 * enabled */
330 {
331 return true;
332 }
333
334 /* We failed negotiation, give appropriate error message */
336 {
338 "OPTIONS ERROR: failed to negotiate "
339 "cipher with server. Add the server's "
340 "cipher ('%s') to --data-ciphers (currently '%s'), e.g."
341 "--data-ciphers %s:%s if you want to connect to this server.",
344 return false;
345 }
346 else
347 {
348 msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to negotiate "
349 "cipher with server. Configure "
350 "--data-ciphers-fallback if you want to connect "
351 "to this server.");
352 return false;
353 }
354}
355
356const char *
357get_p2p_ncp_cipher(struct tls_session *session, const char *peer_info, struct gc_arena *gc)
358{
359 /* we use a local gc arena to keep the temporary strings needed by strsep */
360 struct gc_arena gc_local = gc_new();
361 const char *peer_ciphers = extract_var_peer_info(peer_info, "IV_CIPHERS=", &gc_local);
362
363 if (!peer_ciphers)
364 {
365 gc_free(&gc_local);
366 return NULL;
367 }
368
369 const char *server_ciphers;
370 const char *client_ciphers;
371
372 if (session->opt->server)
373 {
374 server_ciphers = session->opt->config_ncp_ciphers;
375 client_ciphers = peer_ciphers;
376 }
377 else
378 {
379 client_ciphers = session->opt->config_ncp_ciphers;
380 server_ciphers = peer_ciphers;
381 }
382
383 /* Find the first common cipher from TLS server and TLS client. We
384 * use the preference of the server here to make it deterministic */
385 char *tmp_ciphers = string_alloc(server_ciphers, &gc_local);
386
387 const char *token;
388 while ((token = strsep(&tmp_ciphers, ":")))
389 {
390 if (tls_item_in_cipher_list(token, client_ciphers))
391 {
392 break;
393 }
394 }
395
396 const char *ret = NULL;
397 if (token != NULL)
398 {
399 ret = string_alloc(token, gc);
400 }
401 gc_free(&gc_local);
402
403 return ret;
404}
405
406static void
407p2p_ncp_set_options(struct tls_multi *multi, struct tls_session *session, const char *common_cipher)
408{
409 /* will return 0 if peer_info is null */
410 const unsigned int iv_proto_peer = extract_iv_proto(multi->peer_info);
411
412 /* The other peer does not support P2P NCP */
413 if (!(iv_proto_peer & IV_PROTO_NCP_P2P))
414 {
415 return;
416 }
417
418 if (iv_proto_peer & IV_PROTO_DATA_V2)
419 {
420 multi->use_peer_id = true;
421 multi->peer_id = 0x76706e; /* 'v' 'p' 'n' */
422 }
423
424 if (iv_proto_peer & IV_PROTO_CC_EXIT_NOTIFY)
425 {
426 session->opt->crypto_flags |= CO_USE_CC_EXIT_NOTIFY;
427 }
428
429 if (session->opt->data_epoch_supported && (iv_proto_peer & IV_PROTO_DATA_EPOCH) && common_cipher
430 && cipher_kt_mode_aead(common_cipher))
431 {
432 session->opt->crypto_flags |= CO_EPOCH_DATA_KEY_FORMAT;
433 }
434 else
435 {
436 /* The peer might have changed its ciphers options during reconnect,
437 * ensure we clear the flag if we previously had it enabled */
438 session->opt->crypto_flags &= ~CO_EPOCH_DATA_KEY_FORMAT;
439 }
440
441 if (iv_proto_peer & IV_PROTO_TLS_KEY_EXPORT)
442 {
443 session->opt->crypto_flags |= CO_USE_TLS_KEY_MATERIAL_EXPORT;
444
445 if (multi->use_peer_id)
446 {
447 /* Using a non hardcoded peer-id makes a tiny bit harder to
448 * fingerprint packets and also gives each connection a unique
449 * peer-id that can be useful for NAT tracking etc. */
450
451 uint8_t peerid[3];
453 strlen(EXPORT_P2P_PEERID_LABEL), &peerid, 3))
454 {
455 /* Non DCO setup might still work but also this should never
456 * happen or very likely the TLS encryption key exporter will
457 * also fail */
458 msg(M_NONFATAL, "TLS key export for P2P peer id failed. "
459 "Continuing anyway, expect problems");
460 }
461 else
462 {
463 multi->peer_id = (peerid[0] << 16) + (peerid[1] << 8) + peerid[2];
464 }
465 }
466 }
467 if (iv_proto_peer & IV_PROTO_DYN_TLS_CRYPT)
468 {
469 session->opt->crypto_flags |= CO_USE_DYNAMIC_TLS_CRYPT;
470 }
471}
472
473void
475{
476 struct gc_arena gc = gc_new();
477
478 /* Query the common cipher here to log it as part of our message.
479 * We postpone switching the cipher to do_up */
480 const char *common_cipher = get_p2p_ncp_cipher(session, multi->peer_info, &gc);
481
482 /* Set the common options */
483 p2p_ncp_set_options(multi, session, common_cipher);
484
485 if (!common_cipher)
486 {
487 struct buffer out = alloc_buf_gc(128, &gc);
488 /* at this point we do not really know if our fallback is
489 * not enabled or if we use 'none' cipher as fallback, so
490 * keep this ambiguity here and print fallback-cipher: none
491 */
492
493 const char *fallback_name = "none";
494 const char *ciphername = session->opt->key_type.cipher;
495
496 if (cipher_defined(ciphername))
497 {
498 fallback_name = cipher_kt_name(ciphername);
499 }
500
501 buf_printf(&out, "(not negotiated, fallback-cipher: %s)", fallback_name);
502 common_cipher = BSTR(&out);
503 }
504
506 "P2P mode NCP negotiation result: "
507 "TLS_export=%d, DATA_v2=%d, peer-id %d, epoch=%d, cipher=%s",
508 (bool)(session->opt->crypto_flags & CO_USE_TLS_KEY_MATERIAL_EXPORT), multi->use_peer_id,
509 multi->peer_id, (bool)(session->opt->crypto_flags & CO_EPOCH_DATA_KEY_FORMAT),
511
512 gc_free(&gc);
513}
514
515
516bool
518{
520 options->enable_ncp_fallback && streq(options->ciphername, session->opt->config_ciphername);
521
522 if (!session->opt->server && !cipher_allowed_as_fallback
524 {
525 struct gc_arena gc = gc_new();
526 msg(D_TLS_ERRORS, "Error: negotiated cipher not allowed - %s not in %s%s",
528 /* undo cipher push, abort connection setup */
529 options->ciphername = session->opt->config_ciphername;
530 gc_free(&gc);
531 return false;
532 }
533 else
534 {
535 return true;
536 }
537}
538
545static void
546replace_default_in_ncp_ciphers_option(struct options *o, const char *replace)
547{
548 const char *search = "DEFAULT";
549 const size_t ncp_ciphers_len = strlen(o->ncp_ciphers) + strlen(replace) - strlen(search) + 1;
550
551 uint8_t *ncp_ciphers = gc_malloc(ncp_ciphers_len, true, &o->gc);
552
553 struct buffer ncp_ciphers_buf;
555 buf_set_write(&ncp_ciphers_buf, ncp_ciphers, (int)ncp_ciphers_len);
556
557 const char *def = strstr(o->ncp_ciphers, search);
558
559 /* Copy everything before the DEFAULT string */
560 buf_write(&ncp_ciphers_buf, o->ncp_ciphers, def - o->ncp_ciphers);
561
562 /* copy the default string. */
564
565 /* copy the rest of the ncp cipher string */
566 const char *after_default = def + strlen(search);
568
569 o->ncp_ciphers = (char *)ncp_ciphers;
570}
571
577void
579{
581 o->ncp_ciphers && tls_item_in_cipher_list("DEFAULT", o->ncp_ciphers);
582
583 /* preserve the values that the user put into the configuration */
584 o->ncp_ciphers_conf = o->ncp_ciphers;
585
586 /* check if crypto library supports chacha */
587 bool can_do_chacha = cipher_valid("CHACHA20-POLY1305");
588
590 {
591 /* also make sure that dco supports chacha */
593 }
594
595 const char *default_ciphers = "AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305";
596
597 if (!can_do_chacha)
598 {
599 default_ciphers = "AES-256-GCM:AES-128-GCM";
600 }
601
602 /* want to rather print DEFAULT instead of a manually set default list */
603 if (!o->ncp_ciphers_conf || !strcmp(default_ciphers, o->ncp_ciphers_conf))
604 {
605 o->ncp_ciphers = default_ciphers;
606 o->ncp_ciphers_conf = "DEFAULT";
607 }
608 else if (!default_in_cipher_list)
609 {
610 /* custom cipher list without DEFAULT string in it,
611 * nothing to replace/mutate */
612 return;
613 }
614 else
615 {
617 }
618}
619
620const char *
622{
623 if (!strcmp(o->ncp_ciphers, o->ncp_ciphers_conf))
624 {
625 /* expanded ciphers and user set ciphers are identical, no need to
626 * add an expanded version */
627 return "";
628 }
629
630 /* two extra brackets, one space, NUL byte */
631 struct buffer expanded_ciphers_buf = alloc_buf_gc(strlen(o->ncp_ciphers) + 4, gc);
632
633 buf_printf(&expanded_ciphers_buf, " (%s)", o->ncp_ciphers);
634 return BSTR(&expanded_ciphers_buf);
635}
void free_buf(struct buffer *buf)
Definition buffer.c:189
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:246
bool buf_puts(struct buffer *buf, const char *str)
Definition buffer.c:273
void buf_null_terminate(struct buffer *buf)
Definition buffer.c:537
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:341
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:63
bool checked_snprintf(char *str, size_t size, const char *format,...)
Like snprintf() but returns an boolean.
Definition buffer.c:1143
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:653
#define BSTR(buf)
Definition buffer.h:130
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Definition buffer.h:333
static int buf_len(const struct buffer *buf)
Definition buffer.h:255
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:662
static void gc_free(struct gc_arena *a)
Definition buffer.h:1081
static char * buf_str(const struct buffer *buf)
Definition buffer.h:299
static struct gc_arena gc_new(void)
Definition buffer.h:1073
char * strsep(char **stringp, const char *delim)
char * strtok_r(char *s, const char *delim, char **last)
#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:359
#define CO_USE_DYNAMIC_TLS_CRYPT
Bit-flag indicating that renegotiations are using tls-crypt with a TLS-EKM derived key.
Definition crypto.h:375
#define CO_EPOCH_DATA_KEY_FORMAT
Bit-flag indicating the epoch the data format.
Definition crypto.h:379
#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:371
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:381
#define D_TLS_DEBUG_LOW
Definition errlevel.h:76
#define D_PUSH_DEBUG
Definition errlevel.h:149
#define D_TLS_ERRORS
Definition errlevel.h:58
#define M_NONFATAL
Definition error.h:91
#define msg(flags,...)
Definition error.h:152
#define ASSERT(x)
Definition error.h:219
#define M_WARN
Definition error.h:92
#define OPT_P_NCP
Negotiable crypto parameters.
Definition options.h:740
#define streq(x, y)
Definition options.h:723
static bool dco_enabled(const struct options *o)
Returns whether the current configuration has dco enabled.
Definition options.h:989
#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...
bool check_pull_client_ncp(struct context *c, const uint64_t found)
Checks whether the cipher negotiation is in an acceptable state and we continue to connect or should ...
Definition ssl_ncp.c:312
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
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
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:578
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:621
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:517
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:474
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:59
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
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:196
static void p2p_ncp_set_options(struct tls_multi *multi, struct tls_session *session, const char *common_cipher)
Definition ssl_ncp.c:407
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:79
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:300
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:96
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:357
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:546
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:123
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:31
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:60
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:471
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:472
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:579
const char * ncp_ciphers
Definition options.h:580
const char * ciphername
Definition options.h:575
bool enable_ncp_fallback
If defined fall back to ciphername if NCP fails.
Definition options.h:576
struct gc_arena gc
Definition options.h:258
Security parameter state for a single VPN tunnel.
Definition ssl_common.h:611
char * peer_info
A multi-line string of general-purpose info received from peer over control channel.
Definition ssl_common.h:672
char * remote_ciphername
cipher specified in peer's config file
Definition ssl_common.h:702
uint32_t peer_id
Definition ssl_common.h:699
bool use_peer_id
Definition ssl_common.h:700
Security parameter state of a single session within a VPN tunnel.
Definition ssl_common.h:489
struct gc_arena gc
Definition test_ssl.c:133