OpenVPN
Data Structures
Control Channel Processor module

This module controls the setup and maintenance of VPN tunnels and the associated security parameters. More...

Data Structures

struct  key
 Container for unidirectional cipher and HMAC key material. More...
 
struct  key_ctx
 Container for one set of cipher and/or HMAC contexts. More...
 
struct  key2
 Container for bidirectional cipher and HMAC key material. More...
 
struct  key_direction_state
 Key ordering of the key2.keys array. More...
 
struct  key_ctx_bi
 Container for two sets of OpenSSL cipher and/or HMAC contexts for both sending and receiving directions. More...
 
struct  key_source
 Container for one half of random material to be used in key method 2 data channel key generation. More...
 
struct  key_source2
 Container for both halves of random material to be used in key method 2 data channel key generation. More...
 
struct  key_state
 Security parameter state of one TLS and data channel key session. More...
 
struct  tls_session
 Security parameter state of a single session within a VPN tunnel. More...
 
struct  tls_multi
 Security parameter state for a single VPN tunnel. More...
 

Functions for initialization and cleanup of key_state structures

static void key_state_init (struct tls_session *session, struct key_state *ks)
 Initialize a key_state structure. More...
 
static void key_state_free (struct key_state *ks, bool clear)
 Cleanup a key_state structure. More...
 

Functions for initialization and cleanup of tls_session structures

static void tls_session_init (struct tls_multi *multi, struct tls_session *session)
 Initialize a tls_session structure. More...
 
static void tls_session_free (struct tls_session *session, bool clear)
 Clean up a tls_session structure. More...
 

Functions for initialization and cleanup of tls_multi structures

struct tls_multitls_multi_init (struct tls_options *tls_options)
 Allocate and initialize a tls_multi structure. More...
 
void tls_multi_init_finalize (struct tls_multi *multi, int tls_mtu)
 Finalize initialization of a tls_multi structure. More...
 
struct tls_auth_standalonetls_auth_standalone_init (struct tls_options *tls_options, struct gc_arena *gc)
 
void tls_auth_standalone_free (struct tls_auth_standalone *tas)
 Frees a standalone tls-auth verification object. More...
 
void tls_init_control_channel_frame_parameters (struct frame *frame, int tls_mtu)
 
void tls_multi_init_set_options (struct tls_multi *multi, const char *local, const char *remote)
 
void tls_multi_free (struct tls_multi *multi, bool clear)
 Cleanup a tls_multi structure and free associated memory allocations. More...
 

Control channel negotiation states

These states represent the different phases of control channel negotiation between OpenVPN peers.

OpenVPN servers and clients progress through the states in a different order, because of their different roles during exchange of random material. The references to the key_source2 structure in the list below is only valid if key method 2 is being used. See the data channel key generation related page for more information.

Clients follow this order:

  1. S_INITIAL, ready to begin three-way handshake and control channel negotiation.
  2. S_PRE_START, have started three-way handshake, waiting for acknowledgment from remote.
  3. S_START, initial three-way handshake complete.
  4. S_SENT_KEY, have sent local part of key_source2 random material.
  5. S_GOT_KEY, have received remote part of key_source2 random material.
  6. S_ACTIVE, control channel successfully established
  7. S_GENERATED_KEYS, the data channel keys have been generated

Servers follow the same order, except for S_SENT_KEY and S_GOT_KEY being reversed, because the server first receives the client's key_source2 random material before generating and sending its own.

#define S_ERROR   -1
 Error state. More...
 
#define S_UNDEF   0
 Undefined state, used after a key_state is cleaned up. More...
 
#define S_INITIAL   1
 Initial key_state state after initialization by key_state_init() before start of three-way handshake. More...
 
#define S_PRE_START   2
 Waiting for the remote OpenVPN peer to acknowledge during the initial three-way handshake. More...
 
#define S_START   3
 Three-way handshake is complete, start of key exchange. More...
 
#define S_SENT_KEY   4
 Local OpenVPN process has sent its part of the key material. More...
 
#define S_GOT_KEY   5
 Local OpenVPN process has received the remote's part of the key material. More...
 
#define S_ACTIVE   6
 Operational key_state state immediately after negotiation has completed while still within the handshake window. More...
 
#define S_GENERATED_KEYS   7
 The data channel keys have been generated The TLS session is fully authenticated when reaching this state. More...
 

Index of key_state objects within a tls_session structure

This is the index of tls_session.key

#define KS_PRIMARY   0
 Primary key state index. More...
 
#define KS_LAME_DUCK   1
 Key state index that will retire soon. More...
 
#define KS_SIZE   2
 Size of the tls_session.key array. More...
 

