OpenVPN
Modules
Control Channel TLS module

This module provides secure encapsulation of control channel messages exchanged between OpenVPN peers. More...

Collaboration diagram for Control Channel TLS module:

Modules

 Control channel encryption (--tls-crypt)
 

Functions for packets to be sent to a remote OpenVPN peer

int key_state_write_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf)
 Insert a plaintext buffer into the TLS module. More...
 
int key_state_write_plaintext_const (struct key_state_ssl *ks_ssl, const uint8_t *data, int len)
 Insert plaintext data into the TLS module. More...
 
int key_state_read_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf, int maxlen)
 Extract ciphertext data from the TLS module. More...
 

Functions for packets received from a remote OpenVPN peer

int key_state_write_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf)
 Insert a ciphertext buffer into the TLS module. More...
 
int key_state_read_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf, int maxlen)
 Extract plaintext data from the TLS module. More...
 

Function for authenticating a new connection from a remote OpenVPN peer

int verify_callback (void *session_obj, mbedtls_x509_crt *cert, int cert_depth, uint32_t *flags)
 Verify that the remote OpenVPN peer's certificate allows setting up a VPN tunnel. More...
 

Function for authenticating a new connection from a remote OpenVPN peer

int verify_callback (int preverify_ok, X509_STORE_CTX *ctx)
 Verify that the remote OpenVPN peer's certificate allows setting up a VPN tunnel. More...
 

Detailed Description

This module provides secure encapsulation of control channel messages exchanged between OpenVPN peers.

The Control Channel TLS module uses the Transport Layer Security (TLS) protocol to provide an encrypted communication channel between the local OpenVPN process and a remote peer. This protocol simultaneously offers certificate-based authentication of the communicating parties.

This module's roles
The Control Channel TLS module is essential for the security of any OpenVPN-based system. On the one hand, it performs the security operations necessary to protect control channel messages exchanged between OpenVPN peers. On the other hand, before the control and data channels are even setup, it controls the exchange of certificates and verification of the remote's identity during negotiation of VPN tunnels.
The former role is described below. The latter is described in the documentation for the verify_callback() function.
In other words, this module takes care of the confidentiality and integrity of data channel communications, and the authentication of both the communicating parties and the control channel messages exchanged.
Initialization and cleanup
Because of the one-to-one relationship between control channel TLS state and key_state structures, the initialization and cleanup of an instance of the Control Channel TLS module's state happens within the key_state_init() and key_state_free() functions. In other words, each key_state object contains exactly one OpenSSL SSL-BIO object, which is initialized and cleaned up together with the rest of the key_state object.
Packet processing functions
This object behaves somewhat like a black box with a ciphertext and a plaintext I/O port. Its interaction with OpenVPN's control channel during operation takes place within the tls_process() function of the Control Channel Processor. The following functions are available for processing packets:
Transport Layer Security protocol implementation
This module uses the OpenSSL library's implementation of the TLS protocol in the form of an OpenSSL SSL-BIO object.
For more information on the OpenSSL library's BIO objects, please see:

Function Documentation

◆ key_state_read_ciphertext()

int key_state_read_ciphertext ( struct key_state_ssl ks_ssl,
struct buffer buf,
int  maxlen 
)

Extract ciphertext data from the TLS module.

If the buf buffer has a length other than zero, this function does not perform any action and returns 0.

Parameters
ks_ssl- The security parameter state for this key session.
buf- A buffer in which to store the ciphertext.
maxlen- The maximum number of bytes to extract.
Returns
The return value indicates whether the data was successfully processed:
  • 1: Data was extracted successfully.
  • 0: No data was extracted, this function should be called again later to retry.
  • -1: An error occurred.

Definition at line 1610 of file ssl_openssl.c.

References ASSERT, bio_read(), key_state_ssl::ct_out, PERF_BIO_READ_CIPHERTEXT, perf_pop(), and perf_push().

Referenced by tls_process().

◆ key_state_read_plaintext()

int key_state_read_plaintext ( struct key_state_ssl ks_ssl,
struct buffer buf,
int  maxlen 
)

Extract plaintext data from the TLS module.

If the buf buffer has a length other than zero, this function does not perform any action and returns 0.

Parameters
ks_ssl- The security parameter state for this key session.
buf- A buffer in which to store the plaintext.
maxlen- The maximum number of bytes to extract.
Returns
The return value indicates whether the data was successfully processed:
  • 1: Data was extracted successfully.
  • 0: No data was extracted, this function should be called again later to retry.
  • -1: An error occurred.

Definition at line 1640 of file ssl_openssl.c.

References ASSERT, bio_read(), PERF_BIO_READ_PLAINTEXT, perf_pop(), perf_push(), and key_state_ssl::ssl_bio.

Referenced by tls_process().

◆ key_state_write_ciphertext()

int key_state_write_ciphertext ( struct key_state_ssl ks_ssl,
struct buffer buf 
)

Insert a ciphertext buffer into the TLS module.

