summaryrefslogtreecommitdiff
path: root/main/openvpn/src/openvpn/ssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/openvpn/src/openvpn/ssl.c')
-rw-r--r--main/openvpn/src/openvpn/ssl.c167
1 files changed, 100 insertions, 67 deletions
diff --git a/main/openvpn/src/openvpn/ssl.c b/main/openvpn/src/openvpn/ssl.c
index e1e0f31d..103a5114 100644
--- a/main/openvpn/src/openvpn/ssl.c
+++ b/main/openvpn/src/openvpn/ssl.c
@@ -454,7 +454,7 @@ ssl_put_auth_challenge (const char *cr_str)
* return tls_version_max().
*/
int
-tls_version_min_parse(const char *vstr, const char *extra)
+tls_version_parse(const char *vstr, const char *extra)
{
const int max_version = tls_version_max();
if (!strcmp(vstr, "1.0") && TLS_VER_1_0 <= max_version)
@@ -483,7 +483,10 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
if (options->tls_server)
{
tls_ctx_server_new(new_ctx);
- tls_ctx_load_dh_params(new_ctx, options->dh_file, options->dh_file_inline);
+
+ if (options->dh_file)
+ tls_ctx_load_dh_params(new_ctx, options->dh_file,
+ options->dh_file_inline);
}
else /* if client */
{
@@ -761,11 +764,17 @@ key_state_init (struct tls_session *session, struct key_state *ks)
reliable_set_timeout (ks->send_reliable, session->opt->packet_timeout);
/* init packet ID tracker */
- packet_id_init (&ks->packet_id,
- session->opt->tcp_mode,
- session->opt->replay_window,
- session->opt->replay_time,
- "SSL", ks->key_id);
+ if (session->opt->replay)
+ {
+ packet_id_init (&ks->crypto_options.packet_id, session->opt->tcp_mode,
+ session->opt->replay_window, session->opt->replay_time, "SSL",
+ ks->key_id);
+ }
+
+ ks->crypto_options.pid_persist = NULL;
+ ks->crypto_options.flags = session->opt->crypto_flags;
+ ks->crypto_options.flags &= session->opt->crypto_flags_and;
+ ks->crypto_options.flags |= session->opt->crypto_flags_or;
#ifdef MANAGEMENT_DEF_AUTH
ks->mda_key_id = session->opt->mda_context->mda_key_id_counter++;
@@ -793,7 +802,7 @@ key_state_free (struct key_state *ks, bool clear)
key_state_ssl_free(&ks->ks_ssl);
- free_key_ctx_bi (&ks->key);
+ free_key_ctx_bi (&ks->crypto_options.key_ctx_bi);
free_buf (&ks->plaintext_read_buf);
free_buf (&ks->plaintext_write_buf);
free_buf (&ks->ack_write_buf);
@@ -817,7 +826,7 @@ key_state_free (struct key_state *ks, bool clear)
if (ks->key_src)
free (ks->key_src);
- packet_id_free (&ks->packet_id);
+ packet_id_free (&ks->crypto_options.packet_id);
#ifdef PLUGIN_DEF_AUTH
key_state_rm_auth_control_file (ks);
@@ -832,13 +841,6 @@ key_state_free (struct key_state *ks, bool clear)
/** @} addtogroup control_processor */
-/*
- * Must be called if we move a tls_session in memory.
- */
-static inline void tls_session_set_self_referential_pointers (struct tls_session* session) {
- session->tls_auth.packet_id = &session->tls_auth_pid;
-}
-
/**
* Returns whether or not the server should check for username/password
*
@@ -911,18 +913,15 @@ tls_session_init (struct tls_multi *multi, struct tls_session *session)
/* Initialize control channel authentication parameters */
session->tls_auth = session->opt->tls_auth;
- /* Set session internal pointers (also called if session object is moved in memory) */
- tls_session_set_self_referential_pointers (session);
-
/* initialize packet ID replay window for --tls-auth */
- packet_id_init (session->tls_auth.packet_id,
+ packet_id_init (&session->tls_auth.packet_id,
session->opt->tcp_mode,
session->opt->replay_window,
session->opt->replay_time,
"TLS_AUTH", session->key_id);
/* load most recent packet-id to replay protect on --tls-auth */
- packet_id_persist_load_obj (session->tls_auth.pid_persist, session->tls_auth.packet_id);
+ packet_id_persist_load_obj (session->tls_auth.pid_persist, &session->tls_auth.packet_id);
key_state_init (session, &session->key[KS_PRIMARY]);
@@ -949,8 +948,8 @@ tls_session_free (struct tls_session *session, bool clear)
{
int i;
- if (session->tls_auth.packet_id)
- packet_id_free (session->tls_auth.packet_id);
+ if (packet_id_initialized(&session->tls_auth.packet_id))
+ packet_id_free (&session->tls_auth.packet_id);
for (i = 0; i < KS_SIZE; ++i)
key_state_free (&session->key[i], false);
@@ -981,7 +980,6 @@ move_session (struct tls_multi* multi, int dest, int src, bool reinit_src)
ASSERT (dest >= 0 && dest < TM_SIZE);
tls_session_free (&multi->session[dest], false);
multi->session[dest] = multi->session[src];
- tls_session_set_self_referential_pointers (&multi->session[dest]);
if (reinit_src)
tls_session_init (multi, &multi->session[src]);
@@ -1046,9 +1044,6 @@ tls_multi_init (struct tls_options *tls_options)
/* get command line derived options */
ret->opt = *tls_options;
- /* set up pointer to HMAC object for TLS packet authentication */
- ret->opt.tls_auth.key_ctx_bi = &ret->opt.tls_auth_key;
-
/* set up list of keys to be scanned by data channel encrypt and decrypt routines */
ASSERT (SIZE (ret->key_scan) == 3);
ret->key_scan[0] = &ret->session[TM_ACTIVE].key[KS_PRIMARY];
@@ -1056,7 +1051,7 @@ tls_multi_init (struct tls_options *tls_options)
ret->key_scan[2] = &ret->session[TM_LAME_DUCK].key[KS_LAME_DUCK];
/* By default not use P_DATA_V2 */
- ret->use_session_id = false;
+ ret->use_peer_id = false;
return ret;
}
@@ -1087,8 +1082,7 @@ tls_auth_standalone_init (struct tls_options *tls_options,
ALLOC_OBJ_CLEAR_GC (tas, struct tls_auth_standalone, gc);
/* set up pointer to HMAC object for TLS packet authentication */
- tas->tls_auth_key = tls_options->tls_auth_key;
- tas->tls_auth_options.key_ctx_bi = &tas->tls_auth_key;
+ tas->tls_auth_options.key_ctx_bi = tls_options->tls_auth.key_ctx_bi;
tas->tls_auth_options.flags |= CO_PACKET_ID_LONG_FORM;
/* get initial frame parms, still need to finalize */
@@ -1171,11 +1165,11 @@ tls_multi_free (struct tls_multi *multi, bool clear)
static bool
swap_hmac (struct buffer *buf, const struct crypto_options *co, bool incoming)
{
- struct key_ctx *ctx;
+ const struct key_ctx *ctx;
ASSERT (co);
- ctx = (incoming ? &co->key_ctx_bi->decrypt : &co->key_ctx_bi->encrypt);
+ ctx = (incoming ? &co->key_ctx_bi.decrypt : &co->key_ctx_bi.encrypt);
ASSERT (ctx->hmac);
{
@@ -1239,7 +1233,7 @@ write_control_auth (struct tls_session *session,
ASSERT (session_id_write_prepend (&session->session_id, buf));
ASSERT (header = buf_prepend (buf, 1));
*header = ks->key_id | (opcode << P_OPCODE_SHIFT);
- if (session->tls_auth.key_ctx_bi->encrypt.hmac)
+ if (session->tls_auth.key_ctx_bi.encrypt.hmac)
{
/* no encryption, only write hmac */
openvpn_encrypt (buf, null, &session->tls_auth, NULL);
@@ -1253,12 +1247,12 @@ write_control_auth (struct tls_session *session,
*/
static bool
read_control_auth (struct buffer *buf,
- const struct crypto_options *co,
+ struct crypto_options *co,
const struct link_socket_actual *from)
{
struct gc_arena gc = gc_new ();
- if (co->key_ctx_bi->decrypt.hmac)
+ if (co->key_ctx_bi.decrypt.hmac)
{
struct buffer null = clear_buf ();
@@ -1589,6 +1583,41 @@ generate_key_expansion (struct key_ctx_bi *key,
return ret;
}
+/**
+ * Initialize the implicit IV for a key_ctx_bi based on TLS session ids and
+ * cipher used.
+ *
+ * @param keys Encrypt/decrypt key context
+ * @param cipher_kt Cipher key type info
+ * @param session_id_local The local session id for this session
+ * @param session_id_remote The remote seession id for this session
+ *
+ * @return true on success, false on failure.
+ */
+static bool
+ssl_init_implicit_iv(struct key_ctx_bi *keys, const cipher_kt_t *cipher_kt,
+ const struct session_id *session_id_local,
+ const struct session_id *session_id_remote)
+{
+ ASSERT (NULL != keys);
+ ASSERT (NULL != cipher_kt);
+ ASSERT (NULL != session_id_local);
+ ASSERT (NULL != session_id_remote);
+
+ if (cipher_kt_mode_aead(cipher_kt))
+ {
+ if (!key_ctx_set_implicit_iv(&keys->encrypt, session_id_local->id,
+ SID_SIZE))
+ return false;
+
+ if (!key_ctx_set_implicit_iv(&keys->decrypt, session_id_remote->id,
+ SID_SIZE))
+ return false;
+ }
+
+ return true;
+}
+
static bool
random_bytes_to_buf (struct buffer *buf,
uint8_t *out,
@@ -1778,8 +1807,9 @@ key_method_1_write (struct buffer *buf, struct tls_session *session)
return false;
}
- init_key_ctx (&ks->key.encrypt, &key, &session->opt->key_type,
- OPENVPN_OP_ENCRYPT, "Data Channel Encrypt");
+ init_key_ctx (&ks->crypto_options.key_ctx_bi.encrypt, &key,
+ &session->opt->key_type, OPENVPN_OP_ENCRYPT,
+ "Data Channel Encrypt");
CLEAR (key);
/* send local options string */
@@ -1935,7 +1965,7 @@ key_method_2_write (struct buffer *buf, struct tls_session *session)
{
if (ks->authenticated)
{
- if (!generate_key_expansion (&ks->key,
+ if (!generate_key_expansion (&ks->crypto_options.key_ctx_bi,
&session->opt->key_type,
ks->key_src,
&ks->session_id_remote,
@@ -1945,6 +1975,14 @@ key_method_2_write (struct buffer *buf, struct tls_session *session)
msg (D_TLS_ERRORS, "TLS Error: server generate_key_expansion failed");
goto error;
}
+
+ if (!ssl_init_implicit_iv(&ks->crypto_options.key_ctx_bi,
+ session->opt->key_type.cipher, &session->session_id,
+ &ks->session_id_remote))
+ {
+ msg (D_TLS_ERRORS, "TLS Error: initializing implicit IV failed");
+ goto error;
+ }
}
CLEAR (*ks->key_src);
@@ -2006,8 +2044,9 @@ key_method_1_read (struct buffer *buf, struct tls_session *session)
buf_clear (buf);
- init_key_ctx (&ks->key.decrypt, &key, &session->opt->key_type,
- OPENVPN_OP_DECRYPT, "Data Channel Decrypt");
+ init_key_ctx (&ks->crypto_options.key_ctx_bi.decrypt, &key,
+ &session->opt->key_type, OPENVPN_OP_DECRYPT,
+ "Data Channel Decrypt");
CLEAR (key);
ks->authenticated = true;
return true;
@@ -2147,7 +2186,7 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
*/
if (!session->opt->server)
{
- if (!generate_key_expansion (&ks->key,
+ if (!generate_key_expansion (&ks->crypto_options.key_ctx_bi,
&session->opt->key_type,
ks->key_src,
&session->session_id,
@@ -2157,6 +2196,14 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
msg (D_TLS_ERRORS, "TLS Error: client generate_key_expansion failed");
goto error;
}
+
+ if (!ssl_init_implicit_iv(&ks->crypto_options.key_ctx_bi,
+ session->opt->key_type.cipher, &session->session_id,
+ &ks->session_id_remote))
+ {
+ msg (D_TLS_ERRORS, "TLS Error: initializing implicit IV failed");
+ goto error;
+ }
CLEAR (*ks->key_src);
}
@@ -2219,7 +2266,7 @@ tls_process (struct tls_multi *multi,
&& ks->n_bytes >= session->opt->renegotiate_bytes)
|| (session->opt->renegotiate_packets
&& ks->n_packets >= session->opt->renegotiate_packets)
- || (packet_id_close_to_wrapping (&ks->packet_id.send))))
+ || (packet_id_close_to_wrapping (&ks->crypto_options.packet_id.send))))
{
msg (D_TLS_DEBUG_LOW,
"TLS: soft reset sec=%d bytes=" counter_format "/%d pkts=" counter_format "/%d",
@@ -2773,7 +2820,7 @@ bool
tls_pre_decrypt (struct tls_multi *multi,
const struct link_socket_actual *from,
struct buffer *buf,
- struct crypto_options *opt)
+ struct crypto_options **opt)
{
struct gc_arena gc = gc_new ();
bool ret = false;
@@ -2820,11 +2867,7 @@ tls_pre_decrypt (struct tls_multi *multi,
&& link_socket_actual_match (from, &ks->remote_addr))
{
/* return appropriate data channel decrypt key in opt */
- opt->key_ctx_bi = &ks->key;
- opt->packet_id = multi->opt.replay ? &ks->packet_id : NULL;
- opt->pid_persist = NULL;
- opt->flags &= multi->opt.crypto_flags_and;
- opt->flags |= multi->opt.crypto_flags_or;
+ *opt = &ks->crypto_options;
ASSERT (buf_advance (buf, 1));
if (op == P_DATA_V2) {
@@ -3206,10 +3249,7 @@ tls_pre_decrypt (struct tls_multi *multi,
done:
buf->len = 0;
- opt->key_ctx_bi = NULL;
- opt->packet_id = NULL;
- opt->pid_persist = NULL;
- opt->flags &= multi->opt.crypto_flags_and;
+ *opt = NULL;
gc_free (&gc);
return ret;
@@ -3336,7 +3376,7 @@ tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
/* Choose the key with which to encrypt a data packet */
void
tls_pre_encrypt (struct tls_multi *multi,
- struct buffer *buf, struct crypto_options *opt)
+ struct buffer *buf, struct crypto_options **opt)
{
multi->save_ks = NULL;
if (buf->len > 0)
@@ -3365,11 +3405,7 @@ tls_pre_encrypt (struct tls_multi *multi,
if (ks_select)
{
- opt->key_ctx_bi = &ks_select->key;
- opt->packet_id = multi->opt.replay ? &ks_select->packet_id : NULL;
- opt->pid_persist = NULL;
- opt->flags &= multi->opt.crypto_flags_and;
- opt->flags |= multi->opt.crypto_flags_or;
+ *opt = &ks_select->crypto_options;
multi->save_ks = ks_select;
dmsg (D_TLS_KEYSELECT, "TLS: tls_pre_encrypt: key_id=%d", ks_select->key_id);
return;
@@ -3384,10 +3420,7 @@ tls_pre_encrypt (struct tls_multi *multi,
}
buf->len = 0;
- opt->key_ctx_bi = NULL;
- opt->packet_id = NULL;
- opt->pid_persist = NULL;
- opt->flags &= multi->opt.crypto_flags_and;
+ *opt = NULL;
}
/* Prepend the appropriate opcode to encrypted buffer prior to TCP/UDP send */
@@ -3396,7 +3429,7 @@ tls_post_encrypt (struct tls_multi *multi, struct buffer *buf)
{
struct key_state *ks;
uint8_t *op;
- uint32_t sess;
+ uint32_t peer;
ks = multi->save_ks;
multi->save_ks = NULL;
@@ -3404,10 +3437,10 @@ tls_post_encrypt (struct tls_multi *multi, struct buffer *buf)
{
ASSERT (ks);
- if (!multi->opt.server && multi->use_session_id)
+ if (!multi->opt.server && multi->use_peer_id)
{
- sess = htonl(((P_DATA_V2 << P_OPCODE_SHIFT) | ks->key_id) << 24 | (multi->vpn_session_id & 0xFFFFFF));
- ASSERT (buf_write_prepend (buf, &sess, 4));
+ peer = htonl(((P_DATA_V2 << P_OPCODE_SHIFT) | ks->key_id) << 24 | (multi->peer_id & 0xFFFFFF));
+ ASSERT (buf_write_prepend (buf, &peer, 4));
}
else
{
@@ -3497,7 +3530,7 @@ const struct link_socket_actual *from)
for (i = 0; i < KEY_SCAN_SIZE; ++i)
{
struct key_state *ks = multi->key_scan[i];
- if (DECRYPT_KEY_ENABLED (multi, ks) && ks->authenticated && link_socket_actual_defined(&ks->remote_addr))
+ if (DECRYPT_KEY_ENABLED (multi, ks) && ks->authenticated && link_socket_actual_defined(&ks->remote_addr))
{
if (link_socket_actual_match (from, &ks->remote_addr))
continue;