summaryrefslogtreecommitdiffstats
path: root/ssl.c
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2008-09-08 03:52:52 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2008-09-08 03:52:52 +0000
commit1c4af9eaf53a16b30b25a052bebded816191bf76 (patch)
treeed1fb38ad1614fb7489ff4ee8c25ee8779e6e30c /ssl.c
parentb4b5c311d376cd499dfeea146f0b448910700562 (diff)
downloadopenvpn-1c4af9eaf53a16b30b25a052bebded816191bf76.tar.gz
openvpn-1c4af9eaf53a16b30b25a052bebded816191bf76.tar.xz
openvpn-1c4af9eaf53a16b30b25a052bebded816191bf76.zip
Fixed bug in intra-session TLS key rollover that was introduced with
deferred authentication features in 2.1_rc8. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3316 e7ae566f-a301-0410-adde-c780ea21d3b5
Diffstat (limited to 'ssl.c')
-rw-r--r--ssl.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/ssl.c b/ssl.c
index f627999..7874611 100644
--- a/ssl.c
+++ b/ssl.c
@@ -3439,6 +3439,14 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
return false;
}
+static int
+auth_deferred_expire_window (const struct tls_options *o)
+{
+ const int hw = o->handshake_window;
+ const int r2 = o->renegotiate_seconds / 2;
+ return min_int (hw, r2);
+}
+
/*
* This is the primary routine for processing TLS stuff inside the
* the main event loop. When this routine exits
@@ -3519,7 +3527,8 @@ tls_process (struct tls_multi *multi,
buf = reliable_get_buf_output_sequenced (ks->send_reliable);
if (buf)
{
- ks->auth_deferred_expire = ks->must_negotiate = now + session->opt->handshake_window;
+ ks->must_negotiate = now + session->opt->handshake_window;
+ ks->auth_deferred_expire = now + auth_deferred_expire_window (session->opt);
/* null buffer */
reliable_mark_active_outgoing (ks->send_reliable, buf, ks->initial_opcode);
@@ -4084,8 +4093,8 @@ tls_pre_decrypt (struct tls_multi *multi,
ASSERT (buf_advance (buf, 1));
++ks->n_packets;
ks->n_bytes += buf->len;
- dmsg (D_TLS_DEBUG,
- "TLS: data channel, key_id=%d, IP=%s",
+ dmsg (D_TLS_KEYSELECT,
+ "TLS: tls_pre_decrypt, key_id=%d, IP=%s",
key_id, print_link_socket_actual (from, &gc));
gc_free (&gc);
return ret;
@@ -4592,6 +4601,7 @@ tls_pre_encrypt (struct tls_multi *multi,
if (buf->len > 0)
{
int i;
+ struct key_state *ks_select = NULL;
for (i = 0; i < KEY_SCAN_SIZE; ++i)
{
struct key_state *ks = multi->key_scan[i];
@@ -4600,25 +4610,36 @@ tls_pre_encrypt (struct tls_multi *multi,
#ifdef ENABLE_DEF_AUTH
&& !ks->auth_deferred
#endif
- && (!ks->key_id || now >= ks->auth_deferred_expire))
+ )
{
- 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;
- multi->save_ks = ks;
- dmsg (D_TLS_DEBUG, "TLS: tls_pre_encrypt: key_id=%d", ks->key_id);
- return;
+ if (!ks_select)
+ ks_select = ks;
+ if (now >= ks->auth_deferred_expire)
+ {
+ ks_select = ks;
+ break;
+ }
}
}
- {
- struct gc_arena gc = gc_new ();
- dmsg (D_TLS_NO_SEND_KEY, "TLS Warning: no data channel send key available: %s",
- print_key_id (multi, &gc));
- gc_free (&gc);
- }
+ 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;
+ multi->save_ks = ks_select;
+ dmsg (D_TLS_KEYSELECT, "TLS: tls_pre_encrypt: key_id=%d", ks_select->key_id);
+ return;
+ }
+ else
+ {
+ struct gc_arena gc = gc_new ();
+ dmsg (D_TLS_KEYSELECT, "TLS Warning: no data channel send key available: %s",
+ print_key_id (multi, &gc));
+ gc_free (&gc);
+ }
}
buf->len = 0;