{
struct context_buffers *b = c->c2.buffers;
const uint8_t *orig_buf = c->c2.buf.data;
+ struct crypto_options *co = NULL;
#if P2MP_SERVER
/*
*/
if (c->c2.tls_multi)
{
- tls_pre_encrypt (c->c2.tls_multi, &c->c2.buf, &c->c2.crypto_options);
+ tls_pre_encrypt (c->c2.tls_multi, &c->c2.buf, &co);
+ }
+ else
+ {
+ co = &c->c2.crypto_options;
}
/*
* Encrypt the packet and write an optional
* HMAC signature.
*/
- openvpn_encrypt (&c->c2.buf, b->encrypt_buf, &c->c2.crypto_options, &c->c2.frame);
+ openvpn_encrypt (&c->c2.buf, b->encrypt_buf, co, &c->c2.frame);
#endif
/*
* Get the address we will be sending the packet to.
*/
if (c->c2.buf.len > 0)
{
+ struct crypto_options *co = NULL;
if (!link_socket_verify_incoming_addr (&c->c2.buf, lsi, &c->c2.from))
link_socket_bad_incoming_addr (&c->c2.buf, lsi, &c->c2.from);
* will load crypto_options with the correct encryption key
* and return false.
*/
- if (tls_pre_decrypt (c->c2.tls_multi, &c->c2.from, &c->c2.buf, &c->c2.crypto_options, floated))
+ if (tls_pre_decrypt (c->c2.tls_multi, &c->c2.from, &c->c2.buf, &co, floated))
{
interval_action (&c->c2.tmp_int);
event_timeout_reset (&c->c2.ping_rec_interval);
}
}
+ else
+ {
+ co = &c->c2.crypto_options;
+ }
#if P2MP_SERVER
/*
* Drop non-TLS packet if client-connect script/plugin has not
#endif
/* authenticate and decrypt the incoming packet */
- decrypt_status = openvpn_decrypt (&c->c2.buf, c->c2.buffers->decrypt_buf, &c->c2.crypto_options, &c->c2.frame);
+ decrypt_status = openvpn_decrypt (&c->c2.buf, c->c2.buffers->decrypt_buf, co, &c->c2.frame);
if (!decrypt_status && link_socket_connection_oriented (c->c2.link_socket))
{
packet_id_persist_load (&c->c1.pid_persist, c->options.packet_id_file);
}
- /* Initialize crypto options */
-
- if (c->options.use_iv)
- c->c2.crypto_options.flags |= CO_USE_IV;
-
- if (c->options.mute_replay_warnings)
- c->c2.crypto_options.flags |= CO_MUTE_REPLAY_WARNINGS;
-
#ifdef ENABLE_PREDICTION_RESISTANCE
if (c->options.use_prediction_resistance)
rand_ctx_enable_prediction_resistance();
init_crypto_pre (c, flags);
+ /* Initialize flags */
+ if (c->options.use_iv)
+ c->c2.crypto_options.flags |= CO_USE_IV;
+
+ if (c->options.mute_replay_warnings)
+ c->c2.crypto_options.flags |= CO_MUTE_REPLAY_WARNINGS;
+
/* Initialize packet ID tracking */
if (options->replay)
{
/* Set all command-line TLS-related options */
CLEAR (to);
+ if (options->use_iv)
+ to.crypto_flags |= CO_USE_IV;
+
+ if (options->mute_replay_warnings)
+ to.crypto_flags |= CO_MUTE_REPLAY_WARNINGS;
+
to.crypto_flags_and = ~(CO_PACKET_ID_LONG_FORM);
if (packet_id_long_form)
to.crypto_flags_or = CO_PACKET_ID_LONG_FORM;
session->opt->replay_time,
"SSL", ks->key_id);
+ ks->crypto_options.key_ctx_bi = &ks->key;
+ ks->crypto_options.packet_id = session->opt->replay ? &ks->packet_id : NULL;
+ 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++;
#endif
ks->must_die = now + session->opt->transition_window; /* remaining lifetime of old key */
key_state_free (ks_lame, false);
*ks_lame = *ks;
+ ks_lame->crypto_options.key_ctx_bi = &ks_lame->key;
+ ks_lame->crypto_options.packet_id = &ks_lame->packet_id;
key_state_init (session, ks);
ks->session_id_remote = ks_lame->session_id_remote;
tls_pre_decrypt (struct tls_multi *multi,
const struct link_socket_actual *from,
struct buffer *buf,
- struct crypto_options *opt,
+ struct crypto_options **opt,
bool floated)
{
struct gc_arena gc = gc_new ();
&& (floated || 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)
{
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;
/* 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)
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;
}
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 */
* of this packet.
* @param from - The source address of the packet.
* @param buf - A buffer structure containing the incoming packet.
- * @param opt - A crypto options structure that will be loaded with the
- * appropriate security parameters to handle the packet if it is a
- * data channel packet.
+ * @param opt - Returns a crypto options structure with the appropriate security
+ * parameters to handle the packet if it is a data channel packet.
*
* @return
* @li True if the packet is a control channel packet that has been
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,
bool floated);
* @ingroup data_crypto
*
* If no appropriate security parameters can be found, or if some other
- * error occurs, then the buffer is set to empty.
+ * error occurs, then the buffer is set to empty, and the parameters to a NULL
+ * pointer.
*
* @param multi - The TLS state for this packet's destination VPN tunnel.
* @param buf - The buffer containing the outgoing packet.
- * @param opt - The crypto options structure into which the appropriate
- * security parameters should be loaded.
+ * @param opt - Returns a crypto options structure with the security parameters.
*/
void tls_pre_encrypt (struct tls_multi *multi,
- struct buffer *buf, struct crypto_options *opt);
+ struct buffer *buf, struct crypto_options **opt);
/**
struct link_socket_actual remote_addr; /* peer's IP addr */
struct packet_id packet_id; /* for data channel, to prevent replay attacks */
+ struct crypto_options crypto_options;/* data channel crypto options */
struct key_ctx_bi key; /* data channel keys for encrypt/decrypt/hmac */
struct key_source2 *key_src; /* source entropy for key expansion */
bool pass_config_info;
/* struct crypto_option flags */
+ unsigned int crypto_flags;
unsigned int crypto_flags_and;
unsigned int crypto_flags_or;