OpenVPN
|
#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>
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" |
#define AUTH_TOKEN_SESSION_ID_BASE64_LEN (AUTH_TOKEN_SESSION_ID_LEN * 8 / 6) |
Definition at line 22 of file auth_token.c.
#define AUTH_TOKEN_SESSION_ID_LEN 12 |
Definition at line 21 of file auth_token.c.
#define TOKEN_DATA_LEN (2 * sizeof(int64_t) + AUTH_TOKEN_SESSION_ID_LEN + 32) |
Definition at line 29 of file auth_token.c.
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.
Definition at line 38 of file auth_token.c.
References ASSERT, AUTH_TOKEN_EXPIRED, tls_options::auth_token_generate, AUTH_TOKEN_HMAC_OK, tls_multi::auth_token_initial, AUTH_TOKEN_SESSION_ID_LEN, AUTH_TOKEN_VALID_EMPTYUSER, generate_auth_token(), is_auth_token(), session::key, KS_PRIMARY, tls_multi::opt, user_pass::password, SESSION_ID_PREFIX, and setenv_str().
Referenced by auth_token_test_env(), and set_verify_user_pass_env().
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().
|
static |
Definition at line 32 of file auth_token.c.
References create_kt().
Referenced by auth_token_init_secret(), and setup().
void auth_token_write_server_key_file | ( | const char * | filename | ) |
Generate a auth-token server secret key, and write to file.
filename | Filename 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().
|
static |
Definition at line 281 of file auth_token.c.
References ASSERT, hmac_ctx_final(), hmac_ctx_reset(), hmac_ctx_size(), hmac_ctx_update(), memcmp_constant_time(), and TOKEN_DATA_LEN.
Referenced by verify_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 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().
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.
multi | Pointer the multi object of the TLS session |
session | Pointer 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().
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.
Definition at line 297 of file auth_token.c.
References auth_set_client_reason(), AUTH_TOKEN_EXPIRED, AUTH_TOKEN_HMAC_OK, tls_multi::auth_token_initial, tls_options::auth_token_key, tls_options::auth_token_lifetime, AUTH_TOKEN_SESSION_ID_BASE64_LEN, AUTH_TOKEN_SESSION_ID_LEN, AUTH_TOKEN_VALID_EMPTYUSER, check_hmac_token(), key_ctx::hmac, M_INFO, M_WARN, memcmp_constant_time(), msg, now, ntohll, openvpn_base64_decode(), tls_multi::opt, user_pass::password, SESSION_ID_PREFIX, TOKEN_DATA_LEN, USER_PASS_LEN, and user_pass::username.
Referenced by auth_token_basic_test(), auth_token_fail_invalid_key(), auth_token_test_empty_user(), auth_token_test_key_load(), auth_token_test_known_keys(), auth_token_test_random_keys(), auth_token_test_session_mismatch(), auth_token_test_timeout(), and verify_user_pass().
void wipe_auth_token | ( | struct tls_multi * | multi | ) |
Wipes the authentication token out of the memory, frees and cleans up related buffers and flags.
multi | Pointer 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().
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().