--- 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