aboutsummaryrefslogtreecommitdiff
path: root/src/openvpn
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn')
-rw-r--r--src/openvpn/init.c6
-rw-r--r--src/openvpn/multi.c24
-rw-r--r--src/openvpn/push.c6
-rw-r--r--src/openvpn/ssl.c6
-rw-r--r--src/openvpn/ssl.h5
5 files changed, 36 insertions, 11 deletions
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 824b666..b3096dc 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -2343,10 +2343,8 @@ do_deferred_options(struct context *c, const unsigned int found)
}
#endif
- /* Do not regenerate keys if server sends an extra push reply */
- if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized
- && !tls_session_update_crypto_params(session, &c->options, &c->c2.frame,
- frame_fragment))
+ if (!tls_session_update_crypto_params(session, &c->options, &c->c2.frame,
+ frame_fragment))
{
msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto options");
return false;
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index da0aeeb..b42bcec 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -2137,8 +2137,30 @@ multi_process_file_closed(struct multi_context *m, const unsigned int mpp_flags)
{
if (mi)
{
- /* continue authentication and send push_reply */
+ /* continue authentication, perform NCP negotiation and send push_reply */
multi_process_post(m, mi, mpp_flags);
+
+ /* With NCP and deferred authentication, we perform cipher negotiation and
+ * data channel keys generation on incoming push request, assuming that auth
+ * succeeded. When auth succeeds in between push requests and async push is used,
+ * we send push reply immediately. Above multi_process_post() call performs
+ * NCP negotiation and here we do keys generation. */
+
+ struct context *c = &mi->context;
+ struct frame *frame_fragment = NULL;
+#ifdef ENABLE_FRAGMENT
+ if (c->options.ce.fragment)
+ {
+ frame_fragment = &c->c2.frame_fragment;
+ }
+#endif
+ struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
+ if (!tls_session_update_crypto_params(session, &c->options,
+ &c->c2.frame, frame_fragment))
+ {
+ msg(D_TLS_ERRORS, "TLS Error: initializing data channel failed");
+ register_signal(c, SIGUSR1, "init-data-channel-failed");
+ }
}
else
{
diff --git a/src/openvpn/push.c b/src/openvpn/push.c
index 71f22e9..aef00d3 100644
--- a/src/openvpn/push.c
+++ b/src/openvpn/push.c
@@ -298,10 +298,8 @@ incoming_push_message(struct context *c, const struct buffer *buffer)
}
#endif
struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
- /* Do not regenerate keys if client send a second push request */
- if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized
- && !tls_session_update_crypto_params(session, &c->options,
- &c->c2.frame, frame_fragment))
+ if (!tls_session_update_crypto_params(session, &c->options,
+ &c->c2.frame, frame_fragment))
{
msg(D_TLS_ERRORS, "TLS Error: initializing data channel failed");
goto error;
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index e21279f..56d0576 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -1956,6 +1956,12 @@ tls_session_update_crypto_params(struct tls_session *session,
struct options *options, struct frame *frame,
struct frame *frame_fragment)
{
+ if (session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized)
+ {
+ /* keys already generated, nothing to do */
+ return true;
+ }
+
if (!session->opt->server
&& 0 != strcmp(options->ciphername, session->opt->config_ciphername)
&& !tls_item_in_cipher_list(options->ciphername, options->ncp_ciphers))
diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h
index 3449d91..f0a8ef5 100644
--- a/src/openvpn/ssl.h
+++ b/src/openvpn/ssl.h
@@ -474,7 +474,8 @@ void tls_update_remote_addr(struct tls_multi *multi,
/**
* Update TLS session crypto parameters (cipher and auth) and derive data
- * channel keys based on the supplied options.
+ * channel keys based on the supplied options. Does nothing if keys are already
+ * generated.
*
* @param session The TLS session to update.
* @param options The options to use when updating session.
@@ -482,7 +483,7 @@ void tls_update_remote_addr(struct tls_multi *multi,
* adjusted based on the selected cipher/auth).
* @param frame_fragment The fragment frame options.
*
- * @return true if updating succeeded, false otherwise.
+ * @return true if updating succeeded or keys are already generated, false otherwise.
*/
bool tls_session_update_crypto_params(struct tls_session *session,
struct options *options,