OpenVPN
Macros | Functions | Variables
auth_token.c File Reference
#include "syshead.h"
#include "base64.h"
#include "buffer.h"
#include "crypto.h"
#include "openvpn.h"
#include "ssl_common.h"
#include "auth_token.h"
#include "push.h"
#include "integer.h"
#include "ssl.h"
#include "ssl_verify.h"
#include <inttypes.h>
Include dependency graph for auth_token.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define AUTH_TOKEN_SESSION_ID_LEN   12
 
#define AUTH_TOKEN_SESSION_ID_BASE64_LEN   (AUTH_TOKEN_SESSION_ID_LEN * 8 / 6)
 
#define TOKEN_DATA_LEN   (2 * sizeof(int64_t) + AUTH_TOKEN_SESSION_ID_LEN + 32)
 

Functions

static struct key_type auth_token_kt (void)
 
void add_session_token_env (struct tls_session *session, struct tls_multi *multi, const struct user_pass *up)
 Put the session id, and auth token status into the environment if auth-token is enabled. More...
 
void auth_token_write_server_key_file (const char *filename)
 Generate a auth-token server secret key, and write to file. More...
 
void auth_token_init_secret (struct key_ctx *key_ctx, const char *key_file, bool key_inline)
 Loads an HMAC secret from a file or if no file is present generates a epheremal secret for the run time of the server and stores it into ctx. More...
 
void generate_auth_token (const struct user_pass *up, struct tls_multi *multi)
 Generate an auth token based on username and timestamp. More...
 
static bool check_hmac_token (hmac_ctx_t *ctx, const uint8_t *b64decoded, const char *username)
 
unsigned int verify_auth_token (struct user_pass *up, struct tls_multi *multi, struct tls_session *session)
 Verifies the auth token to be in the format that generate_auth_token create and checks if the token is valid. More...
 
void wipe_auth_token (struct tls_multi *multi)
 Wipes the authentication token out of the memory, frees and cleans up related buffers and flags. More...
 
void check_send_auth_token (struct context *c)
 Checks if the timer to resend the auth-token has expired and if a new auth-token should be send to the client and triggers the resending. More...
 
void resend_auth_token_renegotiation (struct tls_multi *multi, struct tls_session *session)
 Checks if a client should be sent a new auth token to update its current auth-token. More...
 

Variables

const char * auth_token_pem_name = "OpenVPN auth-token server key"
 

Macro Definition Documentation

◆ AUTH_TOKEN_SESSION_ID_BASE64_LEN

#define AUTH_TOKEN_SESSION_ID_BASE64_LEN   (AUTH_TOKEN_SESSION_ID_LEN * 8 / 6)

Definition at line 22 of file auth_token.c.

◆ AUTH_TOKEN_SESSION_ID_LEN

#define AUTH_TOKEN_SESSION_ID_LEN   12

Definition at line 21 of file auth_token.c.

◆ TOKEN_DATA_LEN

#define TOKEN_DATA_LEN   (2 * sizeof(int64_t) + AUTH_TOKEN_SESSION_ID_LEN + 32)

Definition at line 29 of file auth_token.c.

Function Documentation

◆ add_session_token_env()

void add_session_token_env ( struct tls_session session,
struct tls_multi multi,
const struct user_pass up 
)

◆ auth_token_init_secret()

void auth_token_init_secret ( struct key_ctx key_ctx,
const char *  key_file,
bool  key_inline 
)

Loads an HMAC secret from a file or if no file is present generates a epheremal secret for the run time of the server and stores it into ctx.

Definition at line 124 of file auth_token.c.

References alloc_buf(), auth_token_kt(), auth_token_pem_name, buf_read(), free_buf(), generate_ephemeral_key(), init_key_ctx(), M_FATAL, msg, and read_pem_key_file().

Referenced by auth_token_test_key_load(), auth_token_test_random_keys(), and do_init_crypto_tls_c1().

◆ auth_token_kt()

static struct key_type auth_token_kt ( void  )
static

Definition at line 32 of file auth_token.c.

References create_kt().

Referenced by auth_token_init_secret(), and setup().

◆ auth_token_write_server_key_file()

void auth_token_write_server_key_file ( const char *  filename)

Generate a auth-token server secret key, and write to file.

Parameters
filenameFilename of the server key file to create.

Definition at line 118 of file auth_token.c.

References auth_token_pem_name, and write_pem_key_file().

Referenced by do_genkey().

◆ check_hmac_token()

static bool check_hmac_token ( hmac_ctx_t ctx,
const uint8_t *  b64decoded,
const char *  username 
)
static

