Prepare for using AEAD cipher modes + tls-auth, as tls-auth might want to use an HMAC, while the data channel uses e.g. GCM tags. This separates the two initialisations. Also, error out (and give a clear error message) if a user specifies tls-auth but no valid auth algorithm, which makes no sense at all.
Signed-off-by: Steffan Karger <stef...@karger.me> --- src/openvpn/crypto.c | 9 ++------- src/openvpn/init.c | 25 +++++++++++++++++++------ src/openvpn/openvpn.h | 1 + 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index c18d88b..806a995 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -751,13 +751,8 @@ get_tls_handshake_key (const struct key_type *key_type, if (passphrase_file && key_type->hmac_length) { struct key2 key2; - struct key_type kt = *key_type; struct key_direction_state kds; - /* for control channel we are only authenticating, not encrypting */ - kt.cipher_length = 0; - kt.cipher = NULL; - if (flags & GHK_INLINE) { /* key was specified inline, key text is in passphrase_file */ @@ -800,9 +795,9 @@ get_tls_handshake_key (const struct key_type *key_type, /* initialize hmac key in both directions */ - init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], &kt, OPENVPN_OP_ENCRYPT, + init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], key_type, OPENVPN_OP_ENCRYPT, "Outgoing Control Channel Authentication"); - init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], &kt, OPENVPN_OP_DECRYPT, + init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], key_type, OPENVPN_OP_DECRYPT, "Incoming Control Channel Authentication"); CLEAR (key2); diff --git a/src/openvpn/init.c b/src/openvpn/init.c index d0020b7..7e6e448 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2206,11 +2206,23 @@ do_init_crypto_tls_c1 (struct context *c) flags |= GHK_INLINE; file = options->tls_auth_file_inline; } - get_tls_handshake_key (&c->c1.ks.key_type, - &c->c1.ks.tls_auth_key, - file, - options->key_direction, - flags); + + /* Initialize key_type for tls-auth with auth only */ + CLEAR (c->c1.ks.tls_auth_key_type); + if (options->authname && options->authname_defined) + { + c->c1.ks.tls_auth_key_type.digest = md_kt_get (options->authname); + c->c1.ks.tls_auth_key_type.hmac_length = + md_kt_size (c->c1.ks.tls_auth_key_type.digest); + } + else + { + msg (M_FATAL, "ERROR: tls-auth enabled, but no valid --auth " + "algorithm specified ('%s')", options->authname); + } + + get_tls_handshake_key (&c->c1.ks.tls_auth_key_type, + &c->c1.ks.tls_auth_key, file, options->key_direction, flags); } #if 0 /* was: #if ENABLE_INLINE_FILES -- Note that enabling this code will break restarts */ @@ -2375,7 +2387,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) to.tls_auth.pid_persist = &c->c1.pid_persist; to.tls_auth.flags |= CO_PACKET_ID_LONG_FORM; crypto_adjust_frame_parameters (&to.frame, - &c->c1.ks.key_type, + &c->c1.ks.tls_auth_key_type, false, false, true, true); } @@ -3758,6 +3770,7 @@ inherit_context_child (struct context *dest, /* inherit SSL context */ dest->c1.ks.ssl_ctx = src->c1.ks.ssl_ctx; dest->c1.ks.tls_auth_key = src->c1.ks.tls_auth_key; + dest->c1.ks.tls_auth_key_type = src->c1.ks.tls_auth_key_type; #endif /* options */ diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h index 3f1df6e..71adf48 100644 --- a/src/openvpn/openvpn.h +++ b/src/openvpn/openvpn.h @@ -66,6 +66,7 @@ struct key_schedule struct tls_root_ctx ssl_ctx; /* optional authentication HMAC key for TLS control channel */ + struct key_type tls_auth_key_type; struct key_ctx_bi tls_auth_key; #else /* ENABLE_CRYPTO */ int dummy; -- 2.5.0