From patchwork Sun May 24 10:33:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Bottomley X-Patchwork-Id: 1123 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director10.mail.ord1d.rsapps.net ([172.27.255.7]) by backend30.mail.ord1d.rsapps.net with LMTP id 6GMXOKPayl7aMgAAIUCqbw for ; Sun, 24 May 2020 16:35:47 -0400 Received: from proxy4.mail.iad3a.rsapps.net ([172.27.255.7]) by director10.mail.ord1d.rsapps.net with LMTP id 0ILgNaPayl6kfQAApN4f7A ; Sun, 24 May 2020 16:35:47 -0400 Received: from smtp31.gate.iad3a ([172.27.255.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy4.mail.iad3a.rsapps.net with LMTP id EDnRMKPayl4jHAAA8Zvu4w ; Sun, 24 May 2020 16:35:47 -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: smtp31.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=hansenpartnership.com; dmarc=fail (p=none; dis=none) header.from=hansenpartnership.com X-Suspicious-Flag: YES X-Classification-ID: 25b4d61c-9dfe-11ea-af60-5254003d9392-1-1 Received: from [216.105.38.7] ([216.105.38.7:51522] helo=lists.sourceforge.net) by smtp31.gate.iad3a.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 36/31-10615-3AADACE5; Sun, 24 May 2020 16:35:47 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jcxKx-0006c8-35; Sun, 24 May 2020 20:35:11 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jcxKw-0006by-G0 for openvpn-devel@lists.sourceforge.net; Sun, 24 May 2020 20:35:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: 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=s3vwBM9QnJ3PrXf2GoGcGhgDUMAixPwybkxJe15MZhY=; b=Nyq6fDuc9tPAf1cIl8to4XT2NK MBxewk+9jZG55lOgmR33QHnOuzngseP2QO9wbYdD1WV7xOyliMDBne9x9FFPPiFuML8UNxAcZMPve az1VAGG+h7irtVkqClgAVRiXRcGHaZ4m6IwUcnm6vxOMG2lm/iQJZzHg61R4mH1kDCPU=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: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=s3vwBM9QnJ3PrXf2GoGcGhgDUMAixPwybkxJe15MZhY=; b=EwHPGLBufzfncw1p6a8KEq/1oi khCaie3GKsuVMYLzUE+56V0rpq6srZ1iuuuMBdJOIcaKu2AaCeKMr9iKgFpuGdFi6MlwXFUu++qEU DjlQTA5l4gMFXN5PUjVLuHY2iVPdvmR0BpQl5t5AvXb5043DpX6eArcNI+7q5LTMKXck=; Received: from bedivere.hansenpartnership.com ([66.63.167.143]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jcxKu-002DAE-AT for openvpn-devel@lists.sourceforge.net; Sun, 24 May 2020 20:35:10 +0000 Received: from localhost (localhost [127.0.0.1]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id D57CB8EE17F for ; Sun, 24 May 2020 13:34:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=hansenpartnership.com; s=20151216; t=1590352495; bh=XqLJggbCWF0N3JHjKJVqf3BZKjKHzgsKzt+DC8DZ4uc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=muShKHFoKVLXA7gCZVhRMqTerRFLTZvU0Ph/fk/4lb8H/gAtl47MAG9QJMAw4R9oY 3dkn8+ymbPDNcwB3xBToJt7em3k1DghjLVOa9Di0fE4ByacI7eFe72mGBHDN/DywBG 98kdEQROhN2hyoxnG9Et3OJg0cjejEDUzBrAFzDI= Received: from bedivere.hansenpartnership.com ([127.0.0.1]) by localhost (bedivere.hansenpartnership.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4t4IEBoSJO_3 for ; Sun, 24 May 2020 13:34:55 -0700 (PDT) Received: from jarvis.lan (jarvis.ext.hansenpartnership.com [153.66.160.226]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 863B28EE173 for ; Sun, 24 May 2020 13:34:55 -0700 (PDT) From: James Bottomley To: openvpn-devel@lists.sourceforge.net Date: Sun, 24 May 2020 13:33:21 -0700 Message-Id: <20200524203322.15885-2-James.Bottomley@HansenPartnership.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200524203322.15885-1-James.Bottomley@HansenPartnership.com> References: <20200524203322.15885-1-James.Bottomley@HansenPartnership.com> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1jcxKu-002DAE-AT Subject: [Openvpn-devel] [PATCH v5 1/2] openssl: add engine method for loading the key 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox As well as doing crypto acceleration, engines can also be used to load key files. If the engine is set, and the private key loading fails for bio methods, this patch makes openvpn try to get the engine to load the key. If that succeeds, we end up using an engine based key. This can be used with the openssl tpm engines to make openvpn use a TPM wrapped key file. Signed-off-by: James Bottomley --- v2: add better configuration guarding v4: - use crypto_msg() instead of raw openssl prints - remove ENGINE_init/finish(). Openvpn already initializes the engine so doing a second initialization is wrong. - don't clear the openssl errors from the BIO_read failure just in case they might be useful. - ad ui.h include for openssl 1.1 build failure v5: add engine init --- src/openvpn/crypto_openssl.c | 56 ++++++++++++++++++++++++++++++++++++ src/openvpn/crypto_openssl.h | 12 ++++++++ src/openvpn/ssl_openssl.c | 5 ++++ 3 files changed, 73 insertions(+) diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index a5b2c45a..a7569623 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -63,6 +63,7 @@ #endif #if HAVE_OPENSSL_ENGINE +#include #include static bool engine_initialized = false; /* GLOBAL */ @@ -1070,4 +1071,59 @@ memcmp_constant_time(const void *a, const void *b, size_t size) { return CRYPTO_memcmp(a, b, size); } + +#if HAVE_OPENSSL_ENGINE +static int +ui_reader(UI *ui, UI_STRING *uis) +{ + SSL_CTX *ctx = UI_get0_user_data(ui); + + if (UI_get_string_type(uis) == UIT_PROMPT) { + pem_password_cb *cb = SSL_CTX_get_default_passwd_cb(ctx); + void *d = SSL_CTX_get_default_passwd_cb_userdata(ctx); + char password[64]; + + cb(password, sizeof(password), 0, d); + UI_set_result(ui, uis, password); + + return 1; + } + return 0; +} +#endif + +EVP_PKEY * +engine_load_key(const char *file, SSL_CTX *ctx) +{ +#if HAVE_OPENSSL_ENGINE + UI_METHOD *ui; + EVP_PKEY *pkey; + + if (!engine_persist) + return NULL; + + /* this will print out the error from BIO_read */ + crypto_msg(M_INFO, "PEM_read_bio failed, now trying engine method to load private key"); + + ui = UI_create_method("openvpn"); + if (!ui) { + crypto_msg(M_FATAL, "Engine UI creation failed"); + return NULL; + } + + UI_method_set_reader(ui, ui_reader); + + ENGINE_init(engine_persist); + pkey = ENGINE_load_private_key(engine_persist, file, ui, ctx); + ENGINE_finish(engine_persist); + if (!pkey) + crypto_msg(M_FATAL, "Engine could not load key file"); + out: + UI_destroy_method(ui); + return pkey; +#else + return NULL; +#endif +} + #endif /* ENABLE_CRYPTO_OPENSSL */ diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h index 64754480..7449fbd3 100644 --- a/src/openvpn/crypto_openssl.h +++ b/src/openvpn/crypto_openssl.h @@ -107,4 +107,16 @@ cipher_kt_var_key_size(const cipher_kt_t *cipher) return EVP_CIPHER_flags(cipher) & EVP_CIPH_VARIABLE_LENGTH; } +/** + * Load a key file from an engine + * + * @param file The engine file to load + * @param ui The UI method for the password prompt + * @param data The data to pass to the UI method + * + * @return The private key if successful or NULL if not + */ +EVP_PKEY * +engine_load_key(const char *file, SSL_CTX *ctx); + #endif /* CRYPTO_OPENSSL_H_ */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 06c836da..a489053b 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -1020,6 +1020,11 @@ tls_ctx_load_priv_file(struct tls_root_ctx *ctx, const char *priv_key_file, pkey = PEM_read_bio_PrivateKey(in, NULL, SSL_CTX_get_default_passwd_cb(ctx->ctx), SSL_CTX_get_default_passwd_cb_userdata(ctx->ctx)); + if (!pkey) + { + pkey = engine_load_key(priv_key_file, ctx->ctx); + } + if (!pkey || !SSL_CTX_use_PrivateKey(ssl_ctx, pkey)) { #ifdef ENABLE_MANAGEMENT