◆ check_send_auth_token()

void check_send_auth_token ( struct context c)

Checks if the timer to resend the auth-token has expired and if a new auth-token should be send to the client and triggers the resending.

Definition at line 424 of file auth_token.c.

References tls_multi::auth_token_initial, context::c2, D_SHOW_KEYS, generate_auth_token(), get_primary_key(), KS_AUTH_TRUE, tls_multi::locked_username, msg, resend_auth_token_renegotiation(), S_GENERATED_KEYS, tls_multi::session, strncpynt(), context_2::tls_multi, TM_ACTIVE, and user_pass::username.

Referenced by process_coarse_timers().

◆ generate_auth_token()

void generate_auth_token ( const struct user_pass up,
struct tls_multi multi 
)

Generate an auth token based on username and timestamp.

The idea of auth token is to be stateless, so that we can verify use it even after we have forgotten about it or server has been restarted.

To achieve this even though we cannot trust the client we use HMAC to be able to verify the information.

Format of the auth-token (before base64 encode)

session id(12 bytes)|uint64 timestamp (8 bytes)| uint64 timestamp (8 bytes)|sha256-hmac(32 bytes)

The first timestamp is the time the token was initially created and is used to determine the maximum renewable time of the token. We always include this even if tokens do not expire (this value is not used) to keep the code cleaner.

The second timestamp is the time the token was renewed/regenerated and is used to determine if this token has been renewed in the acceptable time range (2 * renegotiation timeout)

The session id is a random string of 12 byte (or 16 in base64) that is not used by OpenVPN itself but kept intact so that external logging/management can track the session multiple reconnects/servers. It is deliberately chosen be a multiple of 3 bytes to have a base64 encoding without padding.

The hmac is calculated over the username concatenated with the raw auth-token bytes to include authentication of the username in the token

We encode the auth-token with base64 and then prepend "SESS_ID_" before sending it to the client.

This function will free() an existing multi->auth_token and keep the existing initial timestamp and session id contained in that token.

Definition at line 161 of file auth_token.c.

References alloc_buf_gc(), ASSERT, tls_multi::auth_token, tls_multi::auth_token_initial, tls_options::auth_token_key, AUTH_TOKEN_SESSION_ID_LEN, key_state::auth_token_state_flags, AUTH_TOKEN_VALID_EMPTYUSER, BLEN, BPTR, buf_write(), buf_write_u8(), D_SHOW_KEYS, dmsg, gc_free(), gc_new(), key_ctx::hmac, hmac_ctx_final(), hmac_ctx_reset(), hmac_ctx_size(), hmac_ctx_update(), htonll, tls_session::key, KS_PRIMARY, M_FATAL, msg, now, openvpn_base64_decode(), openvpn_base64_encode(), tls_multi::opt, rand_bytes(), tls_multi::session, SESSION_ID_PREFIX, string_alloc(), TM_ACTIVE, and user_pass::username.

Referenced by add_session_token_env(), auth_token_basic_test(), auth_token_fail_invalid_key(), auth_token_test_empty_user(), auth_token_test_known_keys(), auth_token_test_random_keys(), auth_token_test_session_mismatch(), auth_token_test_timeout(), check_send_auth_token(), and verify_user_pass().

◆ resend_auth_token_renegotiation()

void resend_auth_token_renegotiation ( struct tls_multi multi,
struct tls_session session 
)

Checks if a client should be sent a new auth token to update its current auth-token.

Parameters
multiPointer the multi object of the TLS session
sessionPointer to the TLS session itself

Definition at line 462 of file auth_token.c.

References tls_multi::auth_token_initial, and send_push_reply_auth_token().

Referenced by check_send_auth_token(), and tls_multi_process().

◆ verify_auth_token()

unsigned int verify_auth_token ( struct user_pass up,
struct tls_multi multi,
struct tls_session session 
)

◆ wipe_auth_token()

void wipe_auth_token ( struct tls_multi multi)

Wipes the authentication token out of the memory, frees and cleans up related buffers and flags.

Parameters
multiPointer to a multi object holding the auth_token variables

Definition at line 403 of file auth_token.c.

References tls_multi::auth_token, tls_multi::auth_token_initial, and secure_memzero().

Referenced by auth_token_test_session_mismatch(), teardown(), tls_deauthenticate(), tls_multi_free(), verify_final_auth_checks(), and verify_user_pass().

Variable Documentation

◆ auth_token_pem_name

const char* auth_token_pem_name = "OpenVPN auth-token server key"

Definition at line 19 of file auth_token.c.

Referenced by auth_token_init_secret(), and auth_token_write_server_key_file().