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 (&to.frame, 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 (&to, &c->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..f5609f9 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -30,26 +30,28 @@
 #ifndef OPTIONS_H
 #define OPTIONS_H
 
+/*
+ * Maximum number of parameters associated with an option,
+ * including the option name itself.
+ */
+
+#define MAX_PARMS 16
+
 #include "basic.h"
 #include "common.h"
 #include "mtu.h"
 #include "route.h"
 #include "tun.h"
 #include "socket.h"
+#include "comp.h"
+#include "ssl_common.h"
 #include "plugin.h"
 #include "manage.h"
 #include "proxy.h"
-#include "comp.h"
 #include "pushlist.h"
 #include "clinat.h"
 
 /*
- * Maximum number of parameters associated with an option,
- * including the option name itself.
- */
-#define MAX_PARMS 16
-
-/*
  * Max size of options line and parameter.
  */
 #define OPTION_PARM_SIZE 256
@@ -600,6 +602,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..c23446a 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -2126,6 +2126,11 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
    */
   if (ks->authenticated && plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_TLS_FINAL))
     {
+
+      /* Exported Keying Material [RFC 5705] */    
+      if (session->opt->ekm_used)                                               
+        setenv_str (session->opt->es, "tls_ekm", format_hex (session->ekm, session->ekm_size, 0, &gc));
+
       if (plugin_call (session->opt->plugins, OPENVPN_PLUGIN_TLS_FINAL, NULL, NULL, session->opt->es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
 	ks->authenticated = false;
     }
diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h
index 04ba789..3af5d93 100644
--- a/src/openvpn/ssl_common.h
+++ b/src/openvpn/ssl_common.h
@@ -314,6 +314,12 @@ struct tls_options
 
   /* --gremlin bits */
   int gremlin;
+
+  /* Keying Material Exporter [RFC 5705] parameters */
+  uint8_t *ekm_label;
+  int ekm_label_size;
+  bool ekm_used; /* true when Keying Material should be exported */
+  int ekm_size;
 };
 
 /** @addtogroup control_processor
@@ -359,6 +365,16 @@ struct tls_session
   struct crypto_options tls_auth;
   struct packet_id tls_auth_pid;
 
+  /* number of negotiations for this session */
+  unsigned int negotiations;
+
+  /* channel_id identifies TLS session across (re)negotiations */
+  uint8_t channel_id[32];
+
+  /* Exported Keying Material [RFC 5705] */
+  uint8_t *ekm;
+  int ekm_size;
+
   int initial_opcode;		/* our initial P_ opcode */
   struct session_id session_id;	/* our random session ID */
   int key_id;			/* increments with each soft reset (for key renegotiation) */
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 0b63e26..4dd588f 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -154,6 +154,30 @@ info_callback (INFO_CALLBACK_SSL_CONST SSL * s, int where, int ret)
 	   SSL_alert_type_string_long (ret),
 	   SSL_alert_desc_string_long (ret));
     }
+  else if (where & SSL_CB_HANDSHAKE_DONE)
+    {
+      struct tls_session *tls;
+      tls = (struct tls_session *)SSL_get_ex_data (s, mydata_index);
+
+      if (tls->opt->ekm_used == false)
+        goto done;
+
+      if (tls->ekm)
+        free(tls->ekm);
+
+      tls->ekm_size = tls->opt->ekm_size;
+      tls->ekm = gc_malloc (tls->ekm_size, true, NULL);
+
+      SSL_export_keying_material((SSL *)s, 
+                                 tls->ekm, 
+                                 tls->ekm_size, 
+                                 tls->opt->ekm_label,
+                                 tls->opt->ekm_label_size, 
+                                 NULL, 0, 0);
+
+done:
+      msg (D_HANDSHAKE_VERBOSE, "SSL Handshake done.");
+    }
 }
 
 /*