After successfully processing the data, the data in buf is zeroized, its length set to zero, and a value of 1 is returned.

Parameters
ks_ssl- The security parameter state for this key session.
buf- The ciphertext message to process.
Returns
The return value indicates whether the data was successfully processed:
  • 1: All the data was processed successfully.
  • 0: The data was not processed, this function should be called again later to retry.
  • -1: An error occurred.

Definition at line 1625 of file ssl_openssl.c.

References ASSERT, bio_write(), bio_write_post(), BLEN, BPTR, key_state_ssl::ct_in, PERF_BIO_WRITE_CIPHERTEXT, perf_pop(), and perf_push().

Referenced by tls_process().

◆ key_state_write_plaintext()

int key_state_write_plaintext ( struct key_state_ssl ks_ssl,
struct buffer buf 
)

Insert a plaintext buffer into the TLS module.

After successfully processing the data, the data in buf is zeroized, its length set to zero, and a value of 1 is returned.

Parameters
ks_ssl- The security parameter state for this key session.
buf- The plaintext message to process.
Returns
The return value indicates whether the data was successfully processed:
  • 1: All the data was processed successfully.
  • 0: The data was not processed, this function should be called again later to retry.
  • -1: An error occurred.

Definition at line 1578 of file ssl_openssl.c.

References ASSERT, bio_write(), bio_write_post(), BLEN, BPTR, PERF_BIO_WRITE_PLAINTEXT, perf_pop(), perf_push(), and key_state_ssl::ssl_bio.

Referenced by tls_process().

◆ key_state_write_plaintext_const()

int key_state_write_plaintext_const ( struct key_state_ssl ks_ssl,
const uint8_t data,
int  len 
)

Insert plaintext data into the TLS module.

Parameters
ks_ssl- The security parameter state for this key session.
data- A pointer to the data to process.
len- The length in bytes of the data to process.
Returns
The return value indicates whether the data was successfully processed:
  • 1: All the data was processed successfully.
  • 0: The data was not processed, this function should be called again later to retry.
  • -1: An error occurred.

Definition at line 1596 of file ssl_openssl.c.

References ASSERT, bio_write(), PERF_BIO_WRITE_PLAINTEXT, perf_pop(), perf_push(), and key_state_ssl::ssl_bio.

Referenced by flush_payload_buffer(), and tls_send_payload().

◆ verify_callback() [1/2]

int verify_callback ( int  preverify_ok,
X509_STORE_CTX *  ctx 
)

Verify that the remote OpenVPN peer's certificate allows setting up a VPN tunnel.

This callback function is called every time a new TLS session is being setup to determine whether the remote OpenVPN peer's certificate is allowed to connect. It is called for once for every certificate in the chain. The callback functionality is configured in the init_ssl() function, which calls the OpenSSL library's SSL_CTX_set_verify() function with verify_callback() as its callback argument.

It checks preverify_ok, and registers the certificate hash. If these steps succeed, it calls the verify_cert() function, which performs OpenVPN-specific verification.

Parameters
preverify_ok- Whether the remote OpenVPN peer's certificate past verification. A value of 1 means it verified successfully, 0 means it failed.
ctx- The complete context used by the OpenSSL library to verify the certificate chain.
Returns
The return value indicates whether the supplied certificate is allowed to set up a VPN tunnel. The following values can be returned:
  • 0: failure, this certificate is not allowed to connect.
  • 1: success, this certificate is allowed to connect.

Definition at line 51 of file ssl_verify_openssl.c.

References ASSERT, cert_hash_remember(), D_TLS_DEBUG, D_TLS_DEBUG_LOW, D_TLS_ERRORS, gc_free(), gc_new(), msg, mydata_index, strncpynt(), SUCCESS, tls_session::verified, verify_cert(), x509_get_sha256_fingerprint(), and x509_get_subject().

◆ verify_callback() [2/2]

int verify_callback ( void *  session_obj,
mbedtls_x509_crt *  cert,
int  cert_depth,
uint32_t flags 
)

Verify that the remote OpenVPN peer's certificate allows setting up a VPN tunnel.

This callback function is called when a new TLS session is being setup to determine whether the remote OpenVPN peer's certificate is allowed to connect. It is called for once for every certificate in the chain. The callback functionality is configured in the init_ssl() function, which calls the mbed TLS library's ssl_set_verify_callback() function with verify_callback() as its callback argument.

It checks *flags and registers the certificate hash. If these steps succeed, it calls the verify_cert() function, which performs OpenVPN-specific verification.

Parameters
session_obj- The OpenVPN tls_session associated with this object, as set during SSL session setup.
cert- The certificate used by mbed TLS.
cert_depth- The depth of the current certificate in the chain, with 0 being the actual certificate.
flags- Whether the remote OpenVPN peer's certificate passed verification. A value of 0 means it verified successfully, any other value means it failed. verify_callback() is considered to have ok'ed this certificate if flags is 0 when it returns.
Returns
The return value is 0 unless a fatal error occurred.

Referenced by tls_ctx_set_options().