[Openvpn-devel,v3,1/3] Refactor key_state_export_keying_material functions
Commit Message
This refactors the common code between mbed SSL and OpenSSL into
export_user_keying_material and also prepares the backend functions
to export more than one key.
Also fix checking the return value of SSL_export_keying_material
only 1 is a sucess, -1 is also an error.
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Patch V2: Cache secrets for mbed TLS instead generating all ekms
in the call back function
Patch V3: comment is no longer a lie. (fixed doxygen)
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
---
src/openvpn/ssl.c | 36 ++++++++++++++++++-
src/openvpn/ssl_backend.h | 20 +++++++----
src/openvpn/ssl_mbedtls.c | 73 ++++++++++++++++++++-------------------
src/openvpn/ssl_mbedtls.h | 12 +++++--
src/openvpn/ssl_openssl.c | 43 +++++++++--------------
5 files changed, 114 insertions(+), 70 deletions(-)
Comments
Hi,
On 14-08-2020 16:51, Arne Schwabe wrote:
> This refactors the common code between mbed SSL and OpenSSL into
> export_user_keying_material and also prepares the backend functions
> to export more than one key.
>
> Also fix checking the return value of SSL_export_keying_material
> only 1 is a sucess, -1 is also an error.
>
> Signed-off-by: Arne Schwabe <arne@rfc2549.org>
>
> Patch V2: Cache secrets for mbed TLS instead generating all ekms
> in the call back function
>
> Patch V3: comment is no longer a lie. (fixed doxygen)
>
> Signed-off-by: Arne Schwabe <arne@rfc2549.org>
> ---
> src/openvpn/ssl.c | 36 ++++++++++++++++++-
> src/openvpn/ssl_backend.h | 20 +++++++----
> src/openvpn/ssl_mbedtls.c | 73 ++++++++++++++++++++-------------------
> src/openvpn/ssl_mbedtls.h | 12 +++++--
> src/openvpn/ssl_openssl.c | 43 +++++++++--------------
> 5 files changed, 114 insertions(+), 70 deletions(-)
>
> diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
> index f16114c2..3fcaa25f 100644
> --- a/src/openvpn/ssl.c
> +++ b/src/openvpn/ssl.c
> @@ -2412,6 +2412,40 @@ error:
> return false;
> }
>
> +static void
> +export_user_keying_material(struct key_state_ssl *ssl,
> + struct tls_session *session)
> +{
> + if (session->opt->ekm_size > 0)
> + {
> + unsigned int size = session->opt->ekm_size;
> + struct gc_arena gc = gc_new();
> +
> + unsigned char *ekm;
> + if ((ekm = key_state_export_keying_material(session,
> + session->opt->ekm_label,
> + session->opt->ekm_label_size,
> + session->opt->ekm_size,
> + &gc)))
> + {
> + unsigned int len = (size * 2) + 2;
> +
> + const char *key = format_hex_ex(ekm, size, len, 0, NULL, &gc);
> + setenv_str(session->opt->es, "exported_keying_material", key);
> +
> + dmsg(D_TLS_DEBUG_MED, "%s: exported keying material: %s",
> + __func__, key);
> + secure_memzero(ekm, size);
> + }
> + else
> + {
> + msg(M_WARN, "WARNING: Export keying material failed!");
> + setenv_del(session->opt->es, "exported_keying_material");
> + }
> + gc_free(&gc);
> + }
> +}
> +
> /**
> * Handle reading key data, peer-info, username/password, OCC
> * from the TLS control channel (cleartext).
> @@ -2541,7 +2575,7 @@ key_method_2_read(struct buffer *buf, struct tls_multi *multi, struct tls_sessio
> if ((ks->authenticated > KS_AUTH_FALSE)
> && plugin_defined(session->opt->plugins, OPENVPN_PLUGIN_TLS_FINAL))
> {
> - key_state_export_keying_material(&ks->ks_ssl, session);
> + export_user_keying_material(&ks->ks_ssl, session);
>
> if (plugin_call(session->opt->plugins, OPENVPN_PLUGIN_TLS_FINAL, NULL, NULL, session->opt->es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
> {
> diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h
> index 7f52ab1e..cf9fba25 100644
> --- a/src/openvpn/ssl_backend.h
> +++ b/src/openvpn/ssl_backend.h
> @@ -394,13 +394,21 @@ void backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx,
> * derived from existing TLS channel. This exported keying material can then be
> * used for a variety of purposes.
> *
> - * @param ks_ssl The SSL channel's state info
> * @param session The session associated with the given key_state
> - */
> -
> -void
> -key_state_export_keying_material(struct key_state_ssl *ks_ssl,
> - struct tls_session *session) __attribute__((nonnull));
> + * @param label The label to use when exporting the key
> + * @param label_size The size of the label to use when exporting the key
> + * @param ekm_size THe size of the exported/returned key material
> + * @param gc gc_arena that might be used to allocate the string
> + * returned
> + * @returns The exported key material, the caller may zero the
> + * string but should not free it
> + */
> +
> +unsigned char*
> +key_state_export_keying_material(struct tls_session *session,
> + const char* label, size_t label_size,
> + size_t ekm_size,
> + struct gc_arena *gc) __attribute__((nonnull));
>
> /**************************************************************************/
> /** @addtogroup control_tls
> diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c
> index 9c874788..4287b59e 100644
> --- a/src/openvpn/ssl_mbedtls.c
> +++ b/src/openvpn/ssl_mbedtls.c
> @@ -206,51 +206,54 @@ mbedtls_ssl_export_keys_cb(void *p_expkey, const unsigned char *ms,
> {
> struct tls_session *session = p_expkey;
> struct key_state_ssl *ks_ssl = &session->key[KS_PRIMARY].ks_ssl;
> - unsigned char client_server_random[64];
> + struct tls_key_cache *cache = &ks_ssl->tls_key_cache;
>
> - ks_ssl->exported_key_material = gc_malloc(session->opt->ekm_size,
> - true, NULL);
> + static_assert(sizeof(ks_ssl->ctx->session->master)
> + == sizeof(cache->master_secret), "master size mismatch");
>
> - memcpy(client_server_random, client_random, 32);
> - memcpy(client_server_random + 32, server_random, 32);
> + memcpy(cache->client_server_random, client_random, 32);
> + memcpy(cache->client_server_random + 32, server_random, 32);
> + memcpy(cache->master_secret, ms, sizeof(cache->master_secret));
> + cache->tls_prf_type = tls_prf_type;
>
> - const size_t ms_len = sizeof(ks_ssl->ctx->session->master);
> - int ret = mbedtls_ssl_tls_prf(tls_prf_type, ms, ms_len,
> - session->opt->ekm_label, client_server_random,
> - sizeof(client_server_random), ks_ssl->exported_key_material,
> - session->opt->ekm_size);
> -
> - if (!mbed_ok(ret))
> - {
> - secure_memzero(ks_ssl->exported_key_material, session->opt->ekm_size);
> - }
> -
> - secure_memzero(client_server_random, sizeof(client_server_random));
> -
> - return ret;
> + return true;
> }
> -#endif /* HAVE_EXPORT_KEYING_MATERIAL */
>
> -void
> -key_state_export_keying_material(struct key_state_ssl *ssl,
> - struct tls_session *session)
> +unsigned char *
> +key_state_export_keying_material(struct tls_session *session,
> + const char* label, size_t label_size,
> + size_t ekm_size,
> + struct gc_arena *gc)
> {
> - if (ssl->exported_key_material)
> + ASSERT(strlen(label) == label_size);
> +
> + struct tls_key_cache *cache = &session->key[KS_PRIMARY].ks_ssl.tls_key_cache;
> +
> + /* If the type is NONE, we either have no cached secrets or
> + * there is no PRF, in both cases we cannot generate key material */
> + if (cache->tls_prf_type == MBEDTLS_SSL_TLS_PRF_NONE)
> {
> - unsigned int size = session->opt->ekm_size;
> - struct gc_arena gc = gc_new();
> - unsigned int len = (size * 2) + 2;
> + return NULL;
> + }
>
> - const char *key = format_hex_ex(ssl->exported_key_material,
> - size, len, 0, NULL, &gc);
> - setenv_str(session->opt->es, "exported_keying_material", key);
> + unsigned char *ekm = (unsigned char *) gc_malloc(ekm_size, true, gc);
> + int ret = mbedtls_ssl_tls_prf(cache->tls_prf_type, cache->master_secret,
> + sizeof(cache->master_secret),
> + label, cache->client_server_random,
> + sizeof(cache->client_server_random),
> + ekm, ekm_size);
>
> - dmsg(D_TLS_DEBUG_MED, "%s: exported keying material: %s",
> - __func__, key);
> - gc_free(&gc);
> + if (mbed_ok(ret))
> + {
> + return ekm;
> + }
> + else
> + {
> + secure_memzero(ekm, session->opt->ekm_size);
> + return NULL;
> }
> }
> -
> +#endif /* HAVE_EXPORT_KEYING_MATERIAL */
>
> bool
> tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags)
> @@ -1178,7 +1181,7 @@ key_state_ssl_free(struct key_state_ssl *ks_ssl)
> {
> if (ks_ssl)
> {
> - free(ks_ssl->exported_key_material);
> + CLEAR(ks_ssl->tls_key_cache);
>
> if (ks_ssl->ctx)
> {
> diff --git a/src/openvpn/ssl_mbedtls.h b/src/openvpn/ssl_mbedtls.h
> index 0525134f..17aae551 100644
> --- a/src/openvpn/ssl_mbedtls.h
> +++ b/src/openvpn/ssl_mbedtls.h
> @@ -82,6 +82,15 @@ struct external_context {
> void *sign_ctx;
> };
>
> +/** struct to cache TLS secrets for keying material exporter (RFC 5705).
> + * The constants (64 and 48) are inherent to TLS version and
> + * the whole keying material export will likely change when they change */
> +struct tls_key_cache {
> + unsigned char client_server_random[64];
> + mbedtls_tls_prf_types tls_prf_type;
> + unsigned char master_secret[48];
> +};
> +
> /**
> * Structure that wraps the TLS context. Contents differ depending on the
> * SSL library used.
> @@ -114,8 +123,7 @@ struct key_state_ssl {
> mbedtls_ssl_context *ctx; /**< mbedTLS connection context */
> bio_ctx *bio_ctx;
>
> - /** Keying material exporter cache (RFC 5705). */
> - uint8_t *exported_key_material;
> + struct tls_key_cache tls_key_cache;
>
> };
>
> diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
> index 5ba74402..f52c7c39 100644
> --- a/src/openvpn/ssl_openssl.c
> +++ b/src/openvpn/ssl_openssl.c
> @@ -158,35 +158,26 @@ tls_ctx_initialised(struct tls_root_ctx *ctx)
> return NULL != ctx->ctx;
> }
>
> -void
> -key_state_export_keying_material(struct key_state_ssl *ssl,
> - struct tls_session *session)
> -{
> - if (session->opt->ekm_size > 0)
> - {
> - unsigned int size = session->opt->ekm_size;
> - struct gc_arena gc = gc_new();
> - unsigned char *ekm = (unsigned char *) gc_malloc(size, true, &gc);
> +unsigned char*
> +key_state_export_keying_material(struct tls_session *session,
> + const char* label, size_t label_size,
> + size_t ekm_size,
> + struct gc_arena *gc)
>
> - if (SSL_export_keying_material(ssl->ssl, ekm, size,
> - session->opt->ekm_label,
> - session->opt->ekm_label_size,
> - NULL, 0, 0))
> - {
> - unsigned int len = (size * 2) + 2;
> +{
> + unsigned char *ekm = (unsigned char *) gc_malloc(ekm_size, true, gc);
>
> - const char *key = format_hex_ex(ekm, size, len, 0, NULL, &gc);
> - setenv_str(session->opt->es, "exported_keying_material", key);
> + SSL* ssl = session->key[KS_PRIMARY].ks_ssl.ssl;
>
> - dmsg(D_TLS_DEBUG_MED, "%s: exported keying material: %s",
> - __func__, key);
> - }
> - else
> - {
> - msg(M_WARN, "WARNING: Export keying material failed!");
> - setenv_del(session->opt->es, "exported_keying_material");
> - }
> - gc_free(&gc);
> + if (SSL_export_keying_material(ssl, ekm, ekm_size, label,
> + label_size, NULL, 0, 0) == 1)
> + {
> + return ekm;
> + }
> + else
> + {
> + secure_memzero(ekm, ekm_size);
> + return NULL;
> }
> }
>
>
Thanks, looks good to me now. Changes wrt v2 in comments and whitespace
only, so didn't re-test.
Acked-by: Steffan Karger <steffan@karger.me>
-Steffan
Your patch has been applied to the master branch.
I have no idea what this all does (and not enough brain power to develop
interest in finding out :-/ ) but if Steffan says it's good, so it is.
Also, t_client agrees :-)
commit 10abd656a3ae279cea7344055ce23637b7a62f6b (master)
Author: Arne Schwabe
Date: Fri Aug 14 16:51:53 2020 +0200
Refactor key_state_export_keying_material functions
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Steffan Karger <steffan@karger.me>
Message-Id: <20200814145153.12895-1-arne@rfc2549.org>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg20739.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
--
kind regards,
Gert Doering
Hi,
this commit seems to require a more recent mbedTLS version - it fails
a number of my buildslaves with
gcc -DHAVE_CONFIG_H -I. -I../.. -I../../include -I../../include -I../../src/compat -DPLUGIN_LIBDIR=\"/usr/local/lib/openvpn/plugins\" -Wall -Wno-unused-parameter -Wno-unused-function -Wno-stringop-truncation -g -O2 -std=c99 -MT auth_token.o -MD -MP -MF .deps/auth_token.Tpo -c -o auth_token.o auth_token.c
In file included from ssl_backend.h:41:0,
from ssl_common.h:38,
from ssl.h:43,
from openvpn.h:31,
from auth_token.c:12:
ssl_mbedtls.h:90:5: error: unknown type name 'mbedtls_tls_prf_types'
mbedtls_tls_prf_types tls_prf_type;
^
- I think it *should* fail the configure phase if mbedTLS is too old,
and clearly specify which version is required now (we have a check, but
it's fairly unspecific, and only says "mbed TLS 2.y.z required").
I've opened a trac ticket to track this
https://community.openvpn.net/openvpn/ticket/1319
gert
On Sun, Aug 23, 2020 at 10:01:29PM +0200, Gert Doering wrote:
> Your patch has been applied to the master branch.
>
> I have no idea what this all does (and not enough brain power to develop
> interest in finding out :-/ ) but if Steffan says it's good, so it is.
>
> Also, t_client agrees :-)
>
> commit 10abd656a3ae279cea7344055ce23637b7a62f6b (master)
> Author: Arne Schwabe
> Date: Fri Aug 14 16:51:53 2020 +0200
>
> Refactor key_state_export_keying_material functions
>
> Signed-off-by: Arne Schwabe <arne@rfc2549.org>
> Signed-off-by: Arne Schwabe <arne@rfc2549.org>
> Acked-by: Steffan Karger <steffan@karger.me>
> Message-Id: <20200814145153.12895-1-arne@rfc2549.org>
> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg20739.html
> Signed-off-by: Gert Doering <gert@greenie.muc.de>
>
>
> --
> kind regards,
>
> Gert Doering
>
>
>
> _______________________________________________
> Openvpn-devel mailing list
> Openvpn-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/openvpn-devel
>
@@ -2412,6 +2412,40 @@ error:
return false;
}
+static void
+export_user_keying_material(struct key_state_ssl *ssl,
+ struct tls_session *session)
+{
+ if (session->opt->ekm_size > 0)
+ {
+ unsigned int size = session->opt->ekm_size;
+ struct gc_arena gc = gc_new();
+
+ unsigned char *ekm;
+ if ((ekm = key_state_export_keying_material(session,
+ session->opt->ekm_label,
+ session->opt->ekm_label_size,
+ session->opt->ekm_size,
+ &gc)))
+ {
+ unsigned int len = (size * 2) + 2;
+
+ const char *key = format_hex_ex(ekm, size, len, 0, NULL, &gc);
+ setenv_str(session->opt->es, "exported_keying_material", key);
+
+ dmsg(D_TLS_DEBUG_MED, "%s: exported keying material: %s",
+ __func__, key);
+ secure_memzero(ekm, size);
+ }
+ else
+ {
+ msg(M_WARN, "WARNING: Export keying material failed!");
+ setenv_del(session->opt->es, "exported_keying_material");
+ }
+ gc_free(&gc);
+ }
+}
+
/**
* Handle reading key data, peer-info, username/password, OCC
* from the TLS control channel (cleartext).
@@ -2541,7 +2575,7 @@ key_method_2_read(struct buffer *buf, struct tls_multi *multi, struct tls_sessio
if ((ks->authenticated > KS_AUTH_FALSE)
&& plugin_defined(session->opt->plugins, OPENVPN_PLUGIN_TLS_FINAL))
{
- key_state_export_keying_material(&ks->ks_ssl, session);
+ export_user_keying_material(&ks->ks_ssl, session);
if (plugin_call(session->opt->plugins, OPENVPN_PLUGIN_TLS_FINAL, NULL, NULL, session->opt->es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
{
@@ -394,13 +394,21 @@ void backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx,
* derived from existing TLS channel. This exported keying material can then be
* used for a variety of purposes.
*
- * @param ks_ssl The SSL channel's state info
* @param session The session associated with the given key_state
- */
-
-void
-key_state_export_keying_material(struct key_state_ssl *ks_ssl,
- struct tls_session *session) __attribute__((nonnull));
+ * @param label The label to use when exporting the key
+ * @param label_size The size of the label to use when exporting the key
+ * @param ekm_size THe size of the exported/returned key material
+ * @param gc gc_arena that might be used to allocate the string
+ * returned
+ * @returns The exported key material, the caller may zero the
+ * string but should not free it
+ */
+
+unsigned char*
+key_state_export_keying_material(struct tls_session *session,
+ const char* label, size_t label_size,
+ size_t ekm_size,
+ struct gc_arena *gc) __attribute__((nonnull));
/**************************************************************************/
/** @addtogroup control_tls
@@ -206,51 +206,54 @@ mbedtls_ssl_export_keys_cb(void *p_expkey, const unsigned char *ms,
{
struct tls_session *session = p_expkey;
struct key_state_ssl *ks_ssl = &session->key[KS_PRIMARY].ks_ssl;
- unsigned char client_server_random[64];
+ struct tls_key_cache *cache = &ks_ssl->tls_key_cache;
- ks_ssl->exported_key_material = gc_malloc(session->opt->ekm_size,
- true, NULL);
+ static_assert(sizeof(ks_ssl->ctx->session->master)
+ == sizeof(cache->master_secret), "master size mismatch");
- memcpy(client_server_random, client_random, 32);
- memcpy(client_server_random + 32, server_random, 32);
+ memcpy(cache->client_server_random, client_random, 32);
+ memcpy(cache->client_server_random + 32, server_random, 32);
+ memcpy(cache->master_secret, ms, sizeof(cache->master_secret));
+ cache->tls_prf_type = tls_prf_type;
- const size_t ms_len = sizeof(ks_ssl->ctx->session->master);
- int ret = mbedtls_ssl_tls_prf(tls_prf_type, ms, ms_len,
- session->opt->ekm_label, client_server_random,
- sizeof(client_server_random), ks_ssl->exported_key_material,
- session->opt->ekm_size);
-
- if (!mbed_ok(ret))
- {
- secure_memzero(ks_ssl->exported_key_material, session->opt->ekm_size);
- }
-
- secure_memzero(client_server_random, sizeof(client_server_random));
-
- return ret;
+ return true;
}
-#endif /* HAVE_EXPORT_KEYING_MATERIAL */
-void
-key_state_export_keying_material(struct key_state_ssl *ssl,
- struct tls_session *session)
+unsigned char *
+key_state_export_keying_material(struct tls_session *session,
+ const char* label, size_t label_size,
+ size_t ekm_size,
+ struct gc_arena *gc)
{
- if (ssl->exported_key_material)
+ ASSERT(strlen(label) == label_size);
+
+ struct tls_key_cache *cache = &session->key[KS_PRIMARY].ks_ssl.tls_key_cache;
+
+ /* If the type is NONE, we either have no cached secrets or
+ * there is no PRF, in both cases we cannot generate key material */
+ if (cache->tls_prf_type == MBEDTLS_SSL_TLS_PRF_NONE)
{
- unsigned int size = session->opt->ekm_size;
- struct gc_arena gc = gc_new();
- unsigned int len = (size * 2) + 2;
+ return NULL;
+ }
- const char *key = format_hex_ex(ssl->exported_key_material,
- size, len, 0, NULL, &gc);
- setenv_str(session->opt->es, "exported_keying_material", key);
+ unsigned char *ekm = (unsigned char *) gc_malloc(ekm_size, true, gc);
+ int ret = mbedtls_ssl_tls_prf(cache->tls_prf_type, cache->master_secret,
+ sizeof(cache->master_secret),
+ label, cache->client_server_random,
+ sizeof(cache->client_server_random),
+ ekm, ekm_size);
- dmsg(D_TLS_DEBUG_MED, "%s: exported keying material: %s",
- __func__, key);
- gc_free(&gc);
+ if (mbed_ok(ret))
+ {
+ return ekm;
+ }
+ else
+ {
+ secure_memzero(ekm, session->opt->ekm_size);
+ return NULL;
}
}
-
+#endif /* HAVE_EXPORT_KEYING_MATERIAL */
bool
tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags)
@@ -1178,7 +1181,7 @@ key_state_ssl_free(struct key_state_ssl *ks_ssl)
{
if (ks_ssl)
{
- free(ks_ssl->exported_key_material);
+ CLEAR(ks_ssl->tls_key_cache);
if (ks_ssl->ctx)
{
@@ -82,6 +82,15 @@ struct external_context {
void *sign_ctx;
};
+/** struct to cache TLS secrets for keying material exporter (RFC 5705).
+ * The constants (64 and 48) are inherent to TLS version and
+ * the whole keying material export will likely change when they change */
+struct tls_key_cache {
+ unsigned char client_server_random[64];
+ mbedtls_tls_prf_types tls_prf_type;
+ unsigned char master_secret[48];
+};
+
/**
* Structure that wraps the TLS context. Contents differ depending on the
* SSL library used.
@@ -114,8 +123,7 @@ struct key_state_ssl {
mbedtls_ssl_context *ctx; /**< mbedTLS connection context */
bio_ctx *bio_ctx;
- /** Keying material exporter cache (RFC 5705). */
- uint8_t *exported_key_material;
+ struct tls_key_cache tls_key_cache;
};
@@ -158,35 +158,26 @@ tls_ctx_initialised(struct tls_root_ctx *ctx)
return NULL != ctx->ctx;
}
-void
-key_state_export_keying_material(struct key_state_ssl *ssl,
- struct tls_session *session)
-{
- if (session->opt->ekm_size > 0)
- {
- unsigned int size = session->opt->ekm_size;
- struct gc_arena gc = gc_new();
- unsigned char *ekm = (unsigned char *) gc_malloc(size, true, &gc);
+unsigned char*
+key_state_export_keying_material(struct tls_session *session,
+ const char* label, size_t label_size,
+ size_t ekm_size,
+ struct gc_arena *gc)
- if (SSL_export_keying_material(ssl->ssl, ekm, size,
- session->opt->ekm_label,
- session->opt->ekm_label_size,
- NULL, 0, 0))
- {
- unsigned int len = (size * 2) + 2;
+{
+ unsigned char *ekm = (unsigned char *) gc_malloc(ekm_size, true, gc);
- const char *key = format_hex_ex(ekm, size, len, 0, NULL, &gc);
- setenv_str(session->opt->es, "exported_keying_material", key);
+ SSL* ssl = session->key[KS_PRIMARY].ks_ssl.ssl;
- dmsg(D_TLS_DEBUG_MED, "%s: exported keying material: %s",
- __func__, key);
- }
- else
- {
- msg(M_WARN, "WARNING: Export keying material failed!");
- setenv_del(session->opt->es, "exported_keying_material");
- }
- gc_free(&gc);
+ if (SSL_export_keying_material(ssl, ekm, ekm_size, label,
+ label_size, NULL, 0, 0) == 1)
+ {
+ return ekm;
+ }
+ else
+ {
+ secure_memzero(ekm, ekm_size);
+ return NULL;
}
}