---
 src/openvpn/init.c | 128 +++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 91 insertions(+), 37 deletions(-)

diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 2beec72..d21a862 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -60,6 +60,13 @@ static struct context *static_context; /* GLOBAL */
 #define CF_INIT_TLS_AUTH_STANDALONE (1<<2)

 static void do_init_first_time (struct context *c);
+static void do_init_buffers(struct context *c); 
+static void do_init_tls_multi(struct context *c, const unsigned int flags, 
bool packet_id_long_format);
+static void do_init_frame(struct context *c); 
+static void do_init_frame_tls(struct context *c); 
+static void do_compute_occ_strings(struct context *c); 
+
+

 void
 context_clear (struct context *c)
@@ -1795,6 +1802,7 @@ pull_permission_mask (const struct context *c)
     | OPT_P_SHAPER
     | OPT_P_TIMER
     | OPT_P_COMP
+    | OPT_P_CRYPTO
     | OPT_P_PERSIST
     | OPT_P_MESSAGES
     | OPT_P_EXPLICIT_NOTIFY
@@ -1879,6 +1887,44 @@ do_deferred_options (struct context *c, const unsigned 
int found)
     msg (D_PUSH, "OPTIONS IMPORT: environment modified");

 #ifdef ENABLE_CRYPTO
+  if (found & OPT_P_CRYPTO)
+    {    
+      const struct options *options = &c->options;
+      struct key_type *kt = &c->c1.ks.key_type;
+      /* Save the old crypto length so that we recalculate the extra frame/mtu 
parameters c*/
+      unsigned int old_crypto_length = kt->cipher_length + kt->hmac_length;
+
+      msg (D_PUSH, "OPTIONS IMPORT: crypto options modified");
+
+      /* Update cipher & hash algorithms */
+      init_key_type (kt, options->ciphername,
+                      options->ciphername_defined, options->authname,
+                      options->authname_defined, options->keysize, true, true);
+
+      /* Sanity check on IV, sequence number, and cipher mode options */
+      check_replay_iv_consistency (kt, options->replay, options->use_iv);
+
+      /* In short form, unique datagram identifier is 32 bits, in long form 64 
bits */
+      bool packet_id_long_form = cipher_kt_mode_ofb_cfb (kt->cipher);
+
+      do_init_tls_multi(c, CF_INIT_TLS_MULTI, packet_id_long_form);
+
+      /* Recalculate MTU parameters */
+      frame_add_to_extra_frame(&c->c2.frame, kt->cipher_length + 
kt->hmac_length - old_crypto_length);
+      frame_add_to_link_mtu(&c->c2.frame, kt->cipher_length + kt->hmac_length 
- old_crypto_length);
+
+      do_init_frame_tls(c);
+
+      frame_print(&c->c2.frame, M_WARN, "New data channel");
+      frame_print(&c->c2.tls_multi->opt.frame, M_WARN, "New control channel");
+
+      /* Reallocate the context buffers to adjust for the new frame size */
+      free_context_buffers (c->c2.buffers);
+      do_init_buffers(c);
+
+      do_compute_occ_strings(c);
+    }    
+
   if (found & OPT_P_PEER_ID)
     {
       msg (D_PUSH, "OPTIONS IMPORT: peer-id set");
@@ -2222,39 +2268,10 @@ do_init_crypto_tls_c1 (struct context *c)
 }

 static void
-do_init_crypto_tls (struct context *c, const unsigned int flags)
+do_init_tls_multi(struct context *c, const unsigned int flags, bool 
packet_id_long_form)
 {
   const struct options *options = &c->options;
   struct tls_options to;
-  bool packet_id_long_form;
-
-  ASSERT (options->tls_server || options->tls_client);
-  ASSERT (!options->test_crypto);
-
-  init_crypto_pre (c, flags);
-
-  /* Make sure we are either a TLS client or server but not both */
-  ASSERT (options->tls_server == !options->tls_client);
-
-  /* initialize persistent component */
-  do_init_crypto_tls_c1 (c);
-  if (IS_SIG (c))
-    return;
-
-  /* Sanity check on IV, sequence number, and cipher mode options */
-  check_replay_iv_consistency (&c->c1.ks.key_type, options->replay,
-                              options->use_iv);
-
-  /* In short form, unique datagram identifier is 32 bits, in long form 64 
bits */
-  packet_id_long_form = cipher_kt_mode_ofb_cfb (c->c1.ks.key_type.cipher);
-
-  /* Compute MTU parameters */
-  crypto_adjust_frame_parameters (&c->c2.frame,
-                                 &c->c1.ks.key_type,
-                                 options->ciphername_defined,
-                                 options->use_iv,
-                                 options->replay, packet_id_long_form);
-  tls_adjust_frame_parameters (&c->c2.frame);

   /* Set all command-line TLS-related options */
   CLEAR (to);
@@ -2279,11 +2296,11 @@ do_init_crypto_tls (struct context *c, const unsigned 
int flags)
   to.renegotiate_seconds = options->renegotiate_seconds;
   to.single_session = options->single_session;
 #ifdef ENABLE_PUSH_PEER_INFO
-  if (options->push_peer_info)         /* all there is */
+  if (options->push_peer_info)      /* all there is */
     to.push_peer_info_detail = 2;
-  else if (options->pull)              /* pull clients send some details */
+  else if (options->pull)       /* pull clients send some details */
     to.push_peer_info_detail = 1;
-  else                                 /* default: no peer-info at all */
+  else                  /* default: no peer-info at all */
     to.push_peer_info_detail = 0;
 #endif

@@ -2342,10 +2359,6 @@ do_init_crypto_tls (struct context *c, const unsigned 
int flags)
 #endif
 #endif

-#ifdef USE_COMP
-  to.comp_options = options->comp;
-#endif
-
 #if defined(ENABLE_CRYPTO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10001000
   if (options->keying_material_exporter_label)
     {
@@ -2387,6 +2400,47 @@ do_init_crypto_tls (struct context *c, const unsigned 
int flags)
     c->c2.tls_auth_standalone = tls_auth_standalone_init (&to, &c->c2.gc);
 }

+
+
+static void
+do_init_crypto_tls (struct context *c, const unsigned int flags)
+{
+  const struct options *options = &c->options;
+  struct tls_options to;
+  bool packet_id_long_form;
+
+  ASSERT (options->tls_server || options->tls_client);
+  ASSERT (!options->test_crypto);
+
+  init_crypto_pre (c, flags);
+
+  /* Make sure we are either a TLS client or server but not both */
+  ASSERT (options->tls_server == !options->tls_client);
+
+  /* initialize persistent component */
+  do_init_crypto_tls_c1 (c);
+  if (IS_SIG (c))
+    return;
+
+  /* Sanity check on IV, sequence number, and cipher mode options */
+  check_replay_iv_consistency (&c->c1.ks.key_type, options->replay,
+                              options->use_iv);
+
+  /* In short form, unique datagram identifier is 32 bits, in long form 64 
bits */
+  packet_id_long_form = cipher_kt_mode_ofb_cfb (c->c1.ks.key_type.cipher);
+
+  /* Compute MTU parameters */
+  crypto_adjust_frame_parameters (&c->c2.frame,
+                                 &c->c1.ks.key_type,
+                                 options->ciphername_defined,
+                                 options->use_iv,
+                                 options->replay, packet_id_long_form);
+  tls_adjust_frame_parameters (&c->c2.frame);
+
+  do_init_tls_multi(c, flags, packet_id_long_form);
+}
+
+
 static void
 do_init_finalize_tls_frame (struct context *c)
 {
-- 
1.9.3


Reply via email to