mirror of
https://github.com/OpenVPN/openvpn.git
synced 2024-09-20 12:02:28 +02:00
Added support for TLS Keying Material Exporters [RFC-5705]
Keying Material Exporter [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. [DS: Updated man page to document both upper and lower length boundaries] Signed-off-by: Daniel Kubec <niel@rtfm.cz> Signed-off-by: David Sommerseth <davids@redhat.com> Acked-by: Steffan Karger <steffan.karger@fox-it.com Acked-by: David Sommerseth <davids@redhat.com>
This commit is contained in:
parent
7246ccfdbe
commit
685e486e8b
Notes:
David Sommerseth
2015-10-10 10:41:37 +02:00
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Forgot to add Message-ID and URLs to the commit message. Message-Id: CAEW7GUswCyjPpYN8_2d5OGQzg7xRe8tAVBa=9-243W9vLL4b+g@mail.gmail.com URL: http://article.gmane.org/gmane.network.openvpn.devel/9543 -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iEYEARECAAYFAlYYy94ACgkQDC186MBRfroOgQCgl5Qszv6ZbSqBJ29b2FE/dUMA ilEAn2IgcE6OD4ZPFekaUCv5KKsSSrh6 =DyDt -----END PGP SIGNATURE-----
@ -2757,6 +2757,18 @@ client\-connect), then
|
||||
every module and script must return success (0) in order for
|
||||
the connection to be authenticated.
|
||||
.\"*********************************************************
|
||||
.TP
|
||||
.B \-\-keying-material-exporter label len
|
||||
Save Exported Keying Material [RFC5705] of len bytes (must be
|
||||
between 16 and 4095 bytes) using label in environment
|
||||
(exported_keying_material) for use by plugins in
|
||||
OPENVPN_PLUGIN_TLS_FINAL callback.
|
||||
|
||||
Note that exporter labels have the potential to collide with existing PRF
|
||||
labels. In order to prevent this, labels MUST begin with "EXPORTER".
|
||||
|
||||
This option requires OpenSSL 1.0.1 or newer.
|
||||
.\"*********************************************************
|
||||
.SS Server Mode
|
||||
Starting with OpenVPN 2.0, a multi-client TCP/UDP server mode
|
||||
is supported, and can be enabled with the
|
||||
|
@ -2279,6 +2279,22 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
|
||||
to.comp_options = options->comp;
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_CRYPTO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10001000
|
||||
if (options->keying_material_exporter_label)
|
||||
{
|
||||
to.ekm_size = options->keying_material_exporter_length;
|
||||
if (to.ekm_size < 16 || to.ekm_size > 4095)
|
||||
to.ekm_size = 0;
|
||||
|
||||
to.ekm_label = options->keying_material_exporter_label;
|
||||
to.ekm_label_size = strlen(to.ekm_label);
|
||||
}
|
||||
else
|
||||
{
|
||||
to.ekm_size = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TLS handshake authentication (--tls-auth) */
|
||||
if (options->tls_auth_file)
|
||||
{
|
||||
|
@ -610,6 +610,10 @@ static const char usage_message[] =
|
||||
#ifdef ENABLE_X509_TRACK
|
||||
"--x509-track x : Save peer X509 attribute x in environment for use by\n"
|
||||
" plugins and management interface.\n"
|
||||
#endif
|
||||
#if defined(ENABLE_CRYPTO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10001000
|
||||
"--keying-material-exporter label len : Save Exported Keying Material (RFC5705)\n"
|
||||
" of len bytes (min. 16 bytes) using label in environment for use by plugins.\n"
|
||||
#endif
|
||||
"--remote-cert-ku v ... : Require that the peer certificate was signed with\n"
|
||||
" explicit key usage, you can specify more than one value.\n"
|
||||
@ -7066,6 +7070,29 @@ add_option (struct options *options,
|
||||
options->use_peer_id = true;
|
||||
options->peer_id = atoi(p[1]);
|
||||
}
|
||||
#if defined(ENABLE_CRYPTO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10001000
|
||||
else if (streq (p[0], "keying-material-exporter") && p[1] && p[2])
|
||||
{
|
||||
int ekm_length = positive_atoi (p[2]);
|
||||
|
||||
VERIFY_PERMISSION (OPT_P_GENERAL);
|
||||
|
||||
if (strncmp(p[1], "EXPORTER", 8))
|
||||
{
|
||||
msg (msglevel, "Keying material exporter label must begin with "
|
||||
"\"EXPORTER\"");
|
||||
goto err;
|
||||
}
|
||||
if (ekm_length < 16 || ekm_length > 4095)
|
||||
{
|
||||
msg (msglevel, "Invalid keying material exporter length");
|
||||
goto err;
|
||||
}
|
||||
|
||||
options->keying_material_exporter_label = p[1];
|
||||
options->keying_material_exporter_length = ekm_length;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
@ -591,6 +591,12 @@ struct options
|
||||
|
||||
bool use_peer_id;
|
||||
uint32_t peer_id;
|
||||
|
||||
#if defined(ENABLE_CRYPTO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10001000
|
||||
/* Keying Material Exporters [RFC 5705] */
|
||||
const char *keying_material_exporter_label;
|
||||
int keying_material_exporter_length;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define streq(x, y) (!strcmp((x), (y)))
|
||||
|
@ -2160,8 +2160,12 @@ 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))
|
||||
{
|
||||
key_state_export_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)
|
||||
ks->authenticated = false;
|
||||
|
||||
setenv_del (session->opt->es, "exported_keying_material");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -334,6 +334,19 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl,
|
||||
*/
|
||||
void key_state_ssl_free(struct key_state_ssl *ks_ssl);
|
||||
|
||||
/**
|
||||
* Keying Material Exporters [RFC 5705] allows additional keying material to be
|
||||
* 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));
|
||||
|
||||
/**************************************************************************/
|
||||
/** @addtogroup control_tls
|
||||
* @{ */
|
||||
|
@ -317,6 +317,11 @@ struct tls_options
|
||||
|
||||
/* --gremlin bits */
|
||||
int gremlin;
|
||||
|
||||
/* Keying Material Exporter [RFC 5705] parameters */
|
||||
const char *ekm_label;
|
||||
size_t ekm_label_size;
|
||||
size_t ekm_size;
|
||||
};
|
||||
|
||||
/** @addtogroup control_processor
|
||||
|
@ -133,6 +133,39 @@ bool 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)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10001000)
|
||||
unsigned int size = session->opt->ekm_size;
|
||||
unsigned char ekm[size];
|
||||
|
||||
if (SSL_export_keying_material(ssl->ssl, ekm, sizeof(ekm),
|
||||
session->opt->ekm_label, session->opt->ekm_label_size, NULL, 0, 0))
|
||||
{
|
||||
struct gc_arena gc = gc_new();
|
||||
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);
|
||||
|
||||
gc_free(&gc);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg (M_WARN, "WARNING: Export keying material failed!");
|
||||
setenv_del (session->opt->es, "exported_keying_material");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print debugging information on SSL/TLS session negotiation.
|
||||
*/
|
||||
|
@ -148,6 +148,12 @@ tls_ctx_initialised(struct tls_root_ctx *ctx)
|
||||
return ctx->initialised;
|
||||
}
|
||||
|
||||
void
|
||||
key_state_export_keying_material(struct key_state_ssl *ssl,
|
||||
struct tls_session *session)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user