From patchwork Wed Jul 4 07:54:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steffan Karger X-Patchwork-Id: 403 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director11.mail.ord1d.rsapps.net ([172.27.255.59]) by backend30.mail.ord1d.rsapps.net (Dovecot) with LMTP id k66XCyYKPVuSBwAAIUCqbw for ; Wed, 04 Jul 2018 13:55:50 -0400 Received: from proxy11.mail.iad3a.rsapps.net ([172.27.255.59]) by director11.mail.ord1d.rsapps.net (Dovecot) with LMTP id SycYBSYKPVuSIAAAvGGmqA ; Wed, 04 Jul 2018 13:55:50 -0400 Received: from smtp37.gate.iad3a ([172.27.255.59]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy11.mail.iad3a.rsapps.net with LMTP id 2HjUAiYKPVuOHQAAxCvdqw ; Wed, 04 Jul 2018 13:55:50 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp37.gate.iad3a.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=karger-me.20150623.gappssmtp.com; dmarc=none (p=nil; dis=none) header.from=karger.me X-Suspicious-Flag: YES X-Classification-ID: 7bcf1f28-7fb3-11e8-a01c-525400dc5f6a-1-1 Received: from [216.105.38.7] ([216.105.38.7:40331] helo=lists.sourceforge.net) by smtp37.gate.iad3a.rsapps.net (envelope-from ) (ecelerity 4.2.1.56364 r(Core:4.2.1.14)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 59/FC-26805-52A0D3B5; Wed, 04 Jul 2018 13:55:49 -0400 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1falzM-0003TB-NS; Wed, 04 Jul 2018 17:54:48 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1falzL-0003SW-1B for openvpn-devel@lists.sourceforge.net; Wed, 04 Jul 2018 17:54:47 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=0/997kEdK75nvwdoo9i3oTxCofLcPjQiKuEObV+ZcsY=; b=I4GJ8KjqkFCnelT7TIQmKww5B1 XybKYzSKsvC4Ak0ghK/RggsSwEzzEAoVRSI1/L6TQIHiNQid7iHlF0AGAK3YrnMzec8oDBjuiEYKM IcFy+Kmn/Alvgiiby8w+DNjTcANPYOZqFMbA/ijNDzYYnPCaMOTAqaEvC6shwr2imX3U=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To :MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=0/997kEdK75nvwdoo9i3oTxCofLcPjQiKuEObV+ZcsY=; b=ROlV553oYUu1mMMThda628dOpX BncOw2+fhpwo1ZMjy88XoUsMCjsHZ5kq9ZYOlqjMfvUprMK0F9UTJRCfPY+ECViNq3gjjxPcsqwm1 OaKAaSnX1+QXZotZRqYhRNJVHvmxITIqYqcGU/SEFAA4jgLiJ+oTc90S1Gbfu5KZ1PzA=; Received: from mail-ed1-f47.google.com ([209.85.208.47]) by sfi-mx-4.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.90_1) id 1falzJ-00CwKk-Aw for openvpn-devel@lists.sourceforge.net; Wed, 04 Jul 2018 17:54:46 +0000 Received: by mail-ed1-f47.google.com with SMTP id x5-v6so894277edr.0 for ; Wed, 04 Jul 2018 10:54:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=karger-me.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0/997kEdK75nvwdoo9i3oTxCofLcPjQiKuEObV+ZcsY=; b=J/do7atxzdTUra/i3XhdLuinGCfrp5uaLf5KXrc2ep9v81JLrTKL2NJb1rBd33JOIA ZY+TU0WWjjZ3LYRQl0I7ihJsfDJJTyIZvQKoXJ1PxUc1ndeyXAbUe5bxRPvtz6M6iBAC UN7N3Hk6hRau93iQ+86Ychw4v1UKxe3eengrvdcS0VvDfY90zPOXG/IBwHkZU9l429o1 L/gdvmNgiYM2lCauj91PQ91ZMV7/nTIdl0X42Ny6ko6BL/XxMjjx1K43bSoLubnN5D+T jRNQwEW/1Ynn+C1Vw+DabUs9ojATPDnZj+1rSu6YG70VpEPmd9DZIhiGZegtz9u03SAL 7ebw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=0/997kEdK75nvwdoo9i3oTxCofLcPjQiKuEObV+ZcsY=; b=MftzUx+EZeYasFKZiMUwKe9DnRk3wjxbR85R5+ckvNiOBc3eojZU+eGCKAIJ3xPOjA WCK0SIi7RejMFch0STkkMixYgZgduLDsq8QMtV3VFg6aWG4VcNTwDRbx+cej98LGd4M2 VkDsY5zQGnqJnbyL6HuUKw/sbHrt/15c5fv4hXT41eDVBSRXUbXvPZKHm3b9vZZ2lYii xhH6W0FwIN+vo/WkI9xSQs3H2ozWFth4iwYe4/KPiw1F9lU9Yn2wRZG6PpBbbyIsYuwN t2MUOzTFoOgKQqaSDScBSZRsHi4vMT/4OtMSbuRMT4IhD8cb4GrJ8kGNlqs1TdGC2wos J+Ug== X-Gm-Message-State: APt69E22Qe1jXLYwhS2Q9/05VNfjDMDMLSxYCY9EVaohSfEL5ax8ArBw rFzwg9LjCO09y4CscqXG48HMTIRLEsw= X-Google-Smtp-Source: AAOMgpcjIPkr+wBPI+G0quvpa7xCBx6TCYjhNrTrZKsJmYRThh9HVuA2CEO4GhF0iuURNi0B3y7RzQ== X-Received: by 2002:a50:b178:: with SMTP id l53-v6mr3669530edd.306.1530726878276; Wed, 04 Jul 2018 10:54:38 -0700 (PDT) Received: from vesta.fritz.box ([2001:985:e54:1:f598:331e:3cdf:2649]) by smtp.gmail.com with ESMTPSA id o2-v6sm1948961edd.84.2018.07.04.10.54.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Jul 2018 10:54:37 -0700 (PDT) From: Steffan Karger To: openvpn-devel@lists.sourceforge.net Date: Wed, 4 Jul 2018 19:54:03 +0200 Message-Id: <20180704175404.22371-8-steffan@karger.me> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180704175404.22371-1-steffan@karger.me> References: <1512734870-17133-1-git-send-email-steffan.karger@fox-it.com> <20180704175404.22371-1-steffan@karger.me> X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [209.85.208.47 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.208.47 listed in wl.mailspike.net] 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 T_DKIMWL_WL_MED DKIMwl.org - Whitelisted Medium sender X-Headers-End: 1falzJ-00CwKk-Aw Subject: [Openvpn-devel] [PATCH v2 8/9] tls-crypt-v2: implement tls-crypt-v2 handshake X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: Steffan Karger This makes clients send-and-use, and servers receive-unwrap-and-use tls-crypt-v2 client keys, which completes the on-the-wire work. Signed-off-by: Steffan Karger --- src/openvpn/init.c | 39 +++++++++++++- src/openvpn/openvpn.h | 2 + src/openvpn/options.c | 5 ++ src/openvpn/ssl.c | 79 ++++++++++++++++++++++------ src/openvpn/ssl_common.h | 6 +++ src/openvpn/tls_crypt.c | 50 ++++++++++++++++++ src/openvpn/tls_crypt.h | 14 +++++ tests/unit_tests/openvpn/Makefile.am | 2 +- 8 files changed, 179 insertions(+), 18 deletions(-) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index c1454f36..0874edff 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2436,6 +2436,9 @@ key_schedule_free(struct key_schedule *ks, bool free_ssl_ctx) { tls_ctx_free(&ks->ssl_ctx); free_key_ctx_bi(&ks->tls_wrap_key); + free_key_ctx(&ks->tls_crypt_v2_server_key); + buf_clear(&ks->tls_crypt_v2_wkc); + free_buf(&ks->tls_crypt_v2_wkc); } CLEAR(*ks); } @@ -2604,6 +2607,24 @@ do_init_crypto_tls_c1(struct context *c) options->tls_crypt_inline, options->tls_server); } + /* tls-crypt with client-specific keys (--tls-crypt-v2) */ + if (options->tls_crypt_v2_file) + { + if (options->tls_server) + { + tls_crypt_v2_init_server_key(&c->c1.ks.tls_crypt_v2_server_key, + true, options->tls_crypt_v2_file, + options->tls_crypt_v2_inline); + } + else + { + tls_crypt_v2_init_client_key(&c->c1.ks.tls_wrap_key, + &c->c1.ks.tls_crypt_v2_wkc, + options->tls_crypt_v2_file, + options->tls_crypt_v2_inline); + } + } + c->c1.ciphername = options->ciphername; c->c1.authname = options->authname; c->c1.keysize = options->keysize; @@ -2823,13 +2844,28 @@ do_init_crypto_tls(struct context *c, const unsigned int flags) } /* TLS handshake encryption (--tls-crypt) */ - if (options->tls_crypt_file) + if (options->tls_crypt_file + || (options->tls_crypt_v2_file && options->tls_client)) { to.tls_wrap.mode = TLS_WRAP_CRYPT; to.tls_wrap.opt.key_ctx_bi = c->c1.ks.tls_wrap_key; to.tls_wrap.opt.pid_persist = &c->c1.pid_persist; to.tls_wrap.opt.flags |= CO_PACKET_ID_LONG_FORM; tls_crypt_adjust_frame_parameters(&to.frame); + + if (options->tls_crypt_v2_file) + { + to.tls_wrap.tls_crypt_v2_wkc = &c->c1.ks.tls_crypt_v2_wkc; + } + } + + if (options->tls_crypt_v2_file) + { + to.tls_crypt_v2 = true; + if (options->tls_server) + { + to.tls_wrap.tls_crypt_v2_server_key = c->c1.ks.tls_crypt_v2_server_key; + } } /* If we are running over TCP, allow for @@ -4359,6 +4395,7 @@ inherit_context_child(struct context *dest, dest->c1.ks.ssl_ctx = src->c1.ks.ssl_ctx; dest->c1.ks.tls_wrap_key = src->c1.ks.tls_wrap_key; dest->c1.ks.tls_auth_key_type = src->c1.ks.tls_auth_key_type; + dest->c1.ks.tls_crypt_v2_server_key = src->c1.ks.tls_crypt_v2_server_key; /* inherit pre-NCP ciphers */ dest->c1.ciphername = src->c1.ciphername; dest->c1.authname = src->c1.authname; diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h index c5c767c0..96cff870 100644 --- a/src/openvpn/openvpn.h +++ b/src/openvpn/openvpn.h @@ -66,6 +66,8 @@ struct key_schedule /* optional TLS control channel wrapping */ struct key_type tls_auth_key_type; struct key_ctx_bi tls_wrap_key; + struct key_ctx tls_crypt_v2_server_key; + struct buffer tls_crypt_v2_wkc; /**< Wrapped client key */ }; /* diff --git a/src/openvpn/options.c b/src/openvpn/options.c index c1d53a96..60be7d15 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -2739,6 +2739,11 @@ options_postprocess_verify_ce(const struct options *options, const struct connec { msg(M_USAGE, "--tls-auth and --tls-crypt are mutually exclusive"); } + if (options->client && options->tls_crypt_v2_file + && (options->tls_auth_file || options->tls_crypt_file)) + { + msg(M_USAGE, "--tls-crypt-v2, --tls-auth and --tls-crypt are mutually exclusive in client mode"); + } } else { diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index bfe37fcd..9fc1efa3 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -1055,6 +1055,23 @@ tls_session_user_pass_enabled(struct tls_session *session) /** @addtogroup control_processor * @{ */ +/** Free the elements of a tls_wrap_ctx structure */ +static void tls_wrap_free(struct tls_wrap_ctx *tls_wrap) +{ + if (packet_id_initialized(&tls_wrap->opt.packet_id)) + { + packet_id_free(&tls_wrap->opt.packet_id); + } + + if (tls_wrap->cleanup_key_ctx) + { + free_key_ctx_bi(&tls_wrap->opt.key_ctx_bi); + } + + free_buf(&tls_wrap->tls_crypt_v2_metadata); + free_buf(&tls_wrap->work); +} + /** @name Functions for initialization and cleanup of tls_session structures * @{ */ @@ -1147,16 +1164,9 @@ tls_session_init(struct tls_multi *multi, struct tls_session *session) static void tls_session_free(struct tls_session *session, bool clear) { - int i; - - if (packet_id_initialized(&session->tls_wrap.opt.packet_id)) - { - packet_id_free(&session->tls_wrap.opt.packet_id); - } + tls_wrap_free(&session->tls_wrap); - free_buf(&session->tls_wrap.work); - - for (i = 0; i < KS_SIZE; ++i) + for (size_t i = 0; i < KS_SIZE; ++i) { key_state_free(&session->key[i], false); } @@ -1482,6 +1492,8 @@ write_control_auth(struct tls_session *session, ASSERT(reliable_ack_write (ks->rec_ack, buf, &ks->session_id_remote, max_ack, prepend_ack)); + msg(D_TLS_DEBUG, "%s(): %s", __func__, packet_opcode_name(opcode)); + if (session->tls_wrap.mode == TLS_WRAP_AUTH || session->tls_wrap.mode == TLS_WRAP_NONE) { @@ -1499,17 +1511,26 @@ write_control_auth(struct tls_session *session, ASSERT(buf_init(&session->tls_wrap.work, buf->offset)); ASSERT(buf_write(&session->tls_wrap.work, &header, sizeof(header))); ASSERT(session_id_write(&session->session_id, &session->tls_wrap.work)); - if (tls_crypt_wrap(buf, &session->tls_wrap.work, &session->tls_wrap.opt)) - { - /* Don't change the original data in buf, it's used by the reliability - * layer to resend on failure. */ - *buf = session->tls_wrap.work; - } - else + if (!tls_crypt_wrap(buf, &session->tls_wrap.work, &session->tls_wrap.opt)) { buf->len = 0; return; } + + if (opcode == P_CONTROL_HARD_RESET_CLIENT_V3) + { + if (!buf_copy(&session->tls_wrap.work, + session->tls_wrap.tls_crypt_v2_wkc)) + { + msg(D_TLS_ERRORS, "Could not append tls-crypt-v2 client key"); + buf->len = 0; + return; + } + } + + /* Don't change the original data in buf, it's used by the reliability + * layer to resend on failure. */ + *buf = session->tls_wrap.work; } *to_link_addr = &ks->remote_addr; } @@ -1525,6 +1546,16 @@ read_control_auth(struct buffer *buf, struct gc_arena gc = gc_new(); bool ret = false; + const uint8_t opcode = *(BPTR(buf)) >> P_OPCODE_SHIFT; + if (opcode == P_CONTROL_HARD_RESET_CLIENT_V3 + && !tls_crypt_v2_extract_client_key(buf, ctx)) + { + msg (D_TLS_ERRORS, + "TLS Error: can not extract tls-crypt-v2 client key from %s", + print_link_socket_actual(from, &gc)); + goto cleanup; + } + if (ctx->mode == TLS_WRAP_AUTH) { struct buffer null = clear_buf(); @@ -1564,6 +1595,18 @@ read_control_auth(struct buffer *buf, ASSERT(buf_copy(buf, &tmp)); buf_clear(&tmp); } + else if (ctx->tls_crypt_v2_server_key.cipher) + { + /* If tls-crypt-v2 is enabled, require *some* wrapping */ + msg(D_TLS_ERRORS, "TLS Error: could not determine wrapping from %s", + print_link_socket_actual(from, &gc)); + /* TODO Do we want to support using tls-crypt-v2 and no control channel + * wrapping at all simultaneously? That would allow server admins to + * upgrade clients one-by-one without running a second instance, but we + * should not enable it by default because it breaks DoS-protection. + * So, add something like --tls-crypt-v2-allow-insecure-fallback ? */ + goto cleanup; + } if (ctx->mode == TLS_WRAP_NONE || ctx->mode == TLS_WRAP_AUTH) { @@ -3864,6 +3907,10 @@ tls_pre_decrypt_lite(const struct tls_auth_standalone *tas, /* HMAC test, if --tls-auth was specified */ status = read_control_auth(&newbuf, &tls_wrap_tmp, from); free_buf(&newbuf); + if (tls_wrap_tmp.cleanup_key_ctx) + { + free_key_ctx_bi(&tls_wrap_tmp.opt.key_ctx_bi); + } if (!status) { goto error; diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h index e3c852af..d744881c 100644 --- a/src/openvpn/ssl_common.h +++ b/src/openvpn/ssl_common.h @@ -213,6 +213,12 @@ struct tls_wrap_ctx } mode; /**< Control channel wrapping mode */ struct crypto_options opt; /**< Crypto state */ struct buffer work; /**< Work buffer (only for --tls-crypt) */ + struct key_ctx tls_crypt_v2_server_key; /**< Decrypts client keys */ + const struct buffer *tls_crypt_v2_wkc; /**< Wrapped client key, + sent to server */ + struct buffer tls_crypt_v2_metadata; /**< Received from client */ + bool cleanup_key_ctx; /**< opt.key_ctx_bi is owned by + this context */ }; /* diff --git a/src/openvpn/tls_crypt.c b/src/openvpn/tls_crypt.c index cb0d5faf..0180a753 100644 --- a/src/openvpn/tls_crypt.c +++ b/src/openvpn/tls_crypt.c @@ -33,6 +33,7 @@ #include "crypto.h" #include "platform.h" #include "session_id.h" +#include "ssl.h" #include "tls_crypt.h" @@ -519,6 +520,55 @@ error_exit: return ret; } +bool +tls_crypt_v2_extract_client_key(struct buffer *buf, + struct tls_wrap_ctx *ctx) +{ + static const int hard_reset_length = + TLS_CRYPT_OFF_CT + sizeof(uint8_t) + sizeof(packet_id_type); + + if (!ctx->tls_crypt_v2_server_key.cipher) + { + msg (D_TLS_ERRORS, + "Client want tls-crypt-v2, but no server key present."); + return false; + } + + msg (D_HANDSHAKE, "Control Channel: using tls-crypt-v2 key"); + + struct buffer wrapped_client_key = *buf; + if (!buf_advance(&wrapped_client_key, hard_reset_length)) + { + msg (D_TLS_ERRORS, "Can not locate tls-crypt-v2 client key"); + return false; + } + + struct key2 client_key = { 0 }; + ctx->tls_crypt_v2_metadata = alloc_buf(TLS_CRYPT_V2_MAX_METADATA_LEN); + if (!tls_crypt_v2_unwrap_client_key(&client_key, + &ctx->tls_crypt_v2_metadata, + wrapped_client_key, + &ctx->tls_crypt_v2_server_key)) + { + msg (D_TLS_ERRORS, "Can not unwrap tls-crypt-v2 client key"); + secure_memzero(&client_key, sizeof(client_key)); + return false; + } + + /* Load the decrypted key */ + ctx->mode = TLS_WRAP_CRYPT; + ctx->cleanup_key_ctx = true; + ctx->opt.flags |= CO_PACKET_ID_LONG_FORM; + memset(&ctx->opt.key_ctx_bi, 0, sizeof(ctx->opt.key_ctx_bi)); + tls_crypt_v2_load_client_key(&ctx->opt.key_ctx_bi, &client_key, true); + secure_memzero(&client_key, sizeof(client_key)); + + /* Remove client key from buffer so tls-crypt code can unwrap message */ + ASSERT(buf_inc_len(buf, -(BLEN(&wrapped_client_key)))); + + return true; +} + void tls_crypt_v2_write_server_key_file(const char *filename) { diff --git a/src/openvpn/tls_crypt.h b/src/openvpn/tls_crypt.h index 746f3be8..6521144e 100644 --- a/src/openvpn/tls_crypt.h +++ b/src/openvpn/tls_crypt.h @@ -83,6 +83,7 @@ #include "buffer.h" #include "crypto.h" #include "session_id.h" +#include "ssl_common.h" #define TLS_CRYPT_TAG_SIZE (256/8) #define TLS_CRYPT_PID_SIZE (sizeof(packet_id_type) + sizeof(net_time_t)) @@ -181,6 +182,19 @@ void tls_crypt_v2_init_client_key(struct key_ctx_bi *key, const char *key_file, const char *key_inline); +/** + * Extract a tls-crypt-v2 client key from a P_CONTROL_HARD_RESET_CLIENT_V3 + * message, and load the key into the supplied tls wrap context. + * + * @param buf Buffer containing a received P_CONTROL_HARD_RESET_CLIENT_V3 + * message. + * @param ctx tls-wrap context to be initialized with the client key. + * + * @returns true if a key was successfully extracted. + */ +bool tls_crypt_v2_extract_client_key(struct buffer *buf, + struct tls_wrap_ctx *ctx); + /** * Generate a tls-crypt-v2 server key, and write to file. * diff --git a/tests/unit_tests/openvpn/Makefile.am b/tests/unit_tests/openvpn/Makefile.am index 1ff62615..b51973fa 100644 --- a/tests/unit_tests/openvpn/Makefile.am +++ b/tests/unit_tests/openvpn/Makefile.am @@ -59,7 +59,7 @@ packet_id_testdriver_SOURCES = test_packet_id.c mock_msg.c \ tls_crypt_testdriver_CFLAGS = @TEST_CFLAGS@ \ -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \ - $(OPTIONAL_CRYPTO_CFLAGS) + $(OPTIONAL_CRYPTO_CFLAGS) $(OPTIONAL_PKCS11_HELPER_CFLAGS) tls_crypt_testdriver_LDFLAGS = @TEST_LDFLAGS@ \ $(OPTIONAL_CRYPTO_LIBS) tls_crypt_testdriver_SOURCES = test_tls_crypt.c mock_msg.c \