Channel Binding Key based on Keying Material Exporters [RFC 5705]
PATCH 1/1 Channel Binding Key based on Keying Material Exporters [RFC 5705]
Channel Binding Key based on TLS Keying Material Exporters [RFC 5705 ] allow additional keying material to be derived from existing TLS channel. This exported keying material can then be used for a variety of purposes.
TLS allows client and server to establish keying material for use in the upper layers between the TLS end-points. Channel Bindings is straitforward and well-defined mechanism how to authenticate other layers.
Following two attributes were added primary for the possible plugins extensions.
Attributes
tls_channel_id: Identifies TLS Sessions across (re)negotiationtls_binding_key: Secret crypto derivate based on Keying Material Exporters
Configuration
TLS Binding Key is generated when *.ovpn contains following for each TLS negotiation.
example.ovpn:
{
# Channel Binding based on TLS Keying Material Exporter [RFC 5705] #
# Note that exporter labels have the potential to collide with existing PRF
# labels. In order to prevent this, labels SHOULD begin with "EXPORTER". # This is not a MUST because there are existing uses that have labels which do # not begin with this prefix. keying-material-exporter-label "EXPORTER_OPENVPN"
# Export len bytes of keying material (min. 20)
keying-material-exporter-length 20
}
Changes
This patch stays on top of crypto layer and that's reason why it will work for
both crypto backends (openssl/polarssl).
TLS_FINAL Plugin was called in key_method_2_read() before server_random was generated for the TLS server end-point and that's the reason why it's called at
2 places now. key_method_2_read() for server and key_method_2_write() for client.
Use Cases:
1) Authentication of upper layers (like Kerberos etc)
2) Authentication of VPN's TLS channel using QRCODE and device such as smartphones.
(Instead of user/pass dialog TLS VPN client could show for example QRCODE
based on keying material derivate)
3) Authentication of Binding Key in confidental side-channel can be also used and avoid/detect MITM (MITM provides his public key and that's reason why authentication of binding key will fail)
src/openvpn/init.c +11 -0
@@ -2307,6 +2307,16 @@ 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.binding_key_size = options->keying_material_exporter_length; + + to.kme_label = (uint8_t *)options->keying_material_exporter_label; + to.kme_label_size = to.kme_label ?strlen (to.kme_label) :0 ; + + to.binding_key_size = options->keying_material_exporter_length; + to.binding_key_gen = (to.kme_label_size && to.binding_key_size >=20 ) ? + true : false; +/* * Initialize OpenVPN's master TLS-mode object. */
@@ -2315,6 +2325,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
src/openvpn/options.c +18 -0
@@ -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;
src/openvpn/options.h +13 -7
@@ -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 optionsbool 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)))
src/openvpn/ssl.c +315 -50
460 lines not on this page · raw message
src/openvpn/ssl_common.h +12 -0
@@ -314,6 +314,12 @@ struct tls_options/* --gremlin bits */ int gremlin; + +/* Keying Material Exporter [RFC 5705] parameters */ +uint8_t *kme_label; +int kme_label_size; +bool binding_key_gen;/* true when binding key should be generated */ +int binding_key_size; };/** @addtogroup control_processor
@@ -359,6 +365,12 @@ struct tls_sessionstruct 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 ]; +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) */