OpenVPN
Functions
ssl_ncp.c File Reference
#include "syshead.h"
#include "win32.h"
#include "error.h"
#include "common.h"
#include "ssl_ncp.h"
#include "ssl_util.h"
#include "openvpn.h"
Include dependency graph for ssl_ncp.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

static int tls_peer_info_ncp_ver (const char *peer_info)
 Return the Negotiable Crypto Parameters version advertised in the peer info string, or 0 if none specified. More...
 
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. More...
 
char * mutate_ncp_cipher_list (const char *list, struct gc_arena *gc)
 Check whether the ciphers in the supplied list are supported. More...
 
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. More...
 
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. More...
 
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_info. More...
 
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 peer according to the IV_NCP and IV_CIPHER values in peer_info. More...
 
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. More...
 
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 abort. More...
 
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. More...
 
static void p2p_ncp_set_options (struct tls_multi *multi, struct tls_session *session)
 
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. More...
 

Function Documentation

◆ 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.

Parameters
ooptions struct to modify. Its gc is also used
ciphernamethe ciphername to add

Definition at line 177 of file ssl_ncp.c.

References ASSERT, options::gc, gc_malloc(), options::ncp_ciphers, and openvpn_snprintf().

Referenced by options_set_backwards_compatible_options().

◆ check_pull_client_ncp()

bool check_pull_client_ncp ( struct context c,
int  found 
)

Checks whether the cipher negotiation is in an acceptable state and we continue to connect or should abort.

Returns
Wether the client NCP process suceeded or failed

Definition at line 297 of file ssl_ncp.c.

References context::c2, D_PUSH, D_TLS_ERRORS, options::enable_ncp_fallback, msg, options::ncp_ciphers, OPT_P_NCP, context::options, tls_multi::remote_ciphername, context_2::tls_multi, and tls_poor_mans_ncp().

Referenced by do_deferred_options().

◆ 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.

The first cipher from the tls-server that is also in the tls-client IV_CIPHER list will be returned. If no common cipher can be found, both peer will continue to use whatever cipher is their default and NULL will be returned.

Parameters
sessiontls_session
peer_infopeer info of the peer
gcgc arena that will be used to allocate the returned cipher
Returns
common cipher if one exist.

Definition at line 342 of file ssl_ncp.c.

References tls_options::config_ncp_ciphers, extract_var_peer_info(), gc_free(), gc_new(), tls_session::opt, tls_options::server, string_alloc(), strsep(), and tls_item_in_cipher_list().

Referenced by do_deferred_p2p_ncp(), and p2p_mode_ncp().

◆ 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.

Parameters
listColon-separated list of ciphers gc gc_arena to allocate the returned string
Returns
colon separated string of normalised (via translate_cipher_name_from_openvpn) and zero terminated string iff all ciphers in list are supported and the total length is short than MAX_NCP_CIPHERS_LENGTH. NULL otherwise.

Definition at line 97 of file ssl_ncp.c.

References alloc_buf(), buf_forward_capacity(), buf_len(), buf_null_terminate(), buf_puts(), buf_str(), cipher_kt_get(), cipher_kt_name(), free, free_buf(), M_WARN, MAX_NCP_CIPHERS_LENGTH, msg, and string_alloc().

Referenced by options_postprocess_mutate(), and test_check_ncp_ciphers_list().

◆ 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 peer according to the IV_NCP and IV_CIPHER values in peer_info.

We also accept a cipher that is the remote cipher of the client for "Poor man's NCP": Use peer cipher if it is an allowed (NCP) cipher. Allows non-NCP peers to upgrade their cipher individually.

Make sure to call tls_session_update_crypto_params() after calling this function.

Parameters
gcgc arena that is ONLY used to allocate the returned string
Returns
NULL if no common cipher is available, otherwise the best common cipher

Definition at line 230 of file ssl_ncp.c.

References gc_free(), gc_new(), streq, string_alloc(), strsep(), tls_item_in_cipher_list(), and tls_peer_ncp_list().

Referenced by multi_client_set_protocol_options(), test_ncp_best(), and test_poor_man().

◆ 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.

In contrast of the server mode NCP that tries to accomandate all kind of corner cases in P2P mode NCP only takes IV_CIPHER into account and falls back to previous behaviour if this fails.

Definition at line 443 of file ssl_ncp.c.

References alloc_buf_gc(), BSTR, buf_printf(), key_ctx::cipher, cipher_ctx_get_cipher_kt(), cipher_kt_name(), CO_USE_TLS_KEY_MATERIAL_EXPORT, tls_options::crypto_flags, key_state::crypto_options, D_TLS_DEBUG_LOW, key_ctx_bi::encrypt, gc_free(), gc_new(), get_key_scan(), get_p2p_ncp_cipher(), crypto_options::key_ctx_bi, KS_PRIMARY, msg, tls_session::opt, p2p_ncp_set_options(), tls_multi::peer_id, tls_multi::peer_info, and tls_multi::use_peer_id.

Referenced by key_method_2_read(), and key_method_2_write().

◆ p2p_ncp_set_options()

static void p2p_ncp_set_options ( struct tls_multi multi,
struct tls_session session 
)
static

◆ 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 at line 189 of file ssl_ncp.c.

References free, and string_alloc().

Referenced by do_init_crypto_tls_c1(), get_p2p_ncp_cipher(), ncp_get_best_cipher(), options_postprocess_cipher(), options_set_backwards_compatible_options(), options_string(), push_peer_info(), tls_poor_mans_ncp(), and tls_session_update_crypto_params().

◆ tls_peer_info_ncp_ver()

static int tls_peer_info_ncp_ver ( const char *  peer_info)
static

Return the Negotiable Crypto Parameters version advertised in the peer info string, or 0 if none specified.

Definition at line 59 of file ssl_ncp.c.

Referenced by tls_peer_ncp_list(), and tls_peer_supports_ncp().

◆ 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_info.

Returns
Either a string containing the ncp list that is either static or allocated via gc. If no information is available an empty string ("") is returned.

Definition at line 209 of file ssl_ncp.c.

References extract_var_peer_info(), and tls_peer_info_ncp_ver().

Referenced by multi_client_set_protocol_options(), ncp_get_best_cipher(), and test_extract_client_ciphers().

◆ 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 at line 79 of file ssl_ncp.c.

References tls_peer_info_ncp_ver().

Referenced by prepare_push_reply(), and test_extract_client_ciphers().

◆ tls_poor_mans_ncp()

static bool tls_poor_mans_ncp ( struct options o,
const char *  remote_ciphername 
)
static

"Poor man's NCP": Use peer cipher if it is an allowed (NCP) cipher.

Allows non-NCP peers to upgrade their cipher individually.

Returns true if we switched to the peer's cipher

Make sure to call tls_session_update_crypto_params() after calling this function.

Definition at line 284 of file ssl_ncp.c.

References options::ciphername, D_TLS_DEBUG_LOW, options::gc, msg, options::ncp_ciphers, string_alloc(), and tls_item_in_cipher_list().

Referenced by check_pull_client_ncp().