From patchwork Tue Dec 14 05:59:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 2180 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director15.mail.ord1d.rsapps.net ([172.30.191.6]) by backend41.mail.ord1d.rsapps.net with LMTP id MC/PF+nNuGHPWAAAqwncew (envelope-from ) for ; Tue, 14 Dec 2021 12:01:29 -0500 Received: from proxy9.mail.ord1d.rsapps.net ([172.30.191.6]) by director15.mail.ord1d.rsapps.net with LMTP id gCEROenNuGHREwAAIcMcQg (envelope-from ) for ; Tue, 14 Dec 2021 12:01:29 -0500 Received: from smtp5.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy9.mail.ord1d.rsapps.net with LMTPS id gM2hOOnNuGGdHgAA7h+8OQ (envelope-from ) for ; Tue, 14 Dec 2021 12:01:29 -0500 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: smtp5.gate.ord1d.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=gmail.com; dmarc=fail (p=none; dis=none) header.from=gmail.com X-Suspicious-Flag: YES X-Classification-ID: 7a391e8e-5cff-11ec-8dd6-525400d73c44-1-1 Received: from [216.105.38.7] ([216.105.38.7:38920] helo=lists.sourceforge.net) by smtp5.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 8C/6A-31357-8EDC8B16; Tue, 14 Dec 2021 12:01:28 -0500 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.94.2) (envelope-from ) id 1mxB9p-00036s-HX; Tue, 14 Dec 2021 17:00:06 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1mxB9j-00035U-EL for openvpn-devel@lists.sourceforge.net; Tue, 14 Dec 2021 17:00:00 +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:Cc:To:From:Sender:Reply-To: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=BOBpmRnRvGCL5ON4DFYiFh85piqevBn86UrW3ADXQ90=; b=jUsefj3Z9f+i1cg0nFfNAeG6cd HTSQ6z5vJ48Za9r1hIkSR8I4itprCABetaTAzdcuggUbOvUcuv7co25qKlqK+w2Vr9Geox3TvucKn hjEL9jcQxFhUq6wkEbTyuQ/YNhBBi6X4l5+QAKtqeFyBB122TaIbr5V5nggm3Lrv0Pno=; 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:Cc:To:From:Sender:Reply-To: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=BOBpmRnRvGCL5ON4DFYiFh85piqevBn86UrW3ADXQ90=; b=PtNcRbdOssaW3VRsA/AhFcdtCi 15qqo3/b1OXz47FfOT3m2T6XYEZHxb5YRBwFa3ZE0jdg6+qdLV5rwLFHCop3fH9cRdaEUBO+AV4// +nIYm9GPApY6s/ajCZuZgFhgQ5qr1dRedvUV30Uy1eGDPz9BpZ5sFghrdV9mHTLZgm/Y=; Received: from mail-il1-f177.google.com ([209.85.166.177]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) id 1mxB9j-00FKX7-Hi for openvpn-devel@lists.sourceforge.net; Tue, 14 Dec 2021 17:00:00 +0000 Received: by mail-il1-f177.google.com with SMTP id d14so15571859ila.1 for ; Tue, 14 Dec 2021 08:59:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BOBpmRnRvGCL5ON4DFYiFh85piqevBn86UrW3ADXQ90=; b=cnvnQXFsC6zdDXVKtqtcuuZPfB7m22mhEMuoQVxmDpQv51v7qLiX6nlbpU2DPMvIZu llH05ua1i90uW7X3To881nIufaJzsqFH7n4F4jewQEuuNV/ez0M79f0IcAKKCO+9fpSn +SBRykOeGIhnb8J6SxJu3n21qZkm3e3XqzkVuqJmdFUJ4rXb0Y75O1p6kQycSu6+UJHx bJOyNt4HeoxcYgF7GaSR63dJ1ZxzPFPlAQ3IpfxCA5B+4yp+mO9jLUk75i2ICxYdWEZt Lh++WH6L9mqMXOaZUc+MxXxwuZ00pPVlF3YuHXrhR/cI7h2T8jtF7yLHr+TrhxY3PsWO 9Y4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BOBpmRnRvGCL5ON4DFYiFh85piqevBn86UrW3ADXQ90=; b=65FzfRZx6qCR5PoUezi6K0XbGNtTwWjC/K1taG93TQnRPClWQ3mZ6WxKSiDI/kNU2y LqWdpd3Fq6y8OgDyncGEBtUawyq6bNVUw3B+p/Uc0kABf+QMHT9Mtd855toPQLa95d8Q djX5t41W1am7JwABa/GVtaPQewNZolD5FwwItDg3w0EVwxeGahAXE14u7cJy4I4mSP5g qmICjWRlby62b/eednxwassoqUFzynn6dVOQtVIFseiKyrfBEt5Yz/0qBwvLb196CwIo 2T0fVhSnGvvRxGamrTVtPEBAkISEIw0lH/1v4d/p79vIeNE+gHc4NXi1RLcdwVnhqjLA aUtg== X-Gm-Message-State: AOAM530DzsOl7QgkNuCm1njSWilpoYRmCkE/fOO1vRbIX5N6yEW8AOQT zRhs5XMAnA7ZNLzD7F3R2VzIXnqtPpQ= X-Google-Smtp-Source: ABdhPJxm57KdIPKJD2bXfBuo/7YfNGI+w4CSqCrlzTo6Vc8xVcDmTUeVBYP/Fl6IRqRXdkkoNWcytA== X-Received: by 2002:a05:6e02:144f:: with SMTP id p15mr4410622ilo.180.1639501193727; Tue, 14 Dec 2021 08:59:53 -0800 (PST) Received: from uranus.home.sansel.ca (bras-vprn-tnhlon4053w-lp130-02-70-51-223-8.dsl.bell.ca. [70.51.223.8]) by smtp.gmail.com with ESMTPSA id e9sm178778ilm.44.2021.12.14.08.59.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Dec 2021 08:59:53 -0800 (PST) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Tue, 14 Dec 2021 11:59:15 -0500 Message-Id: <20211214165928.30676-6-selva.nair@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211214165928.30676-1-selva.nair@gmail.com> References: <20211214165928.30676-1-selva.nair@gmail.com> MIME-Version: 1.0 X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Selva Nair - Add function to check when external key is in use - Load xkey provider into a custom library context when required Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.166.177 listed in wl.mailspike.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.166.177 listed in list.dnswl.org] -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 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 X-Headers-End: 1mxB9j-00FKX7-Hi Subject: [Openvpn-devel] [PATCH v3 05/18] Initialize the xkey provider and use it in SSL context 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 From: Selva Nair - Add function to check when external key is in use - Load xkey provider into a custom library context when required - Use the custom libctx in SSL CTX when external key is in use As no keys are yet loaded through the provider, no functionality gets delegated to it as yet. v2 changes: Provider loading is reworked to activate only when external keys are in use This was 2/9 in v1 Signed-off-by: Selva Nair Acked-By: Arne Schwabe --- src/openvpn/openssl_compat.h | 8 ++++ src/openvpn/options.c | 16 +++++++ src/openvpn/options.h | 2 + src/openvpn/ssl.c | 5 ++ src/openvpn/ssl.h | 6 +++ src/openvpn/ssl_mbedtls.c | 6 +++ src/openvpn/ssl_openssl.c | 93 +++++++++++++++++++++++++++++++++++- src/openvpn/xkey_common.h | 1 - 8 files changed, 134 insertions(+), 3 deletions(-) diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index dcc210c7..5c9da9eb 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -760,6 +760,14 @@ int EVP_PKEY_get_group_name(EVP_PKEY *pkey, char *gname, size_t gname_sz, #define EVP_CIPHER_get0_name EVP_CIPHER_name #define EVP_CIPHER_CTX_get_mode EVP_CIPHER_CTX_mode +/** Reduce SSL_CTX_new_ex() to SSL_CTX_new() for OpenSSL < 3 */ +#define SSL_CTX_new_ex(libctx, propq, method) \ + SSL_CTX_new((method)) + +/* Some safe typedefs to avoid too many ifdefs */ +typedef void OSSL_LIB_CTX; +typedef void OSSL_PROVIDER; + /* Mimics the functions but only when the default context without * options is chosen */ static inline const EVP_CIPHER * diff --git a/src/openvpn/options.c b/src/openvpn/options.c index b840b767..fb427410 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -5337,6 +5337,22 @@ show_compression_warning(struct compress_options *info) } #endif +bool key_is_external(const struct options *options) +{ + bool ret = false; +#ifdef ENABLE_MANAGEMENT + ret = ret || (options->management_flags & MF_EXTERNAL_KEY); +#endif +#ifdef ENABLE_PKCS11 + ret = ret || (options->pkcs11_providers[0] != NULL); +#endif +#ifdef ENABLE_CRYPTOAPI + ret = ret || options->cryptoapi_cert; +#endif + + return ret; +} + static void add_option(struct options *options, char *p[], diff --git a/src/openvpn/options.h b/src/openvpn/options.h index d4f41cd7..8dc06343 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -862,4 +862,6 @@ void options_string_import(struct options *options, unsigned int *option_types_found, struct env_set *es); +bool key_is_external(const struct options *options); + #endif /* ifndef OPTIONS_H */ diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 05096ee0..0c4e3234 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -603,6 +603,11 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx, bool in_ch tls_clear_error(); + if (key_is_external(options)) + { + load_xkey_provider(); + } + if (options->tls_server) { tls_ctx_server_new(new_ctx); diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index b14453fe..784ddd32 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -627,4 +627,10 @@ show_available_tls_ciphers(const char *cipher_list, bool tls_session_generate_data_channel_keys(struct tls_session *session); +/** + * Load ovpn.xkey provider used for external key signing + */ +void +load_xkey_provider(void); + #endif /* ifndef OPENVPN_SSL_H */ diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index 94605801..15cd8b16 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -1550,4 +1550,10 @@ get_ssl_library_version(void) return mbedtls_version; } +void +load_xkey_provider(void) +{ + return; /* no external key provider in mbedTLS build */ +} + #endif /* defined(ENABLE_CRYPTO_MBEDTLS) */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 724664bb..bdaa7a2b 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -45,6 +45,7 @@ #include "ssl_common.h" #include "base64.h" #include "openssl_compat.h" +#include "xkey_common.h" #ifdef ENABLE_CRYPTOAPI #include "cryptoapi.h" @@ -69,6 +70,10 @@ #include #endif +static OSSL_LIB_CTX *tls_libctx; + +static void unload_xkey_provider(void); + /* * Allocate space in SSL objects in which to store a struct tls_session * pointer back to parent. @@ -113,7 +118,7 @@ tls_ctx_server_new(struct tls_root_ctx *ctx) { ASSERT(NULL != ctx); - ctx->ctx = SSL_CTX_new(SSLv23_server_method()); + ctx->ctx = SSL_CTX_new_ex(tls_libctx, NULL, SSLv23_server_method()); if (ctx->ctx == NULL) { @@ -131,7 +136,7 @@ tls_ctx_client_new(struct tls_root_ctx *ctx) { ASSERT(NULL != ctx); - ctx->ctx = SSL_CTX_new(SSLv23_client_method()); + ctx->ctx = SSL_CTX_new_ex(tls_libctx, NULL, SSLv23_client_method()); if (ctx->ctx == NULL) { @@ -150,6 +155,7 @@ tls_ctx_free(struct tls_root_ctx *ctx) ASSERT(NULL != ctx); SSL_CTX_free(ctx->ctx); ctx->ctx = NULL; + unload_xkey_provider(); /* in case it is loaded */ } bool @@ -2284,4 +2290,87 @@ get_ssl_library_version(void) return OpenSSL_version(OPENSSL_VERSION); } + +/** Some helper routines for provider load/unload */ +#ifdef HAVE_XKEY_PROVIDER +static int +provider_load(OSSL_PROVIDER *prov, void *dest_libctx) +{ + const char *name = OSSL_PROVIDER_get0_name(prov); + OSSL_PROVIDER_load(dest_libctx, name); + return 1; +} + +static int +provider_unload(OSSL_PROVIDER *prov, void *unused) +{ + (void) unused; + OSSL_PROVIDER_unload(prov); + return 1; +} +#endif /* HAVE_XKEY_PROVIDER */ + +/** + * Setup ovpn.xey provider for signing with external keys. + * It is loaded into a custom library context so as not to pollute + * the default context. Alternatively we could override any + * system-wide property query set on the default context. But we + * want to avoid that. + */ +void +load_xkey_provider(void) +{ +#ifdef HAVE_XKEY_PROVIDER + + /* Make a new library context for use in TLS context */ + if (!tls_libctx) + { + tls_libctx = OSSL_LIB_CTX_new(); + check_malloc_return(tls_libctx); + + /* Load all providers in default LIBCTX into this libctx. + * OpenSSL has a child libctx functionality to automate this, + * but currently that is usable only from within providers. + * So we do something close to it manually here. + */ + OSSL_PROVIDER_do_all(NULL, provider_load, tls_libctx); + } + + if (!OSSL_PROVIDER_available(tls_libctx, "ovpn.xkey")) + { + OSSL_PROVIDER_add_builtin(tls_libctx, "ovpn.xkey", xkey_provider_init); + if (!OSSL_PROVIDER_load(tls_libctx, "ovpn.xkey")) + { + msg(M_NONFATAL, "ERROR: failed loading external key provider: " + "Signing with external keys will not work."); + } + } + + /* We only implement minimal functionality in ovpn.xkey, so we do not want + * methods in xkey to be picked unless absolutely required (i.e, when the key + * is external). Ensure this by setting a default propquery for the custom + * libctx that unprefers, but does not forbid, ovpn.xkey. See also man page + * of "property" in OpenSSL 3.0. + */ + EVP_set_default_properties(tls_libctx, "?provider!=ovpn.xkey"); + +#endif /* HAVE_XKEY_PROVIDER */ +} + +/** + * Undo steps in load_xkey_provider + */ +static void +unload_xkey_provider(void) +{ +#ifdef HAVE_XKEY_PROVIDER + if (tls_libctx) + { + OSSL_PROVIDER_do_all(tls_libctx, provider_unload, NULL); + OSSL_LIB_CTX_free(tls_libctx); + } +#endif /* HAVE_XKEY_PROVIDER */ + tls_libctx = NULL; +} + #endif /* defined(ENABLE_CRYPTO_OPENSSL) */ diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h index db58d077..f46bacd2 100644 --- a/src/openvpn/xkey_common.h +++ b/src/openvpn/xkey_common.h @@ -28,7 +28,6 @@ #include #if OPENSSL_VERSION_NUMBER >= 0x30000010L && !defined(DISABLE_XKEY_PROVIDER) #define HAVE_XKEY_PROVIDER 1 - #include #include