aboutsummaryrefslogtreecommitdiff
path: root/src/openvpn/ssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/ssl.c')
-rw-r--r--src/openvpn/ssl.c54
1 files changed, 48 insertions, 6 deletions
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index f90c6a8..b572b7b 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -1783,6 +1783,29 @@ init_key_contexts(struct key_ctx_bi *key,
}
+static bool
+generate_key_expansion_tls_export(struct tls_session *session, struct key2 *key2)
+{
+ struct gc_arena gc = gc_new();
+ unsigned char *key2data;
+
+ key2data = key_state_export_keying_material(session,
+ EXPORT_KEY_DATA_LABEL,
+ strlen(EXPORT_KEY_DATA_LABEL),
+ sizeof(key2->keys),
+ &gc);
+ if (!key2data)
+ {
+ return false;
+ }
+ memcpy(key2->keys, key2data, sizeof(key2->keys));
+ secure_memzero(key2data, sizeof(key2->keys));
+ key2->n = 2;
+
+ gc_free(&gc);
+ return true;
+}
+
static struct key2
generate_key_expansion_openvpn_prf(const struct tls_session *session)
{
@@ -1854,7 +1877,7 @@ generate_key_expansion_openvpn_prf(const struct tls_session *session)
*/
static bool
generate_key_expansion(struct key_ctx_bi *key,
- const struct tls_session *session)
+ struct tls_session *session)
{
bool ret = false;
struct key2 key2;
@@ -1865,10 +1888,20 @@ generate_key_expansion(struct key_ctx_bi *key,
goto exit;
}
-
bool server = session->opt->server;
- key2 = generate_key_expansion_openvpn_prf(session);
+ if (session->opt->crypto_flags & CO_USE_TLS_KEY_MATERIAL_EXPORT)
+ {
+ if (!generate_key_expansion_tls_export(session, &key2))
+ {
+ msg(D_TLS_ERRORS, "TLS Error: Keying material export failed");
+ goto exit;
+ }
+ }
+ else
+ {
+ key2 = generate_key_expansion_openvpn_prf(session);
+ }
key2_print(&key2, &session->opt->key_type,
"Master Encrypt", "Master Decrypt");
@@ -1967,6 +2000,11 @@ tls_session_update_crypto_params(struct tls_session *session,
return false;
}
+ if (options->data_channel_use_ekm)
+ {
+ session->opt->crypto_flags |= CO_USE_TLS_KEY_MATERIAL_EXPORT;
+ }
+
if (strcmp(options->ciphername, session->opt->config_ciphername))
{
msg(D_HANDSHAKE, "Data Channel: using negotiated cipher '%s'",
@@ -2251,13 +2289,11 @@ push_peer_info(struct buffer *buf, struct tls_session *session)
* push request, also signal that the client wants
* to get push-reply messages without without requiring a round
* trip for a push request message*/
- if(session->opt->pull)
+ if (session->opt->pull)
{
iv_proto |= IV_PROTO_REQUEST_PUSH;
}
- buf_printf(&out, "IV_PROTO=%d\n", iv_proto);
-
/* support for Negotiable Crypto Parameters */
if (session->opt->ncp_enabled
&& (session->opt->mode == MODE_SERVER || session->opt->pull))
@@ -2269,8 +2305,14 @@ push_peer_info(struct buffer *buf, struct tls_session *session)
buf_printf(&out, "IV_NCP=2\n");
}
buf_printf(&out, "IV_CIPHERS=%s\n", session->opt->config_ncp_ciphers);
+
+#ifdef HAVE_EXPORT_KEYING_MATERIAL
+ iv_proto |= IV_PROTO_TLS_KEY_EXPORT;
+#endif
}
+ buf_printf(&out, "IV_PROTO=%d\n", iv_proto);
+
/* push compression status */
#ifdef USE_COMP
comp_generate_peer_info_string(&session->opt->comp_options, &out);