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 | 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 24 of file auth_token.c.
Referenced by auth_token_test_session_mismatch(), and verify_auth_token().
#define AUTH_TOKEN_SESSION_ID_LEN 12 |
Definition at line 23 of file auth_token.c.
Referenced by add_session_token_env(), generate_auth_token(), verify_auth_token(), and zerohmac().
#define TOKEN_DATA_LEN (2 * sizeof(int64_t) + AUTH_TOKEN_SESSION_ID_LEN + 32) |
Definition at line 31 of file auth_token.c.
Referenced by check_hmac_token(), and verify_auth_token().
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 54 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, key_state::auth_token_state_flags, AUTH_TOKEN_VALID_EMPTYUSER, tls_options::es, generate_auth_token(), is_auth_token(), tls_session::key, KS_PRIMARY, tls_session::opt, 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 140 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 34 of file auth_token.c.
References key_type::cipher, key_type::digest, key_type::hmac_length, M_WARN, md_kt_get(), md_kt_size(), and msg.
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 134 of file auth_token.c.
References auth_token_pem_name, and write_pem_key_file().
Referenced by do_genkey().
|
static |
Definition at line 297 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().
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 * renogiation 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/managment can track the session multiple reconnects/servers. It is delibrately chosen be a multiple of 3 bytes to have a base64 encoding without padding.
The hmac is calculated over the username contactinated 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 177 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, free, 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(), 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 432 of file auth_token.c.
References tls_multi::auth_token_initial, tls_session::key, key_state::key_id, KS_PRIMARY, and send_push_reply_auth_token().
Referenced by is_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 313 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_session::opt, tls_multi::opt, user_pass::password, PRIu64, tls_options::renegotiate_seconds, 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 411 of file auth_token.c.
References tls_multi::auth_token, tls_multi::auth_token_initial, free, 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 21 of file auth_token.c.
Referenced by auth_token_init_secret(), and auth_token_write_server_key_file().