Index of tls_session objects within a tls_multi structure

This is the index of tls_multi.session

Normally three tls_session objects are maintained by an active openvpn session. The first is the current, TLS authenticated session, the second is used to process connection requests from a new client that would usurp the current session if successfully authenticated, and the third is used as a repository for a "lame-duck" key in the event that the primary session resets due to error while the lame-duck key still has time left before its expiration. Lame duck keys are used to maintain the continuity of the data channel connection while a new key is being negotiated.

#define TM_ACTIVE   0
 Active tls_session. More...
 
#define TM_INITIAL   1
 As yet un-trusted tls_session being negotiated. More...
 
#define TM_LAME_DUCK   2
 Old tls_session. More...
 
#define TM_SIZE   3
 Size of the tls_multi.session array. More...
 

Detailed Description

This module controls the setup and maintenance of VPN tunnels and the associated security parameters.

This module's role
The Control Channel Processor module lies at the core of OpenVPN's activities. It handles the setup of new VPN tunnels, the negotiation of data channel security parameters, the managing of active VPN tunnels, and finally the cleanup of expired VPN tunnels.
State structures
A large amount of VPN tunnel state information must be stored within an OpenVPN process. A wide variety of container structures are used by this module for that purpose. Several of these structures are listed below, and the function of the first three VPN tunnel state containers is described in more detail later.
  • VPN tunnel state containers:
    • tls_multi, security parameter state for a single VPN tunnel. Contains three instances of the tls_session structure.
    • tls_session, security parameter state of a single session within a VPN tunnel. Contains two instances of the key_state structure.
    • key_state, security parameter state of one TLS and data channel key set.
  • Data channel security parameter containers:
    • key_ctx_bi, container for two sets of OpenSSL cipher and/or HMAC context (both directions). Contains two instances of the key_ctx structure.
    • key_ctx, container for one set of OpenSSL cipher and/or HMAC context (one directions.
  • Key material containers:
    • key2, container for two sets of cipher and/or HMAC key material (both directions). Contains two instances of the key structure.
    • key, container for one set of cipher and/or HMAC key material (one direction).
    • key_direction_state, ordering of key material within the key2.key array.
  • Key method 2 random material containers:
    • key_source2, container for both halves of random material used for key method 2. Contains two instances of the key_source structure.
    • key_source, container for one half of random material used for key method 2.
The life of a tls_multi object
A tls_multi structure contains all the security parameter state information related to the control and data channels of one VPN tunnel. Its life cycle can be summarized as follows:
  1. Initialization: tls_multi_init() and tls_multi_init_finalize(), which are called (indirectly) from init_instance() when initializing a new context structure.
    • Initializes a tls_multi structure.
    • Allocates the three tls_session objects contained by the tls_multi structure, and initializes as appropriate.
  2. Management: tls_multi_process() and tls_pre_decrypt()
  3. Cleanup: tls_multi_free(), which is called (indirectly) from close_instance() when cleaning up a context structure.
The life of a tls_session object
A tls_session structure contains the state information related to an active and a lame-duck key_state. Its life cycle can be summarized as follows:
  1. Initialization: tls_session_init()
  2. Renegotiation: key_state_soft_reset()
  3. Cleanup: tls_session_free()
The life of a key_state object
A key_state structure represents one control and data channel key set. It contains an OpenSSL TLS object that encapsulates the control channel, and the data channel security parameters needed by the Data Channel Crypto module to perform cryptographic operations on data channel packets. Its life cycle can be summarized as follows:
  1. Initialization: key_state_init()
    • Initializes a key_state structure.
    • Creates a new OpenSSL TLS object to encapsulate this new control channel session.
    • Sets key_state.state to S_INITIAL.
    • Allocates several internal buffers.
    • Initializes new reliability layer structures for this key set.
  2. Negotiation: tls_process()
    • The OpenSSL TLS object negotiates a TLS session between itself and the remote peer's TLS object.
    • Key material is generated and exchanged through the TLS session between OpenVPN peers.
    • Both peers initialize their data channel cipher and HMAC key contexts.
    • On successful negotiation, the key_state.state will progress from S_INITIAL to S_ACTIVE and S_NORMAL.
  3. Active tunneling: Data Channel Crypto module
  4. Cleanup: key_state_free()
    • Cleans up a key_state structure together with its OpenSSL TLS object, key material, internal buffers, and reliability layer structures.
Control functions
The following two functions drive the Control Channel Processor's activities.
Functions which control data channel key generation
  • Key method 1 key exchange functions were removed from OpenVPN 2.5
  • Key method 2 key exchange functions:

Macro Definition Documentation

◆ KS_LAME_DUCK

#define KS_LAME_DUCK   1

Key state index that will retire soon.

Definition at line 446 of file ssl_common.h.

◆ KS_PRIMARY

#define KS_PRIMARY   0

Primary key state index.

Definition at line 445 of file ssl_common.h.

◆ KS_SIZE

#define KS_SIZE   2

Size of the tls_session.key array.

Definition at line 448 of file ssl_common.h.

◆ S_ACTIVE

#define S_ACTIVE   6

Operational key_state state immediately after negotiation has completed while still within the handshake window.

Deferred auth and client connect can still be pending.

Definition at line 93 of file ssl_common.h.

◆ S_ERROR

#define S_ERROR   -1

Error state.


Definition at line 77 of file ssl_common.h.

◆ S_GENERATED_KEYS

#define S_GENERATED_KEYS   7

The data channel keys have been generated The TLS session is fully authenticated when reaching this state.

Definition at line 98 of file ssl_common.h.

◆ S_GOT_KEY

#define S_GOT_KEY   5

Local OpenVPN process has received the remote's part of the key material.

Definition at line 90 of file ssl_common.h.

◆ S_INITIAL

#define S_INITIAL   1

Initial key_state state after initialization by key_state_init() before start of three-way handshake.

Definition at line 80 of file ssl_common.h.

◆ S_PRE_START

#define S_PRE_START   2

Waiting for the remote OpenVPN peer to acknowledge during the initial three-way handshake.

Definition at line 83 of file ssl_common.h.

◆ S_SENT_KEY

#define S_SENT_KEY   4

Local OpenVPN process has sent its part of the key material.

Definition at line 88 of file ssl_common.h.

◆ S_START

#define S_START   3

Three-way handshake is complete, start of key exchange.

Definition at line 86 of file ssl_common.h.

◆ S_UNDEF

#define S_UNDEF   0

Undefined state, used after a key_state is cleaned up.

Definition at line 78 of file ssl_common.h.

◆ TM_ACTIVE

#define TM_ACTIVE   0

Active tls_session.

Definition at line 526 of file ssl_common.h.

◆ TM_INITIAL

#define TM_INITIAL   1

As yet un-trusted tls_session being negotiated.

Definition at line 527 of file ssl_common.h.

◆ TM_LAME_DUCK

#define TM_LAME_DUCK   2

Old tls_session.

Definition at line 529 of file ssl_common.h.

◆ TM_SIZE

#define TM_SIZE   3

Size of the tls_multi.session array.

Definition at line 530 of file ssl_common.h.

Function Documentation

◆ key_state_free()

static void key_state_free ( struct key_state ks,
bool  clear 
)
static

◆ key_state_init()

static void key_state_init ( struct tls_session session,
struct key_state ks 
)
static

Initialize a key_state structure.

This function initializes a key_state structure associated with a tls_session. It sets up the structure's SSL-BIO, sets the object's key_state.state to S_INITIAL, and sets the session ID and key ID two appropriate values based on the tls_session's internal state. It also initializes a new set of structures for the Reliability Layer.

Parameters
session- A pointer to the tls_session structure associated with the ks argument.
ks- A pointer to the key_state structure to be initialized. This structure should already have been allocated before calling this function.

Definition at line 795 of file ssl.c.

References key_state::ack_write_buf, alloc_buf(), ALLOC_OBJ_CLEAR, BUF_SIZE, CLEAR, key_state::crypto_options, key_state::initial_opcode, key_state::key_id, key_state::key_src, key_state_ssl_init(), key_state::ks_ssl, key_state::lru_acks, key_state::mda_key_id, P_CONTROL_SOFT_RESET_V1, P_KEY_ID_MASK, crypto_options::packet_id, packet_id_init(), crypto_options::pid_persist, key_state::plaintext_read_buf, key_state::plaintext_write_buf, key_state::rec_ack, key_state::rec_reliable, reliable_init(), reliable_set_timeout(), S_INITIAL, key_state::send_reliable, SSLF_CRL_VERIFY_DIR, key_state::state, TLS_CHANNEL_BUF_SIZE, tls_ctx_reload_crl(), TLS_RELIABLE_N_REC_BUFFERS, TLS_RELIABLE_N_SEND_BUFFERS, and update_time().

Referenced by key_state_soft_reset(), and tls_session_init().

◆ tls_auth_standalone_free()

void tls_auth_standalone_free ( struct tls_auth_standalone tas)

Frees a standalone tls-auth verification object.

Parameters
tasthe object to free. May be NULL.

Definition at line 1198 of file ssl.c.

References tls_wrap_ctx::opt, crypto_options::packet_id, packet_id_free(), and tls_auth_standalone::tls_wrap.

Referenced by do_close_tls().

◆ tls_auth_standalone_init()

struct tls_auth_standalone* tls_auth_standalone_init ( struct tls_options tls_options,
struct gc_arena gc 
)

◆ tls_init_control_channel_frame_parameters()

void tls_init_control_channel_frame_parameters ( struct frame frame,
int  tls_mtu 
)

◆ tls_multi_free()

void tls_multi_free ( struct tls_multi multi,
bool  clear 
)

Cleanup a tls_multi structure and free associated memory allocations.

This function cleans up a tls_multi structure. This includes cleaning up all associated tls_session structures.

Parameters
multi- The tls_multi structure to clean up in free.
clear- Whether the memory allocated for the multi object should be overwritten with 0s.

Definition at line 1227 of file ssl.c.

References ASSERT, auth_set_client_reason(), cert_hash_free(), tls_multi::locked_cert_hash_set, tls_multi::locked_cn, tls_multi::locked_username, tls_multi::peer_info, tls_multi::remote_ciphername, secure_memzero(), tls_multi::session, tls_session_free(), TM_SIZE, and wipe_auth_token().

Referenced by do_close_tls().

◆ tls_multi_init()

struct tls_multi* tls_multi_init ( struct tls_options tls_options)

Allocate and initialize a tls_multi structure.

This function allocates a new tls_multi structure, and performs some amount of initialization. Afterwards, the tls_multi_init_finalize() function must be called to finalize the structure's initialization process.

Parameters
tls_options- The configuration options to be used for this VPN tunnel.
Returns
A newly allocated and initialized tls_multi structure.

Definition at line 1143 of file ssl.c.

References ALLOC_OBJ_CLEAR, tls_multi::dco_peer_id, MAX_PEER_ID, tls_multi::opt, and tls_multi::peer_id.

Referenced by do_init_crypto_tls().

◆ tls_multi_init_finalize()

void tls_multi_init_finalize ( struct tls_multi multi,
int  tls_mtu 
)

Finalize initialization of a tls_multi structure.

This function initializes the TM_ACTIVE tls_session, and in server mode also the TM_INITIAL tls_session, associated with this tls_multi structure. It also configures the control channel's frame structure based on the data channel's frame given in argument frame.

Parameters
multi- The tls_multi structure of which to finalize initialization.
tls_mtu- maximum allowed size for control channel packets

Definition at line 1158 of file ssl.c.

References tls_options::frame, tls_multi::opt, tls_multi::session, tls_init_control_channel_frame_parameters(), tls_session_init(), TM_ACTIVE, and TM_INITIAL.

Referenced by do_init_frame_tls().

◆ tls_multi_init_set_options()

void tls_multi_init_set_options ( struct tls_multi multi,
const char *  local,
const char *  remote 
)

Definition at line 1214 of file ssl.c.

References tls_options::local_options, tls_multi::opt, and tls_options::remote_options.

Referenced by do_compute_occ_strings().

◆ tls_session_free()

static void tls_session_free ( struct tls_session session,
bool  clear 
)
static

Clean up a tls_session structure.

This function cleans up a tls_session structure. This includes cleaning up all associated key_state structures.

Parameters
session- A pointer to the tls_session structure to be cleaned up.
clear- Whether the memory allocated for the session object should be overwritten with 0s. This implicitly sets many states to 0/false, e.g. the validity of the keys in the structure

Definition at line 1034 of file ssl.c.

References cert_hash_free(), session::key, key_state_free(), KS_SIZE, secure_memzero(), and tls_wrap_free().

Referenced by move_session(), reset_session(), tls_multi_free(), and tls_multi_process().

◆ tls_session_init()

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

Initialize a tls_session structure.

This function initializes a tls_session structure. This includes generating a random session ID, and initializing the KS_PRIMARY key_state in the tls_session.key array.

Parameters
multi- A pointer to the tls_multi structure associated with the session argument.
session- A pointer to the tls_session structure to be initialized. This structure should already have been allocated before calling this function.

Definition at line 960 of file ssl.c.

References alloc_buf(), BUF_SIZE, CLEAR, D_TLS_DEBUG, dmsg, EARLY_NEG_START, gc_free(), gc_new(), session::key, key_state_init(), KS_PRIMARY, now, tls_multi::opt, P_CONTROL_HARD_RESET_CLIENT_V2, P_CONTROL_HARD_RESET_CLIENT_V3, P_CONTROL_HARD_RESET_SERVER_V2, packet_id_init(), packet_id_persist_load_obj(), session_id_defined(), session_id_print(), and session_id_random().

Referenced by move_session(), reset_session(), and tls_multi_init_finalize().