diff options
Diffstat (limited to 'src/openvpn/ssl.c')
-rw-r--r-- | src/openvpn/ssl.c | 54 |
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); |