Re: [Openvpn-devel] [PATCH] Keying Material Exporter [RFC 5705]
Updated patch: - setenv_str() will set only valid tls_ekm attribute diff --git a/src/openvpn/init.c b/src/openvpn/init.c index c2907cd..7870d10 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2307,6 +2307,13 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) length prefix */ socket_adjust_frame_parameters (, options->ce.proto); + /* Checking for required parameters for Channel Bindings */ + to.ekm_size = options->keying_material_exporter_length; + + to.ekm_label = (uint8_t*)options->keying_material_exporter_label; + to.ekm_label_size = to.ekm_label ? strlen(to.ekm_label) : 0; + to.ekm_used = (to.ekm_label_size && to.ekm_size >= 20) ? true : false; + /* * Initialize OpenVPN's master TLS-mode object. */ @@ -2315,6 +2322,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) if (flags & CF_INIT_TLS_AUTH_STANDALONE) c->c2.tls_auth_standalone = tls_auth_standalone_init (, >c2.gc); + } static void diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 18cb354..5323cd7 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -6966,6 +6966,24 @@ add_option (struct options *options, options->persist_mode = 1; } #endif + else if (streq (p[0], "keying-material-exporter-label") && p[1]) +{ + if (strncmp(p[1], "EXPORTER", 8)) +{ + msg (msglevel, "keying material exporter labels SHOULD begin with \"EXPORTER\""); + goto err; +} + VERIFY_PERMISSION (OPT_P_GENERAL); + + options->keying_material_exporter_label = p[1]; +} + else if (streq (p[0], "keying-material-exporter-length")) +{ + int len = positive_atoi (p[1]); + VERIFY_PERMISSION (OPT_P_GENERAL); + + options->keying_material_exporter_length = len; +} else { int i; diff --git a/src/openvpn/options.h b/src/openvpn/options.h index ec1d091..8c8aeb3 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -600,6 +600,10 @@ struct options bool show_net_up; int route_method; #endif + + /* Keying Material Exporters [RFC 5705] */ + const char *keying_material_exporter_label; + int keying_material_exporter_length; }; #define streq(x, y) (!strcmp((x), (y))) diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index d4acc0f..b757bfe 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -1,13 +1,14 @@ /* * OpenVPN -- An application to securely tunnel IP networks * over a single TCP/UDP port, with support for SSL/TLS-based - * session authentication and key exchange, + * session authentication, key exchange and channel bindings, * packet encryption, packet authentication, and * packet compression. * * Copyright (C) 2002-2010 OpenVPN Technologies, Inc.* Copyright (C) 2010 Fox Crypto B.V. * Copyright (C) 2008-2013 David Sommerseth + * Copyright (C) 2014 Daniel Kubec * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -905,6 +906,14 @@ tls_session_init (struct tls_multi *multi, struct tls_session *session) key_state_init (session, >key[KS_PRIMARY]); + /* allocate buffers for vpn_binding_key and tls_ekm [RFC 5705] */ + session->ekm = malloc (session->opt->ekm_size); + session->ekm_exported = false; + session->binding_key = malloc (session->opt->ekm_size); + + memset(session->ekm, 0, session->opt->ekm_size); + memset(session->binding_key, 0, session->opt->ekm_size); + dmsg (D_TLS_DEBUG, "TLS: tls_session_init: new session object, sid=%s", session_id_print (>session_id, )); @@ -937,6 +946,12 @@ tls_session_free (struct tls_session *session, bool clear) if (session->common_name) free (session->common_name); + if (session->ekm) +free (session->ekm); + + if (session->binding_key) +free (session->binding_key); + cert_hash_free (session->cert_hash_set); if (clear) @@ -1454,6 +1469,62 @@ tls1_PRF(uint8_t *label, gc_free (); } +/* + * Use the tls1_keying_material_exporter for generating VPN Binding Key + * + * Labels here have the same definition as in TLS, i.e., an ASCII string + * with no terminating NULL. + * + * Note that exporter labels have the potential to collide with existing + * tls1_PRF labels. In order to prevent this, labels SHOULD begin with + * "EXPORTER". + * + * The output is a pseudorandom bit string of length bytes generated + * from the master_secret. + * + * If no context is provided, it then computes: + * + * tls1_PRF(SecurityParameters.master_secret, label, + * SecurityParameters.client_random + + * SecurityParameters.server_random)[length] + * + * If context is provided, it computes: + * + *
Re: [Openvpn-devel] [PATCH] Keying Material Exporter [RFC 5705]
Updated patch. vpn_binding_key: - keying material derived by openvpn's crypto later (ssl.c:tls1_*) - life time across negotiations (works a bit like EKM) tls_ekm: Exported Keying Material [RFC 5705] - derived when crypto backend support ( currently openssl >= 1.0.2 ) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index c2907cd..7870d10 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2307,6 +2307,13 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) length prefix */ socket_adjust_frame_parameters (, options->ce.proto); + /* Checking for required parameters for Channel Bindings */ + to.ekm_size = options->keying_material_exporter_length; + + to.ekm_label = (uint8_t*)options->keying_material_exporter_label; + to.ekm_label_size = to.ekm_label ? strlen(to.ekm_label) : 0; + to.ekm_used = (to.ekm_label_size && to.ekm_size >= 20) ? true : false; + /* * Initialize OpenVPN's master TLS-mode object. */ @@ -2315,6 +2322,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) if (flags & CF_INIT_TLS_AUTH_STANDALONE) c->c2.tls_auth_standalone = tls_auth_standalone_init (, >c2.gc); + } static void diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 18cb354..5323cd7 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -6966,6 +6966,24 @@ add_option (struct options *options, options->persist_mode = 1; } #endif + else if (streq (p[0], "keying-material-exporter-label") && p[1]) +{ + if (strncmp(p[1], "EXPORTER", 8)) +{ + msg (msglevel, "keying material exporter labels SHOULD begin with \"EXPORTER\""); + goto err; +} + VERIFY_PERMISSION (OPT_P_GENERAL); + + options->keying_material_exporter_label = p[1]; +} + else if (streq (p[0], "keying-material-exporter-length")) +{ + int len = positive_atoi (p[1]); + VERIFY_PERMISSION (OPT_P_GENERAL); + + options->keying_material_exporter_length = len; +} else { int i; diff --git a/src/openvpn/options.h b/src/openvpn/options.h index ec1d091..8c8aeb3 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -600,6 +600,10 @@ struct options bool show_net_up; int route_method; #endif + + /* Keying Material Exporters [RFC 5705] */ + const char *keying_material_exporter_label; + int keying_material_exporter_length; }; #define streq(x, y) (!strcmp((x), (y))) diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index d4acc0f..908886c 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -1,13 +1,14 @@ /* * OpenVPN -- An application to securely tunnel IP networks * over a single TCP/UDP port, with support for SSL/TLS-based - * session authentication and key exchange, + * session authentication, key exchange and channel bindings, * packet encryption, packet authentication, and * packet compression. * * Copyright (C) 2002-2010 OpenVPN Technologies, Inc.* Copyright (C) 2010 Fox Crypto B.V. * Copyright (C) 2008-2013 David Sommerseth + * Copyright (C) 2014 Daniel Kubec * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -905,6 +906,10 @@ tls_session_init (struct tls_multi *multi, struct tls_session *session) key_state_init (session, >key[KS_PRIMARY]); + /* allocate buffers for vpn_binding_key and tls_ekm [RFC 5705] */ + session->ekm = malloc (session->opt->ekm_size); + session->binding_key = malloc (session->opt->ekm_size); + dmsg (D_TLS_DEBUG, "TLS: tls_session_init: new session object, sid=%s", session_id_print (>session_id, )); @@ -937,6 +942,12 @@ tls_session_free (struct tls_session *session, bool clear) if (session->common_name) free (session->common_name); + if (session->ekm) +free (session->ekm); + + if (session->binding_key) +free (session->binding_key); + cert_hash_free (session->cert_hash_set); if (clear) @@ -1454,6 +1465,62 @@ tls1_PRF(uint8_t *label, gc_free (); } +/* + * Use the tls1_keying_material_exporter for generating VPN Binding Key + * + * Labels here have the same definition as in TLS, i.e., an ASCII string + * with no terminating NULL. + * + * Note that exporter labels have the potential to collide with existing + * tls1_PRF labels. In order to prevent this, labels SHOULD begin with + * "EXPORTER". + * + * The output is a pseudorandom bit string of length bytes generated + * from the master_secret. + * + * If no context is provided, it then computes: + * + * tls1_PRF(SecurityParameters.master_secret, label, + * SecurityParameters.client_random + + * SecurityParameters.server_random)[length] +