Re: [Openvpn-devel] [PATCH] Keying Material Exporter [RFC 5705]

2014-04-22 Thread Daniel Kubec
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]

2014-04-21 Thread Daniel Kubec
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]
+