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-2025 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2010-2021 Fox Crypto B.V. <openvpn@foxcrypto.com>
10 * Copyright (C) 2008-2025 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 const char *token = strtok(tmp_ciphers, ":");
104 while (token)
105 {
106 /*
107 * Going cipher_kt_name (and translate_cipher_name_from_openvpn/
108 * translate_cipher_name_to_openvpn) also normalises the cipher name,
109 * e.g. replacing AeS-128-gCm with AES-128-GCM
110 *
111 * ciphers that have ? in front of them are considered optional and
112 * OpenVPN will only warn if they are not found (and remove them from
113 * the list)
114 */
115 bool optional = false;
116 if (token[0] == '?')
117 {
118 token++;
119 optional = true;
120 }
121
122 const bool nonecipher = (strcmp(token, "none") == 0);
123 const char *optstr = optional ? "optional " : "";
124
125 if (nonecipher)
126 {
127 msg(M_WARN, "WARNING: cipher 'none' specified for --data-ciphers. "
128 "This allows negotiation of NO encryption and "
129 "tunnelled data WILL then be transmitted in clear text "
130 "over the network! "
131 "PLEASE DO RECONSIDER THIS SETTING!");
132 }
133 if (!nonecipher && !cipher_valid(token))
134 {
135 msg(M_WARN, "Unsupported %scipher in --data-ciphers: %s", optstr, token);
137 }
140 {
141 msg(M_WARN,
142 "Unsupported %scipher algorithm '%s'. It does not use "
143 "CFB, OFB, CBC, or a supported AEAD mode",
144 optstr, token);
146 }
147 else
148 {
150 if (nonecipher)
151 {
152 /* NULL resolves to [null-cipher] but we need none for
153 * data-ciphers */
154 ovpn_cipher_name = "none";
155 }
156
157 if (buf_len(&new_list) > 0)
158 {
159 /* The next if condition ensure there is always space for
160 * a :
161 */
162 buf_puts(&new_list, ":");
163 }
164
165 /* Ensure buffer has capacity for cipher name + : + \0 */
167 {
168 msg(M_WARN, "Length of --data-ciphers is over the "
169 "limit of 127 chars");
170 error_found = true;
171 }
172 else
173 {
175 }
176 }
177 token = strtok(NULL, ":");
178 }
179
180
181 char *ret = NULL;
182 if (!error_found && buf_len(&new_list) > 0)
183 {
186 }
187 free(tmp_ciphers);
189
190 return ret;
191}
192
193
194void
195append_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, ciphername));
202 o->ncp_ciphers = ncp_ciphers;
203}
204
205bool
206tls_item_in_cipher_list(const char *item, const char *list)
207{
208 char *tmp_ciphers = string_alloc(list, NULL);
210
211 const char *token = strtok(tmp_ciphers, ":");
212 while (token)
213 {
214 if (0 == strcmp(token, item))
215 {
216 break;
217 }
218 token = strtok(NULL, ":");
219 }
220 free(tmp_ciphers_orig);
221
222 return token != NULL;
223}
224const char *
225tls_peer_ncp_list(const char *peer_info, struct gc_arena *gc)
226{
227 /* Check if the peer sends the IV_CIPHERS list */
228 const char *iv_ciphers = extract_var_peer_info(peer_info, "IV_CIPHERS=", gc);
229 if (iv_ciphers)
230 {
231 return iv_ciphers;
232 }
233 else if (tls_peer_info_ncp_ver(peer_info) >= 2)
234 {
235 /* If the peer announces IV_NCP=2 then it supports the AES GCM
236 * ciphers */
237 return "AES-256-GCM:AES-128-GCM";
238 }
239 else
240 {
241 return "";
242 }
243}
244
245char *
246ncp_get_best_cipher(const char *server_list, const char *peer_info, const char *remote_cipher,
247 struct gc_arena *gc)
248{
249 /*
250 * The gc of the parameter is tied to the VPN session, create a
251 * short lived gc arena that is only valid for the duration of
252 * this function
253 */
254
255 struct gc_arena gc_tmp = gc_new();
256
257 const char *peer_ncp_list = tls_peer_ncp_list(peer_info, &gc_tmp);
258
259 /* non-NCP clients without OCC? "assume nothing" */
260 /* For client doing the newer version of NCP (that send IV_CIPHERS)
261 * we cannot assume that they will accept remote_cipher */
262 if (remote_cipher == NULL || (peer_info && strstr(peer_info, "IV_CIPHERS=")))
263 {
264 remote_cipher = "";
265 }
266
267 char *tmp_ciphers = string_alloc(server_list, &gc_tmp);
268
269 const char *token;
270 while ((token = strsep(&tmp_ciphers, ":")))
271 {
272 if (tls_item_in_cipher_list(token, peer_ncp_list) || streq(token, remote_cipher))
273 {
274 break;
275 }
276 }
277
278 char *ret = NULL;
279 if (token != NULL)
280 {
281 ret = string_alloc(token, gc);
282 }
283
284 gc_free(&gc_tmp);
285 return ret;
286}
287
297static bool
298tls_poor_mans_ncp(struct options *o, const char *remote_ciphername)
299{
300 if (remote_ciphername && tls_item_in_cipher_list(remote_ciphername, o->ncp_ciphers))
301 {
302 o->ciphername = string_alloc(remote_ciphername, &o->gc);
303 msg(D_TLS_DEBUG_LOW, "Using peer cipher '%s'", o->ciphername);
304 return true;
305 }
306 return false;
307}
308
309bool
310check_pull_client_ncp(struct context *c, const unsigned int found)
311{
312 if (found & OPT_P_NCP)
313 {
314 msg(D_PUSH_DEBUG, "OPTIONS IMPORT: data channel crypto options modified");
315 return true;
316 }
317
318 /* If the server did not push a --cipher, we will switch to the
319 * remote cipher if it is in our ncp-ciphers list */
321 {
322 return true;
323 }
324
325 /* We could not figure out the peer's cipher but we have fallback
326 * enabled */
328 {
329 return true;
330 }
331
332 /* We failed negotiation, give appropriate error message */
334 {
336 "OPTIONS ERROR: failed to negotiate "
337 "cipher with server. Add the server's "
338 "cipher ('%s') to --data-ciphers (currently '%s'), e.g."
339 "--data-ciphers %s:%s if you want to connect to this server.",
342 return false;
343 }
344 else
345 {
346 msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to negotiate "
347 "cipher with server. Configure "
348 "--data-ciphers-fallback if you want to connect "
349 "to this server.");
350 return false;
351 }
352}
353
354const char *
355get_p2p_ncp_cipher(struct tls_session *session, const char *peer_info, struct gc_arena *gc)
356{
357 /* we use a local gc arena to keep the temporary strings needed by strsep */
358 struct gc_arena gc_local = gc_new();
359 const char *peer_ciphers = extract_var_peer_info(peer_info, "IV_CIPHERS=", &gc_local);
360
361 if (!peer_ciphers)
362 {
363 gc_free(&gc_local);
364 return NULL;
365 }
366
367 const char *server_ciphers;
368 const char *client_ciphers;
369
370 if (session->opt->server)
371 {
372 server_ciphers = session->opt->config_ncp_ciphers;
373 client_ciphers = peer_ciphers;
374 }
375 else
376 {
377 client_ciphers = session->opt->config_ncp_ciphers;
378 server_ciphers = peer_ciphers;
379 }
380
381 /* Find the first common cipher from TLS server and TLS client. We
382 * use the preference of the server here to make it deterministic */
383 char *tmp_ciphers = string_alloc(server_ciphers, &gc_local);
384
385 const char *token;
386 while ((token = strsep(&tmp_ciphers, ":")))
387 {
388 if (tls_item_in_cipher_list(token, client_ciphers))
389 {
390 break;
391 }
392 }
393
394 const char *ret = NULL;
395 if (token != NULL)
396 {
397 ret = string_alloc(token, gc);
398 }
399 gc_free(&gc_local);
400
401 return ret;
402}
403
404static void
405p2p_ncp_set_options(struct tls_multi *multi, struct tls_session *session, const char *common_cipher)
406{
407 /* will return 0 if peer_info is null */
408 const unsigned int iv_proto_peer = extract_iv_proto(multi->peer_info);
409
410 /* The other peer does not support P2P NCP */
411 if (!(iv_proto_peer & IV_PROTO_NCP_P2P))
412 {
413 return;
414 }
415
416 if (iv_proto_peer & IV_PROTO_DATA_V2)
417 {
418 multi->use_peer_id = true;
419 multi->peer_id = 0x76706e; /* 'v' 'p' 'n' */
420 }
421
422 if (iv_proto_peer & IV_PROTO_CC_EXIT_NOTIFY)
423 {
424 session->opt->crypto_flags |= CO_USE_CC_EXIT_NOTIFY;
425 }
426
427 if (session->opt->data_epoch_supported && (iv_proto_peer & IV_PROTO_DATA_EPOCH) && common_cipher
428 && cipher_kt_mode_aead(common_cipher))
429 {
430 session->opt->crypto_flags |= CO_EPOCH_DATA_KEY_FORMAT;
431 }
432 else
433 {
434 /* The peer might have changed its ciphers options during reconnect,
435 * ensure we clear the flag if we previously had it enabled */
436 session->opt->crypto_flags &= ~CO_EPOCH_DATA_KEY_FORMAT;
437 }
438
439 if (iv_proto_peer & IV_PROTO_TLS_KEY_EXPORT)
440 {
441 session->opt->crypto_flags |= CO_USE_TLS_KEY_MATERIAL_EXPORT;
442
443 if (multi->use_peer_id)
444 {
445 /* Using a non hardcoded peer-id makes a tiny bit harder to
446 * fingerprint packets and also gives each connection a unique
447 * peer-id that can be useful for NAT tracking etc. */
448
449 uint8_t peerid[3];
451 strlen(EXPORT_P2P_PEERID_LABEL), &peerid, 3))
452 {
453 /* Non DCO setup might still work but also this should never
454 * happen or very likely the TLS encryption key exporter will
455 * also fail */
456 msg(M_NONFATAL, "TLS key export for P2P peer id failed. "
457 "Continuing anyway, expect problems");
458 }
459 else
460 {
461 multi->peer_id = (peerid[0] << 16) + (peerid[1] << 8) + peerid[2];
462 }
463 }
464 }
465 if (iv_proto_peer & IV_PROTO_DYN_TLS_CRYPT)
466 {
467 session->opt->crypto_flags |= CO_USE_DYNAMIC_TLS_CRYPT;
468 }
469}
470
471void
473{
474 struct gc_arena gc = gc_new();
475
476 /* Query the common cipher here to log it as part of our message.
477 * We postpone switching the cipher to do_up */
478 const char *common_cipher = get_p2p_ncp_cipher(session, multi->peer_info, &gc);
479
480 /* Set the common options */
481 p2p_ncp_set_options(multi, session, common_cipher);
482
483 if (!common_cipher)
484 {
485 struct buffer out = alloc_buf_gc(128, &gc);
486 /* at this point we do not really know if our fallback is
487 * not enabled or if we use 'none' cipher as fallback, so
488 * keep this ambiguity here and print fallback-cipher: none
489 */
490
491 const char *fallback_name = "none";
492 const char *ciphername = session->opt->key_type.cipher;
493
494 if (cipher_defined(ciphername))
495 {
496 fallback_name = cipher_kt_name(ciphername);
497 }
498
499 buf_printf(&out, "(not negotiated, fallback-cipher: %s)", fallback_name);
500 common_cipher = BSTR(&out);
501 }
502
504 "P2P mode NCP negotiation result: "
505 "TLS_export=%d, DATA_v2=%d, peer-id %d, epoch=%d, cipher=%s",
506 (bool)(session->opt->crypto_flags & CO_USE_TLS_KEY_MATERIAL_EXPORT), multi->use_peer_id,
507 multi->peer_id, (bool)(session->opt->crypto_flags & CO_EPOCH_DATA_KEY_FORMAT),
509
510 gc_free(&gc);
511}
512
513
514bool
516{
518 options->enable_ncp_fallback && streq(options->ciphername, session->opt->config_ciphername);
519
520 if (!session->opt->server && !cipher_allowed_as_fallback
522 {
523 struct gc_arena gc = gc_new();
524 msg(D_TLS_ERRORS, "Error: negotiated cipher not allowed - %s not in %s%s",
526 /* undo cipher push, abort connection setup */
527 options->ciphername = session->opt->config_ciphername;
528 gc_free(&gc);
529 return false;
530 }
531 else
532 {
533 return true;
534 }
535}
536
543static void
544replace_default_in_ncp_ciphers_option(struct options *o, const char *replace)
545{
546 const char *search = "DEFAULT";
547 const int ncp_ciphers_len = strlen(o->ncp_ciphers) + strlen(replace) - strlen(search) + 1;
548
549 uint8_t *ncp_ciphers = gc_malloc(ncp_ciphers_len, true, &o->gc);
550
551 struct buffer ncp_ciphers_buf;
553
554 const char *def = strstr(o->ncp_ciphers, search);
555
556 /* Copy everything before the DEFAULT string */
557 buf_write(&ncp_ciphers_buf, o->ncp_ciphers, def - o->ncp_ciphers);
558
559 /* copy the default string. */
561
562 /* copy the rest of the ncp cipher string */
563 const char *after_default = def + strlen(search);
565
566 o->ncp_ciphers = (char *)ncp_ciphers;
567}
568
574void
576{
578 o->ncp_ciphers && tls_item_in_cipher_list("DEFAULT", o->ncp_ciphers);
579
580 /* preserve the values that the user put into the configuration */
581 o->ncp_ciphers_conf = o->ncp_ciphers;
582
583 /* check if crypto library supports chacha */
584 bool can_do_chacha = cipher_valid("CHACHA20-POLY1305");
585
587 {
588 /* also make sure that dco supports chacha */
590 }
591
592 const char *default_ciphers = "AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305";
593
594 if (!can_do_chacha)
595 {
596 default_ciphers = "AES-256-GCM:AES-128-GCM";
597 }
598
599 /* want to rather print DEFAULT instead of a manually set default list */
600 if (!o->ncp_ciphers_conf || !strcmp(default_ciphers, o->ncp_ciphers_conf))
601 {
602 o->ncp_ciphers = default_ciphers;
603 o->ncp_ciphers_conf = "DEFAULT";
604 }
605 else if (!default_in_cipher_list)
606 {
607 /* custom cipher list without DEFAULT string in it,
608 * nothing to replace/mutate */
609 return;
610 }
611 else
612 {
614 }
615}
616
617const char *
619{
620 if (!strcmp(o->ncp_ciphers, o->ncp_ciphers_conf))
621 {
622 /* expanded ciphers and user set ciphers are identical, no need to
623 * add an expanded version */
624 return "";
625 }
626
627 /* two extra brackets, one space, NUL byte */
628 struct buffer expanded_ciphers_buf = alloc_buf_gc(strlen(o->ncp_ciphers) + 4, gc);
629
630 buf_printf(&expanded_ciphers_buf, " (%s)", o->ncp_ciphers);
631 return BSTR(&expanded_ciphers_buf);
632}
void free_buf(struct buffer *buf)
Definition buffer.c:184
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:241
bool buf_puts(struct buffer *buf, const char *str)
Definition buffer.c:268
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:89
struct buffer alloc_buf(size_t size)
Definition buffer.c:63
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:649
#define BSTR(buf)
Definition buffer.h:128
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:539
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:660
static void gc_free(struct gc_arena *a)
Definition buffer.h:1015
static char * buf_str(const struct buffer *buf)
Definition buffer.h:297
static struct gc_arena gc_new(void)
Definition buffer.h:1007
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:357
#define CO_USE_DYNAMIC_TLS_CRYPT
Bit-flag indicating that renegotiations are using tls-crypt with a TLS-EKM derived key.
Definition crypto.h:373
#define CO_EPOCH_DATA_KEY_FORMAT
Bit-flag indicating the epoch the data format.
Definition crypto.h:377
#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:369
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:383
#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:89
#define msg(flags,...)
Definition error.h:150
#define ASSERT(x)
Definition error.h:217
#define M_WARN
Definition error.h:90
#define OPT_P_NCP
Negotiable crypto parameters.
Definition options.h:744
#define streq(x, y)
Definition options.h:727
static bool dco_enabled(const struct options *o)
Returns whether the current configuration has dco enabled.
Definition options.h:936
#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:246
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:225
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:575
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:618
bool check_pull_client_ncp(struct context *c, const unsigned int found)
Checks whether the cipher negotiation is in an acceptable state and we continue to connect or should ...
Definition ssl_ncp.c:310
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:515
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:472
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:206
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
static void p2p_ncp_set_options(struct tls_multi *multi, struct tls_session *session, const char *common_cipher)
Definition ssl_ncp.c:405
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:298
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:355
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:544
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:60
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
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:517
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:116
const char * ncp_ciphers_conf
The original ncp_ciphers specified by the user in the configuration.
Definition options.h:580
const char * ncp_ciphers
Definition options.h:581
const char * ciphername
Definition options.h:576
bool enable_ncp_fallback
If defined fall back to ciphername if NCP fails.
Definition options.h:577
struct gc_arena gc
Definition options.h:253
Security parameter state for a single VPN tunnel.
Definition ssl_common.h:612
char * peer_info
A multi-line string of general-purpose info received from peer over control channel.
Definition ssl_common.h:673
char * remote_ciphername
cipher specified in peer's config file
Definition ssl_common.h:703
uint32_t peer_id
Definition ssl_common.h:700
bool use_peer_id
Definition ssl_common.h:701
Security parameter state of a single session within a VPN tunnel.
Definition ssl_common.h:490
struct gc_arena gc
Definition test_ssl.c:154