From patchwork Wed Sep 22 11:12:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 1972 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director7.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id UFL9FK+cS2GTCQAAIUCqbw (envelope-from ) for ; Wed, 22 Sep 2021 17:14:23 -0400 Received: from proxy15.mail.ord1d.rsapps.net ([172.30.191.6]) by director7.mail.ord1d.rsapps.net with LMTP id mCCwFK+cS2GtOgAAovjBpQ (envelope-from ) for ; Wed, 22 Sep 2021 17:14:23 -0400 Received: from smtp12.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy15.mail.ord1d.rsapps.net with LMTPS id QNJ5FK+cS2HNYgAAAY1PeQ (envelope-from ) for ; Wed, 22 Sep 2021 17:14:23 -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: smtp12.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: 0ebb1118-1bea-11ec-8dce-52540070b731-1-1 Received: from [216.105.38.7] ([216.105.38.7:49780] helo=lists.sourceforge.net) by smtp12.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 4D/0C-02441-EAC9B416; Wed, 22 Sep 2021 17:14:23 -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.92.3) (envelope-from ) id 1mT9YJ-0006sI-NT; Wed, 22 Sep 2021 21:13:15 +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.92.3) (envelope-from ) id 1mT9YI-0006s5-Gk for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:14 +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=UKo9+1zYjl91+Jn+l+Ijkx9vpbStFUfewUGAYbT8yC8=; b=O3cKyA5QoV7aU9xbDIuPQfUfzt ds9Zpa/4yz87KgBQMdyV5pAAlDtKS7IZDiLi2uBrEnwVJc9AWNkvxOPR1jbBv5HNGrFJWlPwl+swm gFMUilaeHLQVt5FQzZGzvd86uUY8q+ij1jet/hvCrlkt4NiwdN9asihgI6nX/2PN+OxQ=; 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=UKo9+1zYjl91+Jn+l+Ijkx9vpbStFUfewUGAYbT8yC8=; b=hpZQAa+L13+j+rCxAXEzTrkK/E 0NwECYQ5HTnVPHx4sxhTGGCASrok2uVg+L7I3ziJEA8plgKMBsUCfulqqViy58+mvNC0oaHf+mylZ Ih3BpsHpY+mIIztrDkHTeJaqI2oCu+mZRAFECfd+QhFv4jQKH2CtrqlkWm/UkY6DkLYA=; Received: from mail-qk1-f179.google.com ([209.85.222.179]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) id 1mT9YC-0022xr-Oz for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:14 +0000 Received: by mail-qk1-f179.google.com with SMTP id t4so14453911qkb.9 for ; Wed, 22 Sep 2021 14:13:08 -0700 (PDT) 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=UKo9+1zYjl91+Jn+l+Ijkx9vpbStFUfewUGAYbT8yC8=; b=I5GV1YORg/1Tc1BbJD3ud7+WI8PRJu+ue2BBQksZFj4MEvlc0QuokhAHdAdy2iSTYE eycZcQURRUPRF9i2vJ1qSU9wnTkx0gLum2yENTAu76S3mQniO5SZW7GkzeYZlrkiOoyg Y7Vbo+W29VGvEVr0QPQLSfayq2n6GYh1JZHVXmDv7z99JDAb1spF/QEGM9OxLsyGtbcV z93MkuXpF0Irc3Gu+hLxTnT74BzBMn60Thj+puPb+nkNm8ADFy+dwG9juLFWLIlXr5/V EImC4FXDcckHWf+6/pgzw5wJdZu4U42obGRjhQhf+9yBYyM9hsKiADM4bkfi32VBFHBO e1sQ== 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=UKo9+1zYjl91+Jn+l+Ijkx9vpbStFUfewUGAYbT8yC8=; b=PwIG/T30ZFCrUvXP+JAjQ5Qz+9u5XIKrYfvoa7Sh34p51+g+Aai4+61/jrQVdkb+5I fQOfpiS5P55ecPKS24jc/v6CuM2l0p/zZWYXCjN2z6NABLQYdKvPbOg5sfkmdeomg02M +ecjEAs739O7JhMJpdUcP5A0ozNYqMPnx+kvMTcKLZVGVfEYi3GChhR9D62EDkTrtbKe ooZgx8ipNmxCZ8sI2968CwAFvIwML7MSyLGDQw1yqzHsyBOAoh6bfFyI7gTePIFk7oz7 CH1fTeWkIbrCd2uIc0XeXQqIkfcy3X+MOzz/uxMRjAmt+84XRODuekluW2fewhsEOUlH A9Dg== X-Gm-Message-State: AOAM533dHXe/+mXzAGEvciLeLoJ83Yasu+8jm7TEP5o6l0bzCzY8Akc0 /tApwlJ/xvGVwuLR6aE/1b5FBDr04uM= X-Google-Smtp-Source: ABdhPJzrOBmIzwpbIrumBSze7PbnNoulstpKv5Zf9GF6xyZi4T4Hbw2BHAjynES5tYicmOXQwthraw== X-Received: by 2002:a37:8044:: with SMTP id b65mr1498914qkd.150.1632345182769; Wed, 22 Sep 2021 14:13:02 -0700 (PDT) Received: from uranus.home.sansel.ca (bras-vprn-tnhlon4053w-lp130-02-70-51-223-227.dsl.bell.ca. [70.51.223.227]) by smtp.gmail.com with ESMTPSA id l7sm2185243qth.19.2021.09.22.14.13.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Sep 2021 14:13:02 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Wed, 22 Sep 2021 17:12:46 -0400 Message-Id: <20210922211254.7570-2-selva.nair@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210922211254.7570-1-selva.nair@gmail.com> References: <20210922211254.7570-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 Hooking into callbacks in RSA_METHOD and EVP_PKEY_METHOD structures is deprecated in OpenSSL 3.0. For signing with external keys that are not exportable (tokens, stores, etc.) requires a custom provid [...] Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.222.179 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.222.179 listed in wl.mailspike.net] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from 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: 1mT9YC-0022xr-Oz Subject: [Openvpn-devel] [PATCH 1/9] A built-in provider for using external key with OpenSSL 3.0 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 Hooking into callbacks in RSA_METHOD and EVP_PKEY_METHOD structures is deprecated in OpenSSL 3.0. For signing with external keys that are not exportable (tokens, stores, etc.) requires a custom provider interface so that key operations are done under its context. A single provider is enough for handling all external keys we support -- management-external-key, cryptoapicert(CNG) and pkcs11-helper. The series of patches starting with this implement such a provider. To activate the use of the provider, essentially, the SSL_CTX object is created with property string set to to prioritize our provider. In the provider we implement only keymgmt and signature operations. All other operations get directly used from the default provider. However, signature operations include verify using peer's public key as well. In particular, we get called for both DigestVerify and DigestSign operations. For the former we call back OpenSSL, for the latter we compute the digest using OpenSSL and then pass it to the backend for signature. So a lot of glue code is needed and this makes the patches somewhat large even after splitting into many commits. This patch implements only the provider_init function so that it can be loaded, but has no capabilities. The required interfaces are added in following commits. Signed-off-by: Selva Nair --- configure.ac | 11 +++ src/openvpn/Makefile.am | 1 + src/openvpn/xkey_common.h | 42 +++++++++ src/openvpn/xkey_provider.c | 177 ++++++++++++++++++++++++++++++++++++ 4 files changed, 231 insertions(+) create mode 100644 src/openvpn/xkey_common.h create mode 100644 src/openvpn/xkey_provider.c diff --git a/configure.ac b/configure.ac index 7c2ead6a..0390a05e 100644 --- a/configure.ac +++ b/configure.ac @@ -821,6 +821,17 @@ if test "${with_crypto_library}" = "openssl"; then AC_DEFINE([HAVE_OPENSSL_ENGINE], [1], [OpenSSL engine support available]) fi + have_openssl_provider="yes" + AC_CHECK_FUNCS( + [OSSL_PROVIDER_load] + , + , + [have_openssl_provider="no"; break] + ) + if test "${have_openssl_provider}" = "yes"; then + AC_DEFINE([HAVE_XKEY_PROVIDER], [1], [External key loading provider can be used]) + fi + AC_CHECK_FUNC( [EVP_aes_256_gcm], , diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index 5883c291..432efe73 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -128,6 +128,7 @@ openvpn_SOURCES = \ tls_crypt.c tls_crypt.h \ tun.c tun.h \ vlan.c vlan.h \ + xkey_provider.c xkey_common.h \ win32.h win32.c \ win32-util.h win32-util.c \ cryptoapi.h cryptoapi.c diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h new file mode 100644 index 00000000..eb31604f --- /dev/null +++ b/src/openvpn/xkey_common.h @@ -0,0 +1,42 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2021 Selva Nair + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef XKEY_PUBLIC_H_ +#define XKEY_PUBLIC_H_ + +#ifdef HAVE_XKEY_PROVIDER + +#include +#include + +/** + * Initialization function for OpenVPN external key provider for OpenSSL + * Follows the signature of OSSL_PROVIDER init + */ +OSSL_provider_init_fn xkey_provider_init; + +#endif /* HAVE_XKEY_PROVIDER */ + +#define XKEY_PROV_PROPS "provider=ovpn.xkey" + +#endif /* XKEY_PUBLIC_H_ */ diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c new file mode 100644 index 00000000..9d19d37d --- /dev/null +++ b/src/openvpn/xkey_provider.c @@ -0,0 +1,177 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2021 Selva Nair + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#ifdef HAVE_XKEY_PROVIDER + +#include "syshead.h" +#include "error.h" +#include "buffer.h" +#include "xkey_common.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +/* A descriptive name */ +static const char *provname = "OpenVPN External Key Provider"; + +typedef struct +{ + const OSSL_CORE_HANDLE *core; + OSSL_PROVIDER *deflt; /* default provider that we load for delegating some ops */ + OSSL_LIB_CTX *libctx; /* libctx of the core context in which we are running */ +} XKEY_PROVIDER_CTX; + +/* main provider interface */ + +/* provider callbacks we implement */ +static OSSL_FUNC_provider_query_operation_fn query_operation; +static OSSL_FUNC_provider_gettable_params_fn gettable_params; +static OSSL_FUNC_provider_get_params_fn get_params; +static OSSL_FUNC_provider_teardown_fn teardown; + +static const OSSL_ALGORITHM * +query_operation(void *provctx, int op, int *no_store) +{ + dmsg(D_LOW, "In xkey provider query op with op = %d", op); + + *no_store = 0; + + switch (op) + { + case OSSL_OP_SIGNATURE: + return NULL; + + case OSSL_OP_KEYMGMT: + return NULL; + + default: + break; + } + return NULL; +} + +static const OSSL_PARAM * +gettable_params(void *provctx) +{ + dmsg(D_LOW, "In xkey provider gettable_params"); + + static const OSSL_PARAM param_types[] = { + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0), + OSSL_PARAM_END + }; + + return param_types; +} +static int +get_params(void *provctx, OSSL_PARAM params[]) +{ + OSSL_PARAM *p; + + dmsg(D_LOW, "In xkey provider get_params"); + + p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME); + if (p) + { + return (OSSL_PARAM_set_utf8_ptr(p, provname) != 0); + } + + return 0; +} + +static void +teardown(void *provctx) +{ + dmsg(D_LOW, "In xkey provider teardown"); + + XKEY_PROVIDER_CTX *prov = provctx; + if (prov && prov->deflt) + { + OSSL_PROVIDER_unload(prov->deflt); + } + free(prov); +} + +static const OSSL_DISPATCH dispatch_table[] = { + {OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))gettable_params}, + {OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))get_params}, + {OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))query_operation}, + {OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))teardown}, + {0, NULL} +}; + +int +xkey_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in, + const OSSL_DISPATCH **out, void **provctx) +{ + XKEY_PROVIDER_CTX *prov; + OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL; + + dmsg(D_LOW, "In xkey provider init"); + + prov = calloc(sizeof(*prov), 1); + if (!prov) + { + msg(M_NONFATAL, "xkey_provider_init: out of memory"); + return 0; + } + + /* get our libctx */ + for (; in->function_id != 0; in++) + { + if (in->function_id == OSSL_FUNC_CORE_GET_LIBCTX) + { + c_get_libctx = OSSL_FUNC_core_get_libctx(in); + } + } + + if (c_get_libctx) + { + prov->libctx = (OSSL_LIB_CTX *)c_get_libctx(handle); + } + prov->core = handle; + + prov->deflt = OSSL_PROVIDER_load(prov->libctx, "default"); + if (!prov->deflt) + { + msg(M_NONFATAL, "xkey_provider_init: default provider could not be loaded"); + } + + *out = dispatch_table; + *provctx = prov; + + return 1; +} + +#endif /* HAVE_XKEY_PROVIDER */ From patchwork Wed Sep 22 11:12:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 1967 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director11.mail.ord1d.rsapps.net ([172.31.255.6]) by backend30.mail.ord1d.rsapps.net with LMTP id 4J3GEKqcS2FVCQAAIUCqbw (envelope-from ) for ; Wed, 22 Sep 2021 17:14:18 -0400 Received: from proxy19.mail.iad3b.rsapps.net ([172.31.255.6]) by director11.mail.ord1d.rsapps.net with LMTP id CGqWEKqcS2HjBAAAvGGmqA (envelope-from ) for ; Wed, 22 Sep 2021 17:14:18 -0400 Received: from smtp38.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy19.mail.iad3b.rsapps.net with LMTPS id SDtWCKqcS2EaRAAAIG4riQ (envelope-from ) for ; Wed, 22 Sep 2021 17:14:18 -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: smtp38.gate.iad3b.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: 0b85b61a-1bea-11ec-8d84-5254006f0979-1-1 Received: from [216.105.38.7] ([216.105.38.7:57132] helo=lists.sourceforge.net) by smtp38.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 78/DE-22704-9AC9B416; Wed, 22 Sep 2021 17:14:17 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1mT9YQ-0005AU-Ip; Wed, 22 Sep 2021 21:13:22 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mT9YJ-00059p-3K for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:15 +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=lYsWRtl2z2UL7JnDOuImU+1f8DfKkaXEIZPrJueeVR8=; b=P6jOcSFkjzNdxusYqin3clcCnF j+MgkxhmOYUkPJyP00JwwExsWGh4rpwytwtS5JKncWnN6gSMR4yI6he1P21iXMFMS91WTbn1fuvwy njPm9UbJZvC/Xap9eTQNpyjWOS55aP8RV1uBFpUWnTzjJ2W8Xq8cWhISNI65g/UEyly0=; 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=lYsWRtl2z2UL7JnDOuImU+1f8DfKkaXEIZPrJueeVR8=; b=iLSPZHXFKH154G/5CmmAuYdeyn q7wBXfjGaTmrqtQ8OR1ktCMAmT7rXfyuA2RsVtJNiwPbIKwFdsyq8yYdvq23x7Pf7ftN/5QrX+O1J O4Qaio0a7yiaxbF9WrxzeuubgFcUdR99feguipPL+OzZ3sXYAw47YKzKtMnjFcm+ylEI=; Received: from mail-qk1-f175.google.com ([209.85.222.175]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) id 1mT9YD-0005zl-UQ for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:15 +0000 Received: by mail-qk1-f175.google.com with SMTP id q81so10975876qke.5 for ; Wed, 22 Sep 2021 14:13:09 -0700 (PDT) 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=lYsWRtl2z2UL7JnDOuImU+1f8DfKkaXEIZPrJueeVR8=; b=WxjZE+YVXTRLkjLZ6YEZkyLW9Os/OrYms40MITpqTrIcuBx6T1mVhGwN9lmrEbK2sc W3PGvwxa46C5qahYMwoDxu9NNVpztznbkHwtW8HpFgw6nW70WGpVtAox7JrRusIt3igC BX9JUKS23fdEKMJM4wSxjsikRx2nGiafuQEEVlR46WDkPjDJli94dAF/hJadVStS6Qiv DKkAi2BnfmHwHpd7M6Sha+T442yFYQQJ/0/X2Q0iMMbxdo6ARptJ9PF9YznPWxXj6Rte 4u7/73etFf88Ovm8F1FZb+71qeT5eDcN4UuRxgU8l6s0lcF1cv7z6XIHlPqvure/E9kP ZhdA== 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=lYsWRtl2z2UL7JnDOuImU+1f8DfKkaXEIZPrJueeVR8=; b=s/onYUQlbEujOaBcXmKmRRxyz3dFtceKKDzePvG0MjAo7AslaQzNvCqsWcXe2K4lRR 5A+6IuUxNbuZbsT9pPVvRVOArVXlxwqGvT3HHXmIEOAu40hf/yjoe6KO2mmvpDFZrWaL 6rhiiav0O8jbAYTAdGFhMOIZtJ3khSN1us5sWALGtNN9d+55hM+H9+AzaeaF8QoVuJuo u+Gv5MEYTTlF8V5xmKCClH1Sn7pheqMzajpusFdSOMmbcckgzZv9xCp/KjhPPRZ3Ngg+ pMK9LjgHVFrHU5YA0MtppUMUmz3esMV4vfPIWoJnPj7PbA7xWbavzQi4HTPWnHD1pAoS ZePA== X-Gm-Message-State: AOAM5337ZFOnm5beOSID8s2g9EZ71tJuXAD/lL/rRHOb+F2lQbS9QOvA esIbI4KGmjiHVjzi0G4+3FQ6kTla2Xw= X-Google-Smtp-Source: ABdhPJzmAsXN4vdo8tVbpBoVQqxoMt0qeqpqsOfK8QocM3zy1EYqGPrEGRsSZthsTVj7iD7R8WjxQg== X-Received: by 2002:a37:6146:: with SMTP id v67mr1482065qkb.242.1632345183854; Wed, 22 Sep 2021 14:13:03 -0700 (PDT) Received: from uranus.home.sansel.ca (bras-vprn-tnhlon4053w-lp130-02-70-51-223-227.dsl.bell.ca. [70.51.223.227]) by smtp.gmail.com with ESMTPSA id l7sm2185243qth.19.2021.09.22.14.13.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Sep 2021 14:13:03 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Wed, 22 Sep 2021 17:12:47 -0400 Message-Id: <20210922211254.7570-3-selva.nair@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210922211254.7570-1-selva.nair@gmail.com> References: <20210922211254.7570-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 - The provider is loaded during crypto initialization and unloaded in uninit. The SSL server and client context are created with properties indicating preference for this provider. 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 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.222.175 listed in wl.mailspike.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.222.175 listed in list.dnswl.org] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from 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: 1mT9YD-0005zl-UQ Subject: [Openvpn-devel] [PATCH 2/9] 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 - The provider is loaded during crypto initialization and unloaded in uninit. The SSL server and client context are created with properties indicating preference for this provider. This could be made conditional on use of external keys, but it can't hurt if loaded and used otherwise too. Useful to get the code exercised at least for a period of testing. As the provider is empty, no functionality gets delegated to it as yet. Verb 4 logs with enable-debug will just show the provider_init and teardown called. Signed-off-by: Selva Nair --- src/openvpn/crypto_openssl.c | 19 +++++++++++++++++++ src/openvpn/openssl_compat.h | 12 ++++++++++++ src/openvpn/ssl_openssl.c | 7 +++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index 419265a5..5d7fa847 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -42,6 +42,7 @@ #include "crypto.h" #include "crypto_backend.h" #include "openssl_compat.h" +#include "xkey_common.h" #include #include @@ -75,6 +76,8 @@ static bool engine_initialized = false; /* GLOBAL */ static ENGINE *engine_persist = NULL; /* GLOBAL */ +static void *xkey_prov; + /* Try to load an engine in a shareable library */ static ENGINE * try_load_engine(const char *engine) @@ -161,6 +164,15 @@ crypto_init_lib(void) OPENSSL_config(NULL); #endif #endif /* _WIN32 */ + +#ifdef HAVE_XKEY_PROVIDER + if (!xkey_prov) + { + OSSL_PROVIDER_add_builtin(NULL, "ovpn.xkey", xkey_provider_init); + xkey_prov = OSSL_PROVIDER_load(NULL, "ovpn.xkey"); + } +#endif + /* * If you build the OpenSSL library and OpenVPN with * CRYPTO_MDEBUG, you will get a listing of OpenSSL @@ -190,6 +202,13 @@ crypto_uninit_lib(void) engine_initialized = false; } #endif +#ifdef HAVE_XKEY_PROVIDER + if (xkey_prov) + { + OSSL_PROVIDER_unload(xkey_prov); + } +#endif + xkey_prov = NULL; } void diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index ce8e2b36..3dcdde4d 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -718,4 +718,16 @@ SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max) return 1; } #endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(ENABLE_CRYPTO_WOLFSSL) */ + +/** Mimics SSL_CTX_new_ex for OpenSSL < 3 */ +#if OPENSSL_VERSION_NUMBER < 0x30000000L +static inline SSL_CTX * +SSL_CTX_new_ex(void *libctx, const char *propq, const SSL_METHOD *method) +{ + (void) libctx; + (void) propq; + return SSL_CTX_new(method); +} +#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ + #endif /* OPENSSL_COMPAT_H_ */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 241206fb..61256620 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" @@ -109,7 +110,8 @@ tls_ctx_server_new(struct tls_root_ctx *ctx) { ASSERT(NULL != ctx); - ctx->ctx = SSL_CTX_new(SSLv23_server_method()); + const char *propq = "?" XKEY_PROV_PROPS; + ctx->ctx = SSL_CTX_new_ex(NULL, propq, SSLv23_server_method()); if (ctx->ctx == NULL) { @@ -127,7 +129,8 @@ tls_ctx_client_new(struct tls_root_ctx *ctx) { ASSERT(NULL != ctx); - ctx->ctx = SSL_CTX_new(SSLv23_client_method()); + const char *propq = "?" XKEY_PROV_PROPS; + ctx->ctx = SSL_CTX_new_ex(NULL, propq, SSLv23_client_method()); if (ctx->ctx == NULL) { From patchwork Wed Sep 22 11:12:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 1964 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director7.mail.ord1d.rsapps.net ([172.31.255.6]) by backend30.mail.ord1d.rsapps.net with LMTP id KOPBGaecS2FVCQAAIUCqbw (envelope-from ) for ; Wed, 22 Sep 2021 17:14:15 -0400 Received: from proxy8.mail.iad3b.rsapps.net ([172.31.255.6]) by director7.mail.ord1d.rsapps.net with LMTP id sNuHGaecS2FCPAAAovjBpQ (envelope-from ) for ; Wed, 22 Sep 2021 17:14:15 -0400 Received: from smtp25.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy8.mail.iad3b.rsapps.net with LMTPS id 6GErEqecS2EMWwAAoCsc3g (envelope-from ) for ; Wed, 22 Sep 2021 17:14:15 -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: smtp25.gate.iad3b.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: 09aed5b0-1bea-11ec-b6e0-52540030a522-1-1 Received: from [216.105.38.7] ([216.105.38.7:50888] helo=lists.sourceforge.net) by smtp25.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id DE/8D-13837-6AC9B416; Wed, 22 Sep 2021 17:14:15 -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 1mT9YM-00079b-4X; Wed, 22 Sep 2021 21:13:18 +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 1mT9YJ-00079D-B8 for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:15 +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=0mRKQv3SECsG9au41u7PEECNDP2cq6T+2/d/2vsNHyI=; b=DjUSQNGRsXGxaluxWOwJ2hUJx/ 4iPnGXEuDiW/q88pXsUrmOvOW4xwzVnAhYloHnc/BVg2FbOif8QjM7bCYSN/SUhwHJASgWbe1x0Yy QfAeYs3ZQX5i+iBVFfV532ezHfT4AKh2SsCCi2IMvZjunuJSMLRhoPup5bo1yHLxlLjs=; 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=0mRKQv3SECsG9au41u7PEECNDP2cq6T+2/d/2vsNHyI=; b=dQ1ceoo5CJ0vDKzotPXOnn6mWT GXeunKegz75OdD8b2anhP+joPxOa7izV8yxlqsQESFSRIhy1en2Oio28tMDENMnDjKskakyao9tl5 mnjrsm/CCYf1lec5mlPEPUEsWzZ3QOhUQijv44EGOrZppN7z4LJJ3rjlxqzUxTYnQ+eo=; Received: from mail-qt1-f171.google.com ([209.85.160.171]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) id 1mT9YE-0022yN-No for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:15 +0000 Received: by mail-qt1-f171.google.com with SMTP id r16so4127093qtw.11 for ; Wed, 22 Sep 2021 14:13:10 -0700 (PDT) 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=0mRKQv3SECsG9au41u7PEECNDP2cq6T+2/d/2vsNHyI=; b=bhn5UJRqeprrAtX8Z+EXZSjXFm2b1kL5qM51n2+Mbd8cazrZIHKodMdRWB1QjoDqY4 mXfU/x0XO7twTcuJiGr51ujaabsA6GapyMbbGdfc/6e3fetgkb4RltNQcvJsd3tvP+2o 78TOT6LZ1d4WHAyUyn6THYctSE4vEggi8j9YUUuGf4NLd9VBCSV8OM82GF8XaldyNYWM aM1OgxI70NLvZ//pkzNPF8Jse+xGx6vwg/yCh9Wca+WiS4Hc9h6K/H2+i1JuW783nLkg epOC5+lGvfE1TTeyokGsJj4zXiSPsuS5J0Kd0MJMSx0FWSc9DGzxb/hmZ25rEYy7e8Kw MA+Q== 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=0mRKQv3SECsG9au41u7PEECNDP2cq6T+2/d/2vsNHyI=; b=jVyXUhU3Ydp4QXelUxfHPAEJvGUQXcIQZKt+Jxd7fnzzoQfgbOEI8NzKWDgIvqwGWc ZeVYY2b/m+O7KEVsVZxAsO0/EsKwtXFf0uw5O6bXJZQ3FKAAU1H2KNdrb8jDYX+Lz7RE mOvV8lNlB7MUFol+xzaKbDE4AapeQaSCxrvh4AyP6jbaRDMQqTgUeWODFBisYL+RZEoo R0r4S4W+JwiyLMrc06mmaElAkZj0bryytZtuoVCDSjy4vcCEti7XbUFcLOI6nE92qoSs e/uIWKwA5JKuHlOhk9BaPWgXhB9WfNOCJ8F/Zub0P1a3ldfCE32Rvw9PtFy/b5N9LnuK 9Rqw== X-Gm-Message-State: AOAM531h+KD97IYji1fmk54AOForEAVlrWSwr33DomTfS6c7KguCps1w jtHEcPffpsQm9oakTA2ewNnrd1DiF/w= X-Google-Smtp-Source: ABdhPJz0kx135UoDPHTeaCrgA8ilLH6cAjMZ5jVEDVKfCkywTKVPfLfROFNf+FggpvlcuLxOEnS2pw== X-Received: by 2002:a05:622a:4d4:: with SMTP id q20mr1458858qtx.271.1632345184709; Wed, 22 Sep 2021 14:13:04 -0700 (PDT) Received: from uranus.home.sansel.ca (bras-vprn-tnhlon4053w-lp130-02-70-51-223-227.dsl.bell.ca. [70.51.223.227]) by smtp.gmail.com with ESMTPSA id l7sm2185243qth.19.2021.09.22.14.13.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Sep 2021 14:13:04 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Wed, 22 Sep 2021 17:12:48 -0400 Message-Id: <20210922211254.7570-4-selva.nair@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210922211254.7570-1-selva.nair@gmail.com> References: <20210922211254.7570-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 A minimal set of functions for keymgmt are implemented. No support for external key import as yet, only native keys. Support for native keys is required as all public key ops will get delegated to us [...] 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 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.160.171 listed in wl.mailspike.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.160.171 listed in list.dnswl.org] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from 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: 1mT9YE-0022yN-No Subject: [Openvpn-devel] [PATCH 3/9] Implement keymgmt in the xkey provider 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 A minimal set of functions for keymgmt are implemented. No support for external key import as yet, only native keys. Support for native keys is required as all public key ops will get delegated to us once SSL_CTX is initialized in our context. This will include digest-verify using peer's public key. To test key import, use the normal --key operation, change use_xkey_provider() to return true. The key will import correctly but signing will fail as there is no signature interface in the provider yet. (use enable-debug for the dmsg() chatter). Sign-verify operations for native keys is in the next commit. Signed-off-by: Selva Nair --- src/openvpn/xkey_provider.c | 353 ++++++++++++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c index 9d19d37d..4e5ed130 100644 --- a/src/openvpn/xkey_provider.c +++ b/src/openvpn/xkey_provider.c @@ -43,6 +43,9 @@ #include #include +/* propq set all on all ops we implement */ +static const char *const props = XKEY_PROV_PROPS; + /* A descriptive name */ static const char *provname = "OpenVPN External Key Provider"; @@ -53,6 +56,353 @@ typedef struct OSSL_LIB_CTX *libctx; /* libctx of the core context in which we are running */ } XKEY_PROVIDER_CTX; +typedef enum +{ + ORIGIN_NONAME = 0, + OPENSSL_NATIVE, /* native key imported in */ + EXTERNAL_KEY +} XKEY_ORIGIN; + +/* + * XKEY_KEYDATA: Our keydata encapsulation: + * --------------------------------------- + * We keep an opaque handle provided by the backend for the loaded + * key. It's passed back to the backend for any operation on private + * keys --- in practice, sign() op only. + * + * We also keep the public key in the form of a native OpenSSL EVP_PKEY. + * This allows us to do all public ops by calling ops in the default provider. + */ +typedef struct +{ + /* opaque handle dependent on KEY_ORIGIN -- could be NULL */ + void *handle; + /* associated public key as an openvpn native key */ + EVP_PKEY *pubkey; + /* origin of key -- native or external */ + XKEY_ORIGIN origin; + int refcount; /* reference count */ +} XKEY_KEYDATA; + +#define KEYTYPE(key) ((key)->pubkey ? EVP_PKEY_get_id((key)->pubkey) : 0) +#define KEYSIZE(key) ((key)->pubkey ? EVP_PKEY_get_size((key)->pubkey) : 0) + +/* keymgmt provider */ + +/* keymgmt callbacks we implement */ +static OSSL_FUNC_keymgmt_new_fn keymgmt_new; +static OSSL_FUNC_keymgmt_free_fn keymgmt_free; +static OSSL_FUNC_keymgmt_load_fn keymgmt_load; +static OSSL_FUNC_keymgmt_has_fn keymgmt_has; +static OSSL_FUNC_keymgmt_match_fn keymgmt_match; +static OSSL_FUNC_keymgmt_import_fn rsa_keymgmt_import; +static OSSL_FUNC_keymgmt_import_fn ec_keymgmt_import; +static OSSL_FUNC_keymgmt_import_types_fn keymgmt_types; +static OSSL_FUNC_keymgmt_get_params_fn keymgmt_get_params; +static OSSL_FUNC_keymgmt_gettable_params_fn keymgmt_gettable; +static OSSL_FUNC_keymgmt_query_operation_name_fn rsa_keymgmt_name; +static OSSL_FUNC_keymgmt_query_operation_name_fn ec_keymgmt_name; + +static XKEY_KEYDATA * +keydata_new() +{ + dmsg(D_LOW, "In keydata_new"); + + XKEY_KEYDATA *key = calloc(sizeof(*key), 1); + if (!key) + { + msg(M_NONFATAL, "xkey_keydata_new: out of memory"); + } + + return key; +} + +static void +keydata_free(XKEY_KEYDATA *key) +{ + dmsg(D_LOW, "In keydata_free"); + + if (!key || --key->refcount <= 0) /* free when refcount goes to zero */ + { + return; + } + if (key->pubkey) + { + EVP_PKEY_free(key->pubkey); + } + free(key); +} + +static void * +keymgmt_new(void *provctx) +{ + dmsg(D_LOW, "In keymgmt_new"); + + XKEY_KEYDATA *key = keydata_new(); + return key; +} + +static void * +keymgmt_load(const void *reference, size_t reference_sz) +{ + dmsg(D_LOW, "In keymgmt_load"); + + return NULL; +} + +/** + * Key import function + * When key operations like sign/verify are done in our context + * the key gets imported into us. + * + * For native keys we get called with standard OpenSSL params + * appropriate for the key. We just use it to create a native + * EVP_PKEY from params and assign to keydata->handle. + * + * Import of external keys -- to be implemented + */ +static int +keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[], const char *name) +{ + dmsg(D_LOW, "In keymgmt_import"); + + XKEY_KEYDATA *key = keydata; + + /* Our private key is immutable -- we import only if keydata is empty */ + + if (key->handle || key->pubkey + || !(selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY)) + { + msg(M_WARN, "Error: keymgmt_import: keydata not empty or selection not allowed"); + return 0; + } + + /* create a native public key and assign it to key->pubkey */ + EVP_PKEY *pkey = NULL; + + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, name, NULL); + if (!ctx + || (EVP_PKEY_fromdata_init(ctx) != 1) + || (EVP_PKEY_fromdata(ctx, &pkey, selection, (OSSL_PARAM*) params) !=1)) + { + msg(M_WARN, "Error: keymgmt_import failed for key type <%s>", name); + if (pkey) + { + EVP_PKEY_free(pkey); + } + return 0; + } + + key->pubkey = pkey; + key->origin = OPENSSL_NATIVE; + if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) + { + /* just use the same key as handle -- do not up-ref */ + key->handle = pkey; + } + return 1; +} + +static int +rsa_keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[]) +{ + dmsg(D_LOW, "In rsa_keymgmt_import"); + return keymgmt_import(keydata, selection, params, "RSA"); +} + +static int +ec_keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[]) +{ + dmsg(D_LOW, "In ec_keymgmt_import"); + return keymgmt_import(keydata, selection, params, "EC"); +} + +/* This function has to exist for key import to work + * though we do not support import of individual params + * like n or e. We simply return an empty list here for + * both rsa and ec, which works. + */ +static const OSSL_PARAM * +keymgmt_import_types(int selection) +{ + dmsg(D_LOW, "In keymgmt import types"); + + static const OSSL_PARAM key_types[] = { + OSSL_PARAM_END + }; + + if (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) + { + return key_types; + } + return NULL; +} + +/* We do not support any key export */ + +static void +keymgmt_free(void *keydata) +{ + dmsg(D_LOW, "In keymgmt_free"); + keydata_free(keydata); +} + +static int +keymgmt_has(const void *keydata, int selection) +{ + dmsg(D_LOW, "In keymgmt_has with selection = %d", selection); + + const XKEY_KEYDATA *key = keydata; + int ok = (key != NULL); + + if (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) + { + ok = ok && key->pubkey; + } + if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) + { + ok = ok && key->handle; + } + + return ok; +} + +static int +keymgmt_match(const void *keydata1, const void *keydata2, int selection) +{ + const XKEY_KEYDATA *key1 = keydata1; + const XKEY_KEYDATA *key2 = keydata2; + + dmsg(D_LOW, "In keymgmt_match"); + int ret = 1; + + if (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY + && key1->pubkey && key2->pubkey) + { + ret = ret && EVP_PKEY_eq(key1->pubkey, key2->pubkey); + } + + if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) + { + ret = ret && (key1->origin == key2->origin); /* origins must match */ + if (key1->origin == OPENSSL_NATIVE) + { + ret = ret && EVP_PKEY_eq(key1->pubkey, key2->pubkey); + } + /* private key is opaque. We can only check identity of the handle */ + else + { + ret = ret && (key1->handle == key2->handle); + } + } + + return ret; +} + +/* A minimal set of key params that we can return */ +static const OSSL_PARAM * +keymgmt_gettable_params(void *provctx) +{ + dmsg(D_LOW, "In keymgmt_gettable"); + static OSSL_PARAM gettable[] = { + OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), + OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), + OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), + OSSL_PARAM_END + }; + return gettable; +} + +static int +keymgmt_get_params(void *keydata, OSSL_PARAM *params) +{ + dmsg(D_LOW, "In keymgmt_get_params"); + + XKEY_KEYDATA *key = keydata; + if (!key || !key->pubkey) + { + return 0; + } + + return EVP_PKEY_get_params(key->pubkey, params); +} + +/** + * If the key is an encapsulated native key, we just call + * EVP_PKEY_set_params in the default context. Only those params + * supported by the default provider would work in that case. + */ +static int +keymgmt_set_params(void *keydata, const OSSL_PARAM *params) +{ + XKEY_KEYDATA *key = keydata; + ASSERT(key); + + if (key->origin != OPENSSL_NATIVE) + { + return 0; /* to be implemented */ + } + else if (key->handle == NULL) /* once handle is set our key is immutable */ + { + /* pubkey is always native -- just delegate */ + return EVP_PKEY_set_params(key->pubkey, (OSSL_PARAM *)params); + } + else + { + msg(M_WARN, "xkey keymgmt_set_params: key is immutable"); + } + return 1; +} + +static const char * +rsa_keymgmt_name(int id) +{ + dmsg(D_LOW, "In rsa_keymgmt_name"); + return "RSA"; +} + +static const char * +ec_keymgmt_name(int id) +{ + dmsg(D_LOW, "In ec_keymgmt_name"); + return "EC"; +} + +static const OSSL_DISPATCH rsa_keymgmt_functions[] = { + {OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))keymgmt_new}, + {OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))keymgmt_free}, + {OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))keymgmt_load}, + {OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))keymgmt_has}, + {OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))keymgmt_match}, + {OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))rsa_keymgmt_import}, + {OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))keymgmt_import_types}, + {OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void)) keymgmt_gettable_params}, + {OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void)) keymgmt_get_params}, + {OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))rsa_keymgmt_name}, + {0, NULL } +}; + +static const OSSL_DISPATCH ec_keymgmt_functions[] = { + {OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))keymgmt_new}, + {OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))keymgmt_free}, + {OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))keymgmt_load}, + {OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))keymgmt_has}, + {OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))keymgmt_match}, + {OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ec_keymgmt_import}, + {OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))keymgmt_import_types}, + {OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void)) keymgmt_gettable_params}, + {OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void)) keymgmt_get_params}, + {OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))ec_keymgmt_name}, + {0, NULL } +}; + +const OSSL_ALGORITHM keymgmts[] = { + {"RSA:rsaEncryption", props, rsa_keymgmt_functions}, + {"RSA-PSS:RSASSA-PSS", props, rsa_keymgmt_functions}, + {"EC:id-ecPublicKey", props, ec_keymgmt_functions}, + {NULL, NULL, NULL} +}; + /* main provider interface */ /* provider callbacks we implement */ @@ -74,6 +424,9 @@ query_operation(void *provctx, int op, int *no_store) return NULL; case OSSL_OP_KEYMGMT: + return keymgmts; + + case OSSL_OP_STORE: return NULL; default: From patchwork Wed Sep 22 11:12:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 1970 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director7.mail.ord1d.rsapps.net ([172.31.255.6]) by backend30.mail.ord1d.rsapps.net with LMTP id gzuQC6ycS2GKCQAAIUCqbw (envelope-from ) for ; Wed, 22 Sep 2021 17:14:20 -0400 Received: from proxy9.mail.iad3b.rsapps.net ([172.31.255.6]) by director7.mail.ord1d.rsapps.net with LMTP id 4CBtCqycS2GFOgAAovjBpQ (envelope-from ) for ; Wed, 22 Sep 2021 17:14:20 -0400 Received: from smtp18.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy9.mail.iad3b.rsapps.net with LMTPS id MPsfBaycS2FnGwAAC4PSzw (envelope-from ) for ; Wed, 22 Sep 2021 17:14:20 -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: smtp18.gate.iad3b.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: 0c607e8a-1bea-11ec-a6f0-5254009ad1d4-1-1 Received: from [216.105.38.7] ([216.105.38.7:57160] helo=lists.sourceforge.net) by smtp18.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 69/E6-19168-BAC9B416; Wed, 22 Sep 2021 17:14:19 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1mT9YT-0005B9-Si; Wed, 22 Sep 2021 21:13:25 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mT9YJ-0005A0-J1 for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:15 +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=CUIDe/IZuUgu8sQaYfqfs1rVbjOo8Jc4akW20+FSQaY=; b=Tdpurqr7p+Sv9Aks/yJVrFmwqb Uu/DaF7WcVPspRMMRVyLYZ2nnoSW3dwLKgK//noC5MNcl1GukK3RVMlJ2zPOh6X99hpIztLUxCgvW fxDArAb1Fo3NV17apOVveUusIHeJcxNDMeiJz1BZAeV/7hOO7lwIIlatQJE33VGUd3po=; 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=CUIDe/IZuUgu8sQaYfqfs1rVbjOo8Jc4akW20+FSQaY=; b=dewZvZpFjWD8Ap2bw1nJ9M8tBL WolCxmI9PfXJJrh/dia0G0KacYUtArqReIvxuzeTFTITcSN/KbaWwOXsjqFy2eWquuXb8CDcEnCep ZWX+g90Y5Xs6Qd3OEOzGPFglmnrsE3W26mbRScgy02z7LMPuET+/MXYSTvkCBGNzEsl8=; Received: from mail-qk1-f172.google.com ([209.85.222.172]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) id 1mT9YF-0005zx-ML for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:15 +0000 Received: by mail-qk1-f172.google.com with SMTP id f130so14642095qke.6 for ; Wed, 22 Sep 2021 14:13:11 -0700 (PDT) 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=CUIDe/IZuUgu8sQaYfqfs1rVbjOo8Jc4akW20+FSQaY=; b=dVhJ6e2TdDyhHvEKnCKhJCqS1U/Dnl4WQb5k/9dI6M5zDaSmR1ajboh1xWSP58MwuX MgW1xBNw6yIagpCSg4OCk0CybyRyn7KmagTXdytAHhW216REDnnpFMIXwb0/Zyao6vNS EUzcRFOi7hQA+0xzXQGyt9LInG/TEDJLVefSi26eyEaSB/RVxpP2T0l4Z+FPmVlFoEuX jToagSiYXDrIPsGMydiV372KXx/KTPAjQ/hysUoeDwgH7plVBBhdPvhmPwc6hA2HuT3Q eFbJ2lzXkm83DX8/nKdGDxSPO1ddInvqg19MJUarXYXsLSZkYOokPQG7MOvwld6Y4N9L +ogw== 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=CUIDe/IZuUgu8sQaYfqfs1rVbjOo8Jc4akW20+FSQaY=; b=fwrFWoeXPUIGC6HIKKLfCnV8abovTPNznOFyUILmPPiyHk8sAeC3kGFqoNwx+qp7sT OGNFlu5zOIhx6KnwttS3GFxRUJUtfRGIqO1hRaXgTIza2rcidxAa3xuw5Pvw8SpHxdfR o9CPuU4dqnknsS9/gZd29cvnye5wMj91N1Uand4WUtUXzCYuQfMn7e1YxwL6H0hxnckK pLPmLRv9Gjf90U8sivFMb8f1bTAbFd7Fcs9MoZPmlqeR3qPoQWMkwBO2Kg/73i/8+16z 4HCh/m7DOivDZCQIJ8wMJNV9AeO7BmZSmb2xaBdlR7F8TUIk/BK9RWw7xk+gjXS8uuvr 0t1Q== X-Gm-Message-State: AOAM530nIbTdkn6dAb1tOZcQKm7PWw+gpoFm7/i3C702Jjqu3ahkeo+Q Zs35dFUET2fkgNSs7C8fFoVonROnz+s= X-Google-Smtp-Source: ABdhPJwGbCAUdOtT42PLc8vfmBYMdkK7hhpOVaiAwQiMk1wEhb8oTkg1S8C+0bT2A5oqvakbSsCPpg== X-Received: by 2002:a37:aa8f:: with SMTP id t137mr1394710qke.381.1632345185556; Wed, 22 Sep 2021 14:13:05 -0700 (PDT) Received: from uranus.home.sansel.ca (bras-vprn-tnhlon4053w-lp130-02-70-51-223-227.dsl.bell.ca. [70.51.223.227]) by smtp.gmail.com with ESMTPSA id l7sm2185243qth.19.2021.09.22.14.13.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Sep 2021 14:13:05 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Wed, 22 Sep 2021 17:12:49 -0400 Message-Id: <20210922211254.7570-5-selva.nair@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210922211254.7570-1-selva.nair@gmail.com> References: <20210922211254.7570-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 - DigestVerify and Sign operations for native keys are implemented. DigestVerify ops for native keys are needed because operations on peer's public key will get delegated to us. Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.222.172 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.222.172 listed in wl.mailspike.net] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from 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: 1mT9YF-0005zx-ML Subject: [Openvpn-devel] [PATCH 4/9] Implement provider interface for signature operations 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 - DigestVerify and Sign operations for native keys are implemented. DigestVerify ops for native keys are needed because operations on peer's public key will get delegated to us. Sign operations on native keys are also implemented which now allows us to enable the provider in SSL_CTX with private key in a file (for testing). To test use --key and --cert in the config. Provider function calls are logged at verb = 4 if configured with --enable-debug. As external keys are currently supported by hooks into RSA or EVP_PKEY interface, it will continue work bypassing the provider. Even in those cases ops with peer's public key are done by our provider as those are initialized by OpenSSL using the provider interface. Subsequent commits will move all these into the provider framework. Signed-off-by: Selva Nair --- src/openvpn/xkey_common.h | 36 +++ src/openvpn/xkey_provider.c | 486 +++++++++++++++++++++++++++++++++++- 2 files changed, 521 insertions(+), 1 deletion(-) diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h index eb31604f..0cb76db1 100644 --- a/src/openvpn/xkey_common.h +++ b/src/openvpn/xkey_common.h @@ -39,4 +39,40 @@ OSSL_provider_init_fn xkey_provider_init; #define XKEY_PROV_PROPS "provider=ovpn.xkey" +/** + * Stuct to encapsulate signature algorithm parameters to pass + * to sign operation. + */ +typedef struct { + const char *padmode; /* "pkcs1", "pss" or "none" */ + const char *mdname; /* "SHA256" or "SHA2-256" etc. */ + const char *saltlen; /* "digest", "auto" or "max" */ + const char *keytype; /* "EC" or "RSA" */ +} XKEY_SIGALG; + +/** + * Callback for sign operation -- must be implemented for each backend and + * is used in xkey_signature_sign(), or set when loading the key. + * (custom key loading not yet implemented). + * + * @param handle opaque key handle provided by the backend -- could be null + * or unused for management interface. + * @param sig On return caller should fill this with the signature + * @param siglen On entry *siglen has max size of sig and on return must be + * set to the actual size of the signature + * @param tbs buffer to sign + * @param tbslen size of data in tbs buffer + * @sigalg contains the signature algorithm parameters + * + * @returns 1 on success, 0 on error. + * + * The data in tbs is just the digest with no DigestInfo header added. This is + * unlike the deprecated RSA_sign callback which provides encoded digest. + * For RSA_PKCS1 signatures, the external signing function must encode the digest + * before signing. The digest algorithm used is passed in the sigalg structure. + */ +typedef int (XKEY_EXTERNAL_SIGN_fn)(void *handle, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen, + XKEY_SIGALG sigalg); + #endif /* XKEY_PUBLIC_H_ */ diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c index 4e5ed130..88906ef4 100644 --- a/src/openvpn/xkey_provider.c +++ b/src/openvpn/xkey_provider.c @@ -87,6 +87,14 @@ typedef struct #define KEYTYPE(key) ((key)->pubkey ? EVP_PKEY_get_id((key)->pubkey) : 0) #define KEYSIZE(key) ((key)->pubkey ? EVP_PKEY_get_size((key)->pubkey) : 0) +/** + * Helper sign function for native keys -- this is not + * an external key, but we use the same function signature + * for consistency. Implemented using OpenSSL calls. + */ +XKEY_EXTERNAL_SIGN_fn xkey_native_sign; + + /* keymgmt provider */ /* keymgmt callbacks we implement */ @@ -403,6 +411,482 @@ const OSSL_ALGORITHM keymgmts[] = { {NULL, NULL, NULL} }; + +/* signature provider */ + +/* signature provider callbacks we provide */ +static OSSL_FUNC_signature_newctx_fn signature_newctx; +static OSSL_FUNC_signature_freectx_fn signature_freectx; +static OSSL_FUNC_signature_sign_init_fn signature_sign_init; +static OSSL_FUNC_signature_sign_fn signature_sign; +static OSSL_FUNC_signature_digest_verify_init_fn signature_digest_verify_init; +static OSSL_FUNC_signature_digest_verify_fn signature_digest_verify; +static OSSL_FUNC_signature_digest_sign_init_fn signature_digest_sign_init; +static OSSL_FUNC_signature_digest_sign_fn signature_digest_sign; +static OSSL_FUNC_signature_set_ctx_params_fn signature_set_ctx_params; +static OSSL_FUNC_signature_settable_ctx_params_fn signature_settable_ctx_params; +static OSSL_FUNC_signature_get_ctx_params_fn signature_get_ctx_params; +static OSSL_FUNC_signature_gettable_ctx_params_fn signature_gettable_ctx_params; + +typedef struct +{ + XKEY_PROVIDER_CTX *prov; + XKEY_KEYDATA *keydata; + EVP_MD_CTX *mdctx; /* Used for digest-verify ops */ + EVP_PKEY_CTX *ectx; /* Used for digest-verify ops */ + XKEY_SIGALG sigalg; +} XKEY_SIGNATURE_CTX; + +static const XKEY_SIGALG default_sigalg = { .mdname="MD5-SHA1", .saltlen="digest", + .padmode="pkcs1", .keytype = "RSA"}; + +const struct { + int id; + const char *name; +} digest_names[] = {{NID_md5_sha1, "MD5-SHA1"}, {NID_sha1, "SHA1"}, + {NID_sha224, "SHA224",}, {NID_sha256, "SHA256"}, {NID_sha384, "SHA384"}, + {NID_sha224, "SHA2-224"}, {NID_sha256, "SHA2-256"}, {NID_sha384, "SHA2-384"}, + {NID_sha512, "SHA512"}, {NID_sha512, "SHA2-512"}, {NID_md5_sha1, ""}, + {0, NULL}}; + +/* return a string literal for digest name */ +static const char * +xkey_mdname(const char *s) +{ + int i = 0; + while(digest_names[i].name && strcasecmp(digest_names[i].name, s)) + { + i++; + } + return (digest_names[i].id != 0) ? OBJ_nid2sn(digest_names[i].id) : "MD5-SHA1"; +} + +static void * +signature_newctx(void *provctx, const char *props) +{ + dmsg(D_LOW, "In xkey signature_newctx"); + + XKEY_SIGNATURE_CTX *sctx = calloc(sizeof(*sctx), 1); + if (!sctx) + { + msg(M_NONFATAL, "xkey_signature_newctx: out of memory"); + return NULL; + } + + sctx->prov = provctx; + sctx->sigalg = default_sigalg; + + return sctx; +} + +static void +signature_freectx(void *ctx) +{ + dmsg(D_LOW, "In xkey signature_freectx"); + + XKEY_SIGNATURE_CTX *sctx = ctx; + + if (sctx->mdctx) + { + EVP_MD_CTX_free(sctx->mdctx); + /* sctx->ectx is owned by mdctx, do not free */ + } + + free(sctx); +} + +static const OSSL_PARAM * +signature_settable_ctx_params(void *ctx, void *provctx) +{ + dmsg(D_LOW, "In xkey signature_settable_ctx_params"); + + static OSSL_PARAM settable[] = { + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), + OSSL_PARAM_END + }; + + return settable; +} + +static int +signature_set_ctx_params(void *ctx, const OSSL_PARAM params[]) +{ + dmsg(D_LOW, "In signature_set_ctx_params"); + + XKEY_SIGNATURE_CTX *sctx = ctx; + const OSSL_PARAM *p; + + if (sctx->ectx) + { + EVP_PKEY_CTX_set_params(sctx->ectx, params); + } + + if (params == NULL) + { + return 1; /* not an error */ + } + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PAD_MODE); + if (p && p->data_type == OSSL_PARAM_UTF8_STRING) + { + if (!strcmp(p->data, "pss")) + { + sctx->sigalg.padmode = "pss"; + } + else if (!strcmp(p->data, "pkcs1")) + { + sctx->sigalg.padmode = "pkcs1"; + } + else if (!strcmp(p->data, "none")) + { + sctx->sigalg.padmode = "none"; + } + else + { + msg(D_LOW, "xkey signature_ctx: padmode <%s>, treating as ", + (char *)p->data); + sctx->sigalg.padmode = "none"; + } + dmsg(D_LOW, "xkey_sign_parameters: setting padmode to %s", sctx->sigalg.padmode); + } + else if (p && p->data_type == OSSL_PARAM_INTEGER) + { + int padmode; + if (OSSL_PARAM_get_int(p, &padmode)) + { + if (padmode == RSA_PKCS1_PSS_PADDING) + { + sctx->sigalg.padmode = "pss"; + } + else if (padmode == RSA_PKCS1_PADDING) + { + sctx->sigalg.padmode = "pkcs1"; + } + else + { + sctx->sigalg.padmode = "none"; + } + } + dmsg(D_LOW, "xkey_sign_parameters: setting padmode to <%s>", sctx->sigalg.padmode); + } + else if (p) + { + msg(M_WARN, "xkey_signature_params: unknown padmode ignored"); + } + + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); + if (p && p->data_type == OSSL_PARAM_UTF8_STRING) + { + sctx->sigalg.mdname = xkey_mdname(p->data); + msg(D_LOW, "xkey_sign_parameters: setting hashalg to %s", sctx->sigalg.mdname); + } + else if (p) + { + msg(M_WARN, "xkey_signature_params: unknown digest type ignored"); + } + + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PSS_SALTLEN); + if (p && p->data_type == OSSL_PARAM_UTF8_STRING) + { + if (!strcmp((char *)p->data, "digest")) + { + sctx->sigalg.saltlen = "digest"; + } + else if (!strcmp(p->data, "max")) + { + sctx->sigalg.saltlen = "max"; + } + else if (!strcmp(p->data, "auto")) + { + sctx->sigalg.saltlen = "auto"; + } + else + { + msg(M_WARN, "xkey_signature_params: unknown saltlen <%s>", + (char *)p->data); + sctx->sigalg.saltlen = "digest"; /* most common ? */ + } + msg(D_LOW, "xkey_sign_parameters: setting saltlen to %s", sctx->sigalg.saltlen); + } + else if (p) + { + msg(M_WARN, "xkey_signature_params: unknown saltlen ignored"); + } + + return 1; +} + +static const OSSL_PARAM * +signature_gettable_ctx_params(void *ctx, void *provctx) +{ + dmsg(D_LOW,"In xkey signature_gettable_ctx_params"); + + static OSSL_PARAM gettable[] = { + OSSL_PARAM_END + }; + + return gettable; +} + +static int +signature_get_ctx_params(void *ctx, OSSL_PARAM params[]) +{ + dmsg(D_LOW, "In signature_get_ctx_params -- not implemented!!"); + return 0; +} + +static int +signature_sign_init(void *ctx, void *provkey, const OSSL_PARAM params[]) +{ + dmsg(D_LOW, "In xkey sign_init"); + + XKEY_SIGNATURE_CTX *sctx = ctx; + + sctx->keydata = provkey; + sctx->keydata->refcount++; + sctx->sigalg.keytype = KEYTYPE(sctx->keydata) == EVP_PKEY_RSA ? "RSA" : "EC"; + + signature_set_ctx_params(sctx, params); + + return 1; +} + +static int +signature_sign(void *ctx, unsigned char *sig, size_t *siglen, size_t sigsize, + const unsigned char *tbs, size_t tbslen) +{ + dmsg(D_LOW, "In xkey signature_sign with siglen = %zu\n", *siglen); + + XKEY_SIGNATURE_CTX *sctx = ctx; + ASSERT(sctx); + ASSERT(sctx->keydata); + + if (!sig) + { + *siglen = KEYSIZE(sctx->keydata); + return 1; + } + + if (sctx->keydata->origin == OPENSSL_NATIVE) + { + return xkey_native_sign(sctx->keydata->handle, sig, siglen, tbs, tbslen, sctx->sigalg); + } + else + { + /* external key handling not yet implemented */ + return 0; + } +} + +/* Digest verify ops are simply delegated to the default provider using pubkey */ +static int +signature_digest_init_helper(void *ctx, const char *mdname, void *provkey) +{ + dmsg(D_LOW, "In xkey digest_init_helper with mdname = <%s>", mdname); + + XKEY_SIGNATURE_CTX *sctx = ctx; + + ASSERT(sctx); + ASSERT(provkey); + + if (!sctx->mdctx) { + sctx->mdctx = EVP_MD_CTX_new(); + } + if (!sctx->mdctx) { + msg(M_WARN, "xkey_signature_digest_init: EVP_MD_CTX_new failed"); + return 0; + } + + EVP_MD_CTX_init(sctx->mdctx); + sctx->keydata = provkey; /* used by digest_sign */ + sctx->keydata->refcount++; + + return 1; +} + +static int +signature_digest_verify_init(void *ctx, const char *mdname, void *provkey, + const OSSL_PARAM params[]) +{ + dmsg(D_LOW, "In xkey digest_verify init with mdname <%s>", mdname); + + XKEY_SIGNATURE_CTX *sctx = ctx; + ASSERT(sctx); + ASSERT(sctx->prov); + + + int ret = signature_digest_init_helper(ctx, mdname, provkey); + if (ret) + { + EVP_PKEY *pubkey = ((XKEY_KEYDATA*)provkey)->pubkey; + ret = EVP_DigestVerifyInit_ex(sctx->mdctx, &sctx->ectx, mdname, + sctx->prov->libctx, NULL, pubkey, params); + } + return ret; +} + +static int +signature_digest_verify(void *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + dmsg(D_LOW, "In xkey digest_verify"); + + XKEY_SIGNATURE_CTX *sctx = ctx; + + if (!sctx || !sctx->mdctx) + { + return 0; + } + return EVP_DigestVerify(sctx->mdctx, sig, siglen, tbs, tbslen); +} + +static int +signature_digest_sign_init(void *ctx, const char *mdname, + void *provkey, const OSSL_PARAM params[]) +{ + dmsg(D_LOW, "In xkey digest_sign_init with mdname = %s>", mdname); + + XKEY_SIGNATURE_CTX *sctx = ctx; + + ASSERT(sctx); + ASSERT(provkey); + ASSERT(sctx->prov); + + sctx->keydata = provkey; /* used by digest_sign */ + sctx->keydata->refcount++; + sctx->sigalg.keytype = KEYTYPE(sctx->keydata) == EVP_PKEY_RSA ? "RSA" : "EC"; + + signature_set_ctx_params(ctx, params); + if (mdname) + { + sctx->sigalg.mdname = xkey_mdname(mdname); /* get a string literal pointer */ + } + else + { + msg(M_WARN, "xkey digest_sign_init: mdname is NULL."); + } + return 1; +} + +static int +signature_digest_sign(void *ctx, unsigned char *sig, size_t *siglen, + size_t sigsize, const unsigned char *tbs, size_t tbslen) +{ + dmsg(D_LOW, "In xkey digest_sign"); + + XKEY_SIGNATURE_CTX *sctx = ctx; + + ASSERT(sctx); + ASSERT(sctx->keydata); + + if (!sig) /* set siglen and return */ + { + *siglen = KEYSIZE(sctx->keydata); + return 1; + } + + /* create digest and pass on to signature_sign() */ + + const char *mdname = sctx->sigalg.mdname; + EVP_MD *md = EVP_MD_fetch(sctx->prov->libctx, mdname, NULL); + if (!md) + { + msg(M_WARN, "WARN: xkey digest_sign_init: MD_fetch failed for <%s>", mdname); + return 0; + } + + /* construct digest using OpenSSL */ + unsigned char buf[EVP_MAX_MD_SIZE]; + unsigned int sz; + if (EVP_Digest(tbs, tbslen, buf, &sz, md, NULL) != 1) + { + msg(M_WARN, "WARN: xkey digest_sign: EVP_Digest failed"); + return 0; + } + + return signature_sign(ctx, sig, siglen, sigsize, buf, sz); +} + +/* Sign digest using native sign function -- will only work for native keys + */ +int +xkey_native_sign(void *handle, unsigned char *sig, size_t *siglen, const unsigned char *tbs, + size_t tbslen, XKEY_SIGALG sigalg) +{ + dmsg(D_LOW, "In xkey_native_sign"); + + EVP_PKEY *pkey = handle; + int ret = 0; + + ASSERT(sig); + ASSERT(pkey); + + const char *saltlen = sigalg.saltlen; + const char *mdname = sigalg.mdname; + const char *padmode = sigalg.padmode; + + dmsg(D_LOW, "In xkey_native_sign with digest <%s> padmode = <%s> saltlen=<%s>", mdname, padmode, saltlen); + + int i = 0; + OSSL_PARAM params[6]; + params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, (char *)mdname, 0); + if (EVP_PKEY_get_id(pkey) == EVP_PKEY_RSA) + { + params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, (char *)padmode, 0); + if (!strcmp(sigalg.padmode, "pss")) + { + params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, (char *) saltlen, 0); + /* same digest for mgf1 */ + params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, (char *) mdname, 0); + } + } + params[i++] = OSSL_PARAM_construct_end(); + + EVP_PKEY_CTX *ectx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); + + if (!ectx) + { + msg(M_WARN, "WARN: xkey test_sign: call to EVP_PKEY_CTX_new...failed"); + return 0; + } + + /* params must be set in a separate call after the sign_init */ + if (EVP_PKEY_sign_init_ex(ectx, NULL) != 1) + { + msg(M_WARN, "WARN: xkey test_sign: call to EVP_PKEY_sign_init failed"); + return 0; + } + EVP_PKEY_CTX_set_params(ectx, params); + + ret = EVP_PKEY_sign(ectx, sig, siglen, tbs, tbslen); + EVP_PKEY_CTX_free(ectx); + + return ret; +} + +static const OSSL_DISPATCH signature_functions[] = { + {OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))signature_newctx}, + {OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))signature_freectx}, + {OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))signature_sign_init}, + {OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))signature_sign}, + {OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, (void (*)(void))signature_digest_verify_init}, + {OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, (void (*)(void))signature_digest_verify}, + {OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, (void (*)(void))signature_digest_sign_init}, + {OSSL_FUNC_SIGNATURE_DIGEST_SIGN, (void (*)(void))signature_digest_sign}, + {OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))signature_set_ctx_params}, + {OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, (void (*)(void))signature_settable_ctx_params}, + {OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))signature_get_ctx_params}, + {OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, (void (*)(void))signature_gettable_ctx_params}, + {0, NULL } +}; + +const OSSL_ALGORITHM signatures[] = { + {"RSA:rsaEncryption", props, signature_functions}, + {"ECDSA", props, signature_functions}, + {NULL, NULL, NULL} +}; + /* main provider interface */ /* provider callbacks we implement */ @@ -421,7 +905,7 @@ query_operation(void *provctx, int op, int *no_store) switch (op) { case OSSL_OP_SIGNATURE: - return NULL; + return signatures; case OSSL_OP_KEYMGMT: return keymgmts; From patchwork Wed Sep 22 11:12:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 1969 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id eFJZGKucS2FZCQAAIUCqbw (envelope-from ) for ; Wed, 22 Sep 2021 17:14:19 -0400 Received: from proxy1.mail.ord1d.rsapps.net ([172.30.191.6]) by director8.mail.ord1d.rsapps.net with LMTP id yChCGKucS2HSVAAAfY0hYg (envelope-from ) for ; Wed, 22 Sep 2021 17:14:19 -0400 Received: from smtp30.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy1.mail.ord1d.rsapps.net with LMTPS id qJD6F6ucS2GnIAAAasrz9Q (envelope-from ) for ; Wed, 22 Sep 2021 17:14:19 -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: smtp30.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: 0c5e8314-1bea-11ec-9dbf-5254001e8e38-1-1 Received: from [216.105.38.7] ([216.105.38.7:49742] helo=lists.sourceforge.net) by smtp30.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id F2/B9-02332-AAC9B416; Wed, 22 Sep 2021 17:14:19 -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.92.3) (envelope-from ) id 1mT9YN-0006sj-US; Wed, 22 Sep 2021 21:13:19 +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.92.3) (envelope-from ) id 1mT9YJ-0006sC-Ce for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:15 +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=56h2EyqyXAinZ7Dl1oGWpIRi9KP2DGlmL2x9wcqbgJc=; b=gv7DvG4tNHAeWGxs8IaFSF9kN/ aoV+fz1lrFJJn6nTW1HpNt7yz9i8oJGqLSLEvF4EO28+FmVj7Q47sxA2eabK75WI7lQPdg7E3SQob HAcxImadZ8vQZZuEnqzxjm9xn8W1og23xlXg3jqRxac7iXZELPMPVa2qgQPKo+BFAPOw=; 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=56h2EyqyXAinZ7Dl1oGWpIRi9KP2DGlmL2x9wcqbgJc=; b=B0ygTS8V0vYDrNRIrz1AqIZtsA l2apZqhOLn0pAQDVXTvjzweAXJmHFsP6En/n/xwmG7da5cAH95iErI1bq3RQgWmxsnCHDGJEJz9NN /3lmKQm5YO1c6gcW9AlMQtU5qHVtskVpaqfpco45hqQu3anSV3NyHuQ7Ruhwen9/L0yI=; Received: from mail-qt1-f170.google.com ([209.85.160.170]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) id 1mT9YG-0022ye-M1 for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:15 +0000 Received: by mail-qt1-f170.google.com with SMTP id u21so4147490qtw.8 for ; Wed, 22 Sep 2021 14:13:12 -0700 (PDT) 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=56h2EyqyXAinZ7Dl1oGWpIRi9KP2DGlmL2x9wcqbgJc=; b=IkVA/0SsDpbEbY8S2h6y5eXBlaRiA3/TH2ufjUukTVvLxsRcBsf7iND3smP0+n7/je LrpS3I7+C2u83cH1vbKR5v/pUryfdDKk8WkCI4b0yzogQIUm/S85WhPi31OwhsENid+J Z2LlmF5UBIVl3vR4/6ctXzRoSUxcRSO18UfQLageZBcwx10cRMhFsSfhkhn/3O1T7Ynq cxPItQOTqbwaMQdcKiZHS7tgH0AmWFE7+u16h1n7UffAEDGAPksNWvh0Dd097Ii+L21b zSlDLIynIVLw9uzd2uSoh0ROGgm9UAWhBZa3TSUYJuZz8aBEi9k9kErYUy4S46+F3EtJ S7Hw== 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=56h2EyqyXAinZ7Dl1oGWpIRi9KP2DGlmL2x9wcqbgJc=; b=dzh9Ty/kSWwAs3ls8kbo6owyBYDj8lurZyHfCxMRBFU++JSRsilAjnLSUW6p+BMxVf obj0HYf/NqsAh2DrGL0rRZSQ2MIJMEaGM4F0IHJTG4GdazW/4D4+VqLuHYgquaCc4vPb aVMIQu1Ye21zj+AHQTa5HJIIxXlp3KD+MVllAVvpc4/aYAj77YhADYj8KUs52AkA3Ef5 /i36+QnAWmuyxlXNAIzvX5CoUzjD7MtlKGTLmuUMEpxYdBcyA5m9BlqXuO7RP7mOEacz WdqHlm252p7klTiVlZ53jX9iM7vbwB+QYUFWdG3ywkJqC0lQoDUNVDno1LfhxGn3CWop cjhQ== X-Gm-Message-State: AOAM53291yPA1eI09hugBxhskaZNiAV3q+9GZgiR643NWofuDs4bonGV oUBtvRIKMzpM3bi9J0O1eP/kxBSZ6r4= X-Google-Smtp-Source: ABdhPJziIq6998a+3q/w7nwrpK5FfHYkA1guPJnXSmmtk/WMStKAUzCII7Ahl94TGv4nVLuVa1g7vw== X-Received: by 2002:ac8:4042:: with SMTP id j2mr1445993qtl.229.1632345186543; Wed, 22 Sep 2021 14:13:06 -0700 (PDT) Received: from uranus.home.sansel.ca (bras-vprn-tnhlon4053w-lp130-02-70-51-223-227.dsl.bell.ca. [70.51.223.227]) by smtp.gmail.com with ESMTPSA id l7sm2185243qth.19.2021.09.22.14.13.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Sep 2021 14:13:05 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Wed, 22 Sep 2021 17:12:50 -0400 Message-Id: <20210922211254.7570-6-selva.nair@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210922211254.7570-1-selva.nair@gmail.com> References: <20210922211254.7570-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 Our key object retains info about the external key as an opaque handle to the backend. We also need the public key as an EVP_PKEY *. For native keys we use OpenSSL API to import data into the key. In fact the 'handle' in that case is the OpenSSL EVP_PKEY object itself. 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 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [209.85.160.170 listed in wl.mailspike.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.160.170 listed in list.dnswl.org] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from 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 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1mT9YG-0022ye-M1 Subject: [Openvpn-devel] [PATCH 5/9] Implement import of custom external keys 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 Our key object retains info about the external key as an opaque handle to the backend. We also need the public key as an EVP_PKEY *. For native keys we use OpenSSL API to import data into the key. In fact the 'handle' in that case is the OpenSSL EVP_PKEY object itself. For importing custom keys, we need to define custom parameters describing the key using OSSL_PARAM structure. We define 4 required and 1 optional parameters for loading the key: Required params: {.key="origin", .data_type = OSSL_PARAM_UTF8_STRING .data = "foobar", .data_size = 0 } Note: data_size = 0 refer to NUL terminated string in OpenSSL. This parameter is only used to identify that the key as non-native with an opaque handle. We really do not check the content of the string. Should not be NULL. {.key="handle", .data_type = OSSL_PARAM_OCTET_PTR, .data = &handle, .data_size = sizeof(handle)} {.key="pubkey", .data_type = OSSL_PARAM_OCTET_STRING, .data = &pubkey, .data_size = sizeof(pubkey)} {.key="sign_op", .data_type = OSSL_PARAM_OCTET_PTR, .data = &sign_op_ptr, .data_size = sizeof(sign_op_ptr)} Optional params: {.key="free_op", .data_type = OSSL_PARAM_OCTET_PTR, .data = &free_op_ptr, .data_size = sizeof(free_op_ptr)} The 'handle' is opaque to us and is retained. The caller should not free it. We will free it when no longer required by calling 'free_op()', if provided. The 'handle' should not be null as that indicates missing private key. The 'pubkey' must be an 'EVP_PKEY *' variable, and is duplicated by us. The caller may free it when not required. The 'sign_op' and 'free_op' function pointers should be of type 'XKEY_EXTERNAL_SIGN_fn' and 'XKEY_PRIVKEY_FREE_fn' defined in xkey_common.h For example, for management-external-key, we really do not need any 'handle'. Pass anything that will live long and won't dereference to NULL. We do not use it for any other purpose. Pointer to a const string would be a good choice. In this case, the 'free_op' must be NULL or some harmless function. NULL is the safest choice. The way of passing pointers via 'OSSL_PARAM' is somewhat fragile, as everything is cast into 'void *' and relies on abiding to the contract. For 'pubkey' we could pass it as a der encoded octet string, for example, and instead of function pointers we can just hard code the callbacks into our implementation. After all this is a private built-in provider. However, no external data is involved, so the only possible bad actor is the developer herself. A helper function to load the management key is in the next commit. Signed-off-by: Selva Nair --- src/openvpn/xkey_common.h | 7 ++ src/openvpn/xkey_provider.c | 166 +++++++++++++++++++++++++++++++++--- 2 files changed, 162 insertions(+), 11 deletions(-) diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h index 0cb76db1..466b2b8d 100644 --- a/src/openvpn/xkey_common.h +++ b/src/openvpn/xkey_common.h @@ -75,4 +75,11 @@ typedef int (XKEY_EXTERNAL_SIGN_fn)(void *handle, unsigned char *sig, size_t *si const unsigned char *tbs, size_t tbslen, XKEY_SIGALG sigalg); +/** + * Signature of private key free function callback used + * to free the opaque private key handle obtained from the + * backend. Not required for management-external-key. + */ +typedef void (XKEY_PRIVKEY_FREE_fn)(void *handle); + #endif /* XKEY_PUBLIC_H_ */ diff --git a/src/openvpn/xkey_provider.c b/src/openvpn/xkey_provider.c index 88906ef4..3ff01634 100644 --- a/src/openvpn/xkey_provider.c +++ b/src/openvpn/xkey_provider.c @@ -72,6 +72,13 @@ typedef enum * * We also keep the public key in the form of a native OpenSSL EVP_PKEY. * This allows us to do all public ops by calling ops in the default provider. + * Both these are references retained by us and freed when the key is + * destroyed. As the pubkey is native, we free it using EVP_PKEY_free(). + * To free the handle we call the backend if a free function + * has been set for that key origin. It could be set when the key is + * created/imported. + * For native keys no need to free handle as its same as the pubkey + * which we always free. */ typedef struct { @@ -81,6 +88,10 @@ typedef struct EVP_PKEY *pubkey; /* origin of key -- native or external */ XKEY_ORIGIN origin; + /* sign function in backend to call */ + XKEY_EXTERNAL_SIGN_fn *sign; + /* keydata handle free function of backend */ + XKEY_PRIVKEY_FREE_fn *free; int refcount; /* reference count */ } XKEY_KEYDATA; @@ -111,6 +122,9 @@ static OSSL_FUNC_keymgmt_gettable_params_fn keymgmt_gettable; static OSSL_FUNC_keymgmt_query_operation_name_fn rsa_keymgmt_name; static OSSL_FUNC_keymgmt_query_operation_name_fn ec_keymgmt_name; +static int +keymgmt_import_helper(XKEY_KEYDATA *key, const OSSL_PARAM params[]); + static XKEY_KEYDATA * keydata_new() { @@ -134,6 +148,11 @@ keydata_free(XKEY_KEYDATA *key) { return; } + if (key->free && key->handle) + { + key->free(key->handle); + key->handle = NULL; + } if (key->pubkey) { EVP_PKEY_free(key->pubkey); @@ -167,7 +186,27 @@ keymgmt_load(const void *reference, size_t reference_sz) * appropriate for the key. We just use it to create a native * EVP_PKEY from params and assign to keydata->handle. * - * Import of external keys -- to be implemented + * For non-native keys the params[] array should include a custom + * value with name "origin". + * + * Other required parameters in the params array are: + * + * pubkey - pointer to native public key as a OCTET_STRING + * the public key is duplicated on receipt + * handle - reference to opaque handle to private key -- if not required + * pass a dummy value that is not zero. type = OCTET_PTR + * The reference is retained -- caller must _not_ free it. + * sign_op - function pointer for sign operation. type = OCTET_PTR + * Must be a reference to XKEY_EXTERNAL_SIGN_fn + * origin - A custom string to indicate the external key origin. UTF8_STRING + * The value doesn't really matter, but must be present. + * + * Optional params + * free_op - Called as free(handle) when the key is deleted. If the + * handle should not be freed, do not include. type = OCTET_PTR + * Must be a reference to XKEY_PRIVKEY_FREE_fn + * + * See xkey_load_management_key for an example use. */ static int keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[], const char *name) @@ -185,6 +224,15 @@ keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[], const ch return 0; } + /* if params contain a custom origin, call our import helper */ + + const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, "origin"); + if (p && p->data_type == OSSL_PARAM_UTF8_STRING) + { + key->origin = EXTERNAL_KEY; + return keymgmt_import_helper(key, params); + } + /* create a native public key and assign it to key->pubkey */ EVP_PKEY *pkey = NULL; @@ -203,6 +251,7 @@ keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[], const ch key->pubkey = pkey; key->origin = OPENSSL_NATIVE; + key->sign = xkey_native_sign; if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) { /* just use the same key as handle -- do not up-ref */ @@ -335,10 +384,94 @@ keymgmt_get_params(void *keydata, OSSL_PARAM *params) return EVP_PKEY_get_params(key->pubkey, params); } +/* Helper used by keymgmt_import and keymgmt_set_params + * for our keys. Not to be used for OpenSSL native keys. + */ +static int +keymgmt_import_helper(XKEY_KEYDATA *key, const OSSL_PARAM *params) +{ + dmsg(D_LOW, "In keymgmt_import_helper"); + + const OSSL_PARAM *p; + EVP_PKEY *pkey = NULL; + + ASSERT(key); + /* calling this with native keys is a coding error */ + ASSERT(key->origin != OPENSSL_NATIVE); + + if (params == NULL) + { + return 1; /* not an error */ + } + + /* our keys are immutable, we do not allow resetting parameters */ + if (key->pubkey) + { + return 0; + } + + /* only check params we understand and ignore the rest */ + + p = OSSL_PARAM_locate_const(params, "pubkey"); /*setting pubkey on our keydata */ + if (p && p->data_type == OSSL_PARAM_OCTET_STRING + && p->data_size == sizeof(pkey)) + { + pkey = *(EVP_PKEY **)p->data; + ASSERT(pkey); + + int id = EVP_PKEY_get_id(pkey); + if (id != EVP_PKEY_RSA && id != EVP_PKEY_EC) + { + msg(M_WARN, "Error: xkey keymgmt_import: unknown key type (%d)", id); + return 0; + } + + key->pubkey = EVP_PKEY_dup(pkey); + if (key->pubkey == NULL) + { + msg(M_NONFATAL, "Error: xkey keymgmt_import: duplicating pubkey failed."); + return 0; + } + } + + p = OSSL_PARAM_locate_const(params, "handle"); /*setting privkey */ + if (p && p->data_type == OSSL_PARAM_OCTET_PTR + && p->data_size == sizeof(key->handle)) + { + key->handle = *(void **)p->data; + /* caller should keep the reference alive until we call free */ + ASSERT(key->handle); /* fix your params array */ + } + + p = OSSL_PARAM_locate_const(params, "sign_op"); /*setting sign_op */ + if (p && p->data_type == OSSL_PARAM_OCTET_PTR + && p->data_size == sizeof(key->sign)) + { + key->sign = *(void **)p->data; + ASSERT(key->sign); /* fix your params array */ + } + + /* optional parameters */ + p = OSSL_PARAM_locate_const(params, "free_op"); /*setting free_op */ + if (p && p->data_type == OSSL_PARAM_OCTET_PTR + && p->data_size == sizeof(key->free)) + { + key->free = *(void **)p->data; + } + + return 1; +} + /** + * Set params on a key. + * * If the key is an encapsulated native key, we just call * EVP_PKEY_set_params in the default context. Only those params * supported by the default provider would work in that case. + * + * We treat our key object as immutable, so this works only with an + * empty key. Supported params for external keys are the + * same as those listed in the description of keymgmt_import. */ static int keymgmt_set_params(void *keydata, const OSSL_PARAM *params) @@ -348,7 +481,7 @@ keymgmt_set_params(void *keydata, const OSSL_PARAM *params) if (key->origin != OPENSSL_NATIVE) { - return 0; /* to be implemented */ + return keymgmt_import_helper(key, params); } else if (key->handle == NULL) /* once handle is set our key is immutable */ { @@ -652,6 +785,22 @@ signature_sign_init(void *ctx, void *provkey, const OSSL_PARAM params[]) return 1; } +/* Sign digest using backend sign function */ +static int +xkey_sign_dispatch(XKEY_SIGNATURE_CTX *sctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, + size_t tbslen) +{ + XKEY_EXTERNAL_SIGN_fn *sign = sctx->keydata->sign; + + if (!sign) + { + /* should not happen */ + msg(M_FATAL, "Signing function for this key is not defined."); + return 0; + } + return sign(sctx->keydata->handle, sig, siglen, tbs, tbslen, sctx->sigalg); +} + static int signature_sign(void *ctx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) @@ -668,15 +817,10 @@ signature_sign(void *ctx, unsigned char *sig, size_t *siglen, size_t sigsize, return 1; } - if (sctx->keydata->origin == OPENSSL_NATIVE) - { - return xkey_native_sign(sctx->keydata->handle, sig, siglen, tbs, tbslen, sctx->sigalg); - } - else - { - /* external key handling not yet implemented */ - return 0; - } + /* we have sign_op set on natve keys as well + * so no need for the if/else here any more. + */ + return xkey_sign_dispatch(sctx, sig, siglen, tbs, tbslen); } /* Digest verify ops are simply delegated to the default provider using pubkey */ From patchwork Wed Sep 22 11:12:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 1966 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director11.mail.ord1d.rsapps.net ([172.31.255.6]) by backend30.mail.ord1d.rsapps.net with LMTP id WOmnFqmcS2FVCQAAIUCqbw (envelope-from ) for ; Wed, 22 Sep 2021 17:14:17 -0400 Received: from proxy8.mail.iad3b.rsapps.net ([172.31.255.6]) by director11.mail.ord1d.rsapps.net with LMTP id SIlyFqmcS2FQBQAAvGGmqA (envelope-from ) for ; Wed, 22 Sep 2021 17:14:17 -0400 Received: from smtp24.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy8.mail.iad3b.rsapps.net with LMTPS id GCyYD6mcS2ELWwAAoCsc3g (envelope-from ) for ; Wed, 22 Sep 2021 17:14:17 -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: smtp24.gate.iad3b.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: 0aefeb08-1bea-11ec-90e5-525400892b35-1-1 Received: from [216.105.38.7] ([216.105.38.7:50940] helo=lists.sourceforge.net) by smtp24.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id DA/86-16254-8AC9B416; Wed, 22 Sep 2021 17:14:16 -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 1mT9YM-00079n-Gp; Wed, 22 Sep 2021 21:13:18 +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 1mT9YJ-00079L-NL for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:15 +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=5Udp+C5tDRt1lzebYBvHUlhRjlVGp7phXwn/EGjQcFY=; b=PtkJyPYQw55RahdzjjDXLkWARv EbePAXV6c4cr0/nmYldpDZZnwLhYuDCjPzx9Lv7ZuvMTCUw0v+hcQspe7dylIyFx6Uu5VzoVg4JrF GDhFwg1PM+6HGrlkMkItfHvRLMWo1ARnpc0bJ3FOkv8MklaCZPiMJTiwjG1uIL0LJjSU=; 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=5Udp+C5tDRt1lzebYBvHUlhRjlVGp7phXwn/EGjQcFY=; b=Y8VpTDAkfUEX9g5JzCM8njHM/R NSr8cRhKLz/iMUMPCCraZaxr2mnFOtCCVS0DUYVsR/YC3SfBxM6l/TEcboJRKeV3uYFv7/TXrNdFC Pu+NTW3PSLn9TxZcfwamhfRJAKYfVJQI7c7KoUUCPikDAeyGqDsrY/8fvE2Uoeq1VAe4=; Received: from mail-qk1-f176.google.com ([209.85.222.176]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) id 1mT9YH-0022yk-8N for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:15 +0000 Received: by mail-qk1-f176.google.com with SMTP id c7so14865486qka.2 for ; Wed, 22 Sep 2021 14:13:13 -0700 (PDT) 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=5Udp+C5tDRt1lzebYBvHUlhRjlVGp7phXwn/EGjQcFY=; b=pH9B7w5sSHEZvGJbBuu6g2doyKmbWkQG27XgRtgtvXuhZgWrrylhYP+B3E919wWwSB 2YkP1Xg6Xa1nrh7fKqFXHYqFow0cGTouPA2tqgbOqp1ADdsr3YR7HWaA2fiZQxyD2aib HJN/+hyozkgBLmmEScw420khyw7tsLg9UzNehL3l1t0cb41O+d1g5eX5mbgprMRoDUcf 8TkL4GQtUE//JFaTC/4BjBwhSY2AOg0jUFCGveEQG7ksomuoi1st0GEhMUGvK/HTgl0w IrJ9lPWc1j8B+WZ+JwEkFTx40lwOLBOO+WdNV+wV0b3TDFDwp6UO4Kl8/PJjrbuPDaah G4Rw== 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=5Udp+C5tDRt1lzebYBvHUlhRjlVGp7phXwn/EGjQcFY=; b=CdYHVU5xX8lnmkM9ysPVDTKxJHUVNsPsYYAqoH9QW3lSZmXMNJQGLCMHgGUVNFtqTd itYyzYX/vl2G4wLA1AC1GmGCzQu9pNcMHCqUPcNHCCsztV8y29747l7PT++uV8hgQ90b iShxXzm3bv7AIoo076KnJFq3FdRX2SG9FtsKQ8w/G31rxgSWyWG51BBXyqE9Xhiobui1 PZ4HZTmgYFbnM1c0afoiLqMreuR5W55e36xvNIVqusnkvPg4/zF3HwT2dB/i4A1DS24Y xIxakNEPIoL53xPWJFpp/ogI5P+UUkQTaLe7YUKCvGmb3Yuxw9kDDTztwgAyDSf+xdss TCww== X-Gm-Message-State: AOAM532iPWpXL/QknwZPGl2xbEUKqSlSGBrQuQ6cakq9uyu+E05vS7dH sYnh2EsJP7YiiOGQ3oUt7E6XAQIPeoo= X-Google-Smtp-Source: ABdhPJwu3GNy9Ahmtt+TUo3ezJAH9ywdCAL8mopZ/N+0c5//UIbH04FKVXPqlRCbferq9Do5lLmkNw== X-Received: by 2002:a37:2f81:: with SMTP id v123mr1502827qkh.494.1632345187321; Wed, 22 Sep 2021 14:13:07 -0700 (PDT) Received: from uranus.home.sansel.ca (bras-vprn-tnhlon4053w-lp130-02-70-51-223-227.dsl.bell.ca. [70.51.223.227]) by smtp.gmail.com with ESMTPSA id l7sm2185243qth.19.2021.09.22.14.13.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Sep 2021 14:13:06 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Wed, 22 Sep 2021 17:12:51 -0400 Message-Id: <20210922211254.7570-7-selva.nair@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210922211254.7570-1-selva.nair@gmail.com> References: <20210922211254.7570-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 - A wrapper around the keymgmt import of xkey provider - When the provider is available, use this to set SSL_CTX_use_PrivateKey for management-external-key Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.222.176 listed in wl.mailspike.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.222.176 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] -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_EF Message has a valid DKIM or DK signature from envelope-from 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: 1mT9YH-0022yk-8N Subject: [Openvpn-devel] [PATCH 6/9] A helper function to load key for management-external-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 From: Selva Nair - A wrapper around the keymgmt import of xkey provider - When the provider is available, use this to set SSL_CTX_use_PrivateKey for management-external-key sign_op is not implemented yet. This will error out while signing with --management-external-key. The next commit fixes that. Signed-off-by: Selva Nair --- src/openvpn/Makefile.am | 1 + src/openvpn/ssl_openssl.c | 10 ++++ src/openvpn/xkey_common.h | 11 +++++ src/openvpn/xkey_helper.c | 96 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 src/openvpn/xkey_helper.c diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index 432efe73..0331298b 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -129,6 +129,7 @@ openvpn_SOURCES = \ tun.c tun.h \ vlan.c vlan.h \ xkey_provider.c xkey_common.h \ + xkey_helper.c \ win32.h win32.c \ win32-util.h win32-util.c \ cryptoapi.h cryptoapi.c diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 61256620..b9453653 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -1450,6 +1450,14 @@ tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) EVP_PKEY *pkey = X509_get0_pubkey(cert); ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */ +#ifdef HAVE_XKEY_PROVIDER + EVP_PKEY *privkey = xkey_load_management_key(NULL, pkey); + if (!privkey + || !SSL_CTX_use_PrivateKey(ctx->ctx, privkey)) + { + goto cleanup; + } +#else if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { if (!tls_ctx_use_external_rsa_key(ctx, pkey)) @@ -1478,6 +1486,8 @@ tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) } #endif /* OPENSSL_VERSION_NUMBER > 1.1.0 dev && !defined(OPENSSL_NO_EC) */ +#endif /* HAVE_XKEY_PROVIDER */ + ret = 0; cleanup: if (ret) diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h index 466b2b8d..751f18a0 100644 --- a/src/openvpn/xkey_common.h +++ b/src/openvpn/xkey_common.h @@ -82,4 +82,15 @@ typedef int (XKEY_EXTERNAL_SIGN_fn)(void *handle, unsigned char *sig, size_t *si */ typedef void (XKEY_PRIVKEY_FREE_fn)(void *handle); +/** + * Generate an encapsulated EVP_PKEY for management-external-key + * + * @param libctx library context in which xkey provider has been loaded + * @param pubkey corresponding pubkey in the default provider's context + * + * @returns a new EVP_PKEY in the provider's keymgmt context. + * The pubkey is up-refd if retained -- the caller can free it after return + */ +EVP_PKEY *xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY *pubkey); + #endif /* XKEY_PUBLIC_H_ */ diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c new file mode 100644 index 00000000..aa9f23b8 --- /dev/null +++ b/src/openvpn/xkey_helper.c @@ -0,0 +1,96 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2021 Selva Nair + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#ifdef HAVE_XKEY_PROVIDER + +#include "syshead.h" +#include "error.h" +#include "buffer.h" +#include "xkey_common.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *const props = XKEY_PROV_PROPS; + +XKEY_EXTERNAL_SIGN_fn xkey_management_sign; + +/** + * Load external key for signing via management interface. + * The public key must be passed in by the caller as we may not + * be able to get it from the management. + * Returns an EVP_PKEY object attached to xkey provider. + * Caller must free it when no longer needed. + */ +EVP_PKEY * +xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY *pubkey) +{ + EVP_PKEY *pkey = NULL; + ASSERT(pubkey); + + /* Management interface doesnt require any handle to be + * stored in the key. We use a dummy pointer as we do need a + * non-NULL value to indicate private key is avaialble. + */ + void *dummy = & "dummy"; + + const char *origin = "management"; + XKEY_EXTERNAL_SIGN_fn *sign_op = xkey_management_sign; + + /* UTF8 string pointers in here are only read from, so cast is safe */ + OSSL_PARAM params[] = { + {"origin", OSSL_PARAM_UTF8_STRING, (char *) origin, 0, 0}, + {"pubkey", OSSL_PARAM_OCTET_STRING, &pubkey, sizeof(pubkey), 0}, + {"handle", OSSL_PARAM_OCTET_PTR, &dummy, sizeof(dummy), 0}, + {"sign_op", OSSL_PARAM_OCTET_PTR, (void **) &sign_op, sizeof(sign_op), 0}, + {NULL, 0, NULL, 0, 0}}; + + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pubkey, props); + EVP_PKEY_fromdata_init(ctx); + EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params); + + return pkey; +} + +/* not yet implemented */ +int +xkey_management_sign(void *unused, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen, XKEY_SIGALG alg) +{ + msg(M_FATAL, "FATAL ERROR: A sign callback for this key is not implemented."); + return 0; +} + +#endif /* HAVE_XKEY_PROVIDER */ From patchwork Wed Sep 22 11:12:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 1965 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director7.mail.ord1d.rsapps.net ([172.31.255.6]) by backend30.mail.ord1d.rsapps.net with LMTP id +NkJC6mcS2FZCQAAIUCqbw (envelope-from ) for ; Wed, 22 Sep 2021 17:14:17 -0400 Received: from proxy3.mail.iad3b.rsapps.net ([172.31.255.6]) by director7.mail.ord1d.rsapps.net with LMTP id oIXUCqmcS2HRPAAAovjBpQ (envelope-from ) for ; Wed, 22 Sep 2021 17:14:17 -0400 Received: from smtp27.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy3.mail.iad3b.rsapps.net with LMTPS id WN2SBamcS2ElJwAAM8Wetg (envelope-from ) for ; Wed, 22 Sep 2021 17:14:17 -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: smtp27.gate.iad3b.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: 0ad70f98-1bea-11ec-9ee9-5254006b1ac1-1-1 Received: from [216.105.38.7] ([216.105.38.7:57114] helo=lists.sourceforge.net) by smtp27.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 22/18-06611-8AC9B416; Wed, 22 Sep 2021 17:14:16 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1mT9YU-0005BT-MJ; Wed, 22 Sep 2021 21:13:26 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mT9YM-0005AK-HG for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:18 +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=XboY7RgldvWYdd/iJW/wW8Nt3gvSwkqJmp4MnkTCRRc=; b=PuAgNJIxOI1p+GuIFBYTb1kx1H piB40g9wAZL3dBCuTzQFHD4yI3lIsWWszmox1vovloRFbCeu8d3+u9UHJiuzshTvQVW5dDSBl+gNd x2lU1d712dolJcqO0TKnxx3CGMCrjuIPpJxqMhpu3AH1bbh0eM7dfgXQXSCdqIWt6huY=; 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=XboY7RgldvWYdd/iJW/wW8Nt3gvSwkqJmp4MnkTCRRc=; b=Q8ORq7aevzq5rrDs2hlbZeRmSl 0voCFSY33VMjO0BsL/IeGZRrZYBBEqRjiAEyb9TpiR98wykrGD4813HC7PMiZ90PV78g0F8JeTAXS tSkWAXf0U9DP4acNAKfDC5rCmgoMUnatjzVZPHh0R+haHzMq0b1Wjujz91mSD5Jo5Tec=; Received: from mail-qt1-f178.google.com ([209.85.160.178]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) id 1mT9YL-00060J-Rm for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:18 +0000 Received: by mail-qt1-f178.google.com with SMTP id 2so4206784qtw.1 for ; Wed, 22 Sep 2021 14:13:17 -0700 (PDT) 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=XboY7RgldvWYdd/iJW/wW8Nt3gvSwkqJmp4MnkTCRRc=; b=hRH8R/QjzhmR1eUUjvRKg4IueWyWc098WiM8mXZm1XrGjCkMssCrA2afsj4kapoXX0 1xFMAkSdDHLGpPmzgV6yzsjBq7p9YJ4sb6txkqdG6ZEWLpk53fMO01xJfxINGbWujMZF yjX9nIozInS0wPP13bksaY4xRJXPM7zdP+6kS4LPhLHWtChY9I4WQVNr9v8dI0C+JlTM WmwffqQ9ZlXXmuO7OJzK/lElehGO69ZKOlku38WCeWxbUb0DlPLhOh6KKs+A+Kq0YiP3 NtKW6BFhx9aGuqnkcQoMtamney9T/MCMiF4hwwFUqpv8zd7VEHr8Y5h32VW/d02hHqpo uriQ== 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=XboY7RgldvWYdd/iJW/wW8Nt3gvSwkqJmp4MnkTCRRc=; b=T0p+fjTzG0GcmqliW6hZTCTBzV6yzu/+8uDLx7vee2A2zOh9k3t2kmb9z/q0KMZseb kbddhHKh0wD8Iu1ilhPfOcHc0JitAfM4q31QCU+7Q5ljBoKMMjQ0d4FBDtrdIbdq8YT9 biIdQnf0M6LIGlMjBbDw+p6s3EeuLSM354EmkBD1zjxA/OeoIBppzSKXNFKflr1HWCxC MTlgXDWs7lllQvVtOMJsA93jJoV/PF9svsjDoX7V9ejGdhp6g92ttPv6qi1i3IaJdCtG /1Atyzx1itsMz28RZcqhRYDcxEZgLvIULVlrma+DgI6mUGBkxRoxVychEvVat9HUo/Zq 5YPw== X-Gm-Message-State: AOAM533PnU6u2sFCS/oq8sN4JmF1Qmck4G6SQbOPwEQRUzZjDYB+hyLu +jdOgUeuIL3HyfbQlNpeUV5zKiHsOcs= X-Google-Smtp-Source: ABdhPJwAeYrNrxpIPauGBDxbM+bGXLBs2fCEU4kcoeshbMK12+BQqB/IwYXW5iCkjiHmKjkw7luHmQ== X-Received: by 2002:ac8:4d48:: with SMTP id x8mr1427991qtv.415.1632345188640; Wed, 22 Sep 2021 14:13:08 -0700 (PDT) Received: from uranus.home.sansel.ca (bras-vprn-tnhlon4053w-lp130-02-70-51-223-227.dsl.bell.ca. [70.51.223.227]) by smtp.gmail.com with ESMTPSA id l7sm2185243qth.19.2021.09.22.14.13.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Sep 2021 14:13:08 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Wed, 22 Sep 2021 17:12:52 -0400 Message-Id: <20210922211254.7570-8-selva.nair@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210922211254.7570-1-selva.nair@gmail.com> References: <20210922211254.7570-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 a function to set as sign_op during key import. The function passes the signature request to management interface, and returns the result to the provider. Signed-off-by: Selva Nair --- src/openvpn/xkey_common.h | 4 +++ src/openvpn/xkey_helper.c | 68 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 3 deletions(-) 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 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [209.85.160.178 listed in wl.mailspike.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.160.178 listed in list.dnswl.org] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from 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 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1mT9YL-00060J-Rm Subject: [Openvpn-devel] [PATCH 7/9] Enable signing via provider for management-external-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 From: Selva Nair - Add a function to set as sign_op during key import. The function passes the signature request to management interface, and returns the result to the provider. Signed-off-by: Selva Nair --- src/openvpn/xkey_common.h | 4 +++ src/openvpn/xkey_helper.c | 68 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h index 751f18a0..6a00c382 100644 --- a/src/openvpn/xkey_common.h +++ b/src/openvpn/xkey_common.h @@ -35,6 +35,10 @@ */ OSSL_provider_init_fn xkey_provider_init; +#else + +#define OSSL_LIB_CTX void + #endif /* HAVE_XKEY_PROVIDER */ #define XKEY_PROV_PROPS "provider=ovpn.xkey" diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c index aa9f23b8..c9e8d218 100644 --- a/src/openvpn/xkey_helper.c +++ b/src/openvpn/xkey_helper.c @@ -33,6 +33,8 @@ #include "error.h" #include "buffer.h" #include "xkey_common.h" +#include "manage.h" +#include "base64.h" #include #include @@ -84,13 +86,73 @@ xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY *pubkey) return pkey; } -/* not yet implemented */ +/** + * Signature callback for xkey_provider with management-external-key + * + * @param handle Unused -- may be null + * @param sig On successful return signature is in sig. + * @param siglen On entry *siglen has length of buffer sig, + * on successful return size of signature + * @param tbs hash to be signed + * @param tbslen len of data in dgst + * @param sigalg extra signature parameters + * + * @return signature length or -1 on error. + * For PKCS1 signature, the passed in hash is pure messaged digest + * not encoded with digest info even for the TLS 1.1 MD5_SHA hashes. + */ int xkey_management_sign(void *unused, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen, XKEY_SIGALG alg) { - msg(M_FATAL, "FATAL ERROR: A sign callback for this key is not implemented."); - return 0; + (void) unused; + char alg_str[64]; + + if (!strcmp(alg.keytype, "EC")) + { + strncpynt(alg_str, "ECDSA", sizeof(alg_str)); + } + /* else assume RSA key */ + else if (!strcmp(alg.padmode, "pkcs1")) + { + strncpynt(alg_str, "RSA_PKCS1_PADDING", sizeof(alg_str)); + } + else if (!strcmp(alg.padmode, "none")) + { + strncpynt(alg_str, "RSA_NO_PADDING", sizeof(alg_str)); + } + else if (!strcmp(alg.padmode, "pss")) + { + openvpn_snprintf(alg_str, sizeof(alg_str), "%s,hashalg=%s,saltlen=%s", + "RSA_PKCS1_PSS_PADDING", alg.mdname,alg.saltlen); + } + else { + msg(M_NONFATAL, "Unsupported RSA padding mode in signature request<%s>", + alg.padmode); + return 0; + } + dmsg(D_LOW, "xkey management_sign: requesting sig with algorithm <%s>", alg_str); + + char *in_b64 = NULL; + char *out_b64 = NULL; + int len = -1; + + int bencret = openvpn_base64_encode(tbs, (int) tbslen, &in_b64); + + if (management && bencret > 0) + { + out_b64 = management_query_pk_sig(management, in_b64, alg_str); + } + if (out_b64) + { + len = openvpn_base64_decode(out_b64, sig, (int) *siglen); + } + free(in_b64); + free(out_b64); + + *siglen = (len > 0) ? len : 0; + + return (*siglen > 0); } #endif /* HAVE_XKEY_PROVIDER */ From patchwork Wed Sep 22 11:12:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 1971 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director13.mail.ord1d.rsapps.net ([172.31.255.6]) by backend30.mail.ord1d.rsapps.net with LMTP id yC3UNqycS2GLCQAAIUCqbw (envelope-from ) for ; Wed, 22 Sep 2021 17:14:20 -0400 Received: from proxy16.mail.iad3b.rsapps.net ([172.31.255.6]) by director13.mail.ord1d.rsapps.net with LMTP id aGwsNqycS2FHXwAA91zNiA (envelope-from ) for ; Wed, 22 Sep 2021 17:14:20 -0400 Received: from smtp32.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy16.mail.iad3b.rsapps.net with LMTPS id +LRGL6ycS2EtEAAAPj+4aA (envelope-from ) for ; Wed, 22 Sep 2021 17:14:20 -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: smtp32.gate.iad3b.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: 0d22e2d6-1bea-11ec-8d97-5254006a2e70-1-1 Received: from [216.105.38.7] ([216.105.38.7:51044] helo=lists.sourceforge.net) by smtp32.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 42/5D-06898-CAC9B416; Wed, 22 Sep 2021 17:14:20 -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 1mT9YW-0007BO-2i; Wed, 22 Sep 2021 21:13:28 +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 1mT9YM-00079y-Ld for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:18 +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=lcAgHugMmOBwOl4Q7tieqwAD9mSI425n6ReCoSWD7nk=; b=QI/us/+m48OIJGt6jNDQohliVJ nelM7BQT5qG1umlsEWXCpwce7Pbc1aCSmQ5Tewi4syIl+KXmcO0SSub3vb9Ly7Lx0EbsREBARMd0r Y+xxUaCbWCNpqVOqJpEFRjIID1dZ3aTNBo0f71apY59ZVbdIwrx29aOrRyZdobPbCtj8=; 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=lcAgHugMmOBwOl4Q7tieqwAD9mSI425n6ReCoSWD7nk=; b=hO7yyyQXmLaY9Rj0iNM/7BYRik KDkEnYzySrWNhq4peq8QsuyI6cBTzqpAWjOGjsLSQR5Ir+dSDkq7ke1dTpax3tggBbvSMf0oybn0B Q2padcRAMl+4PIT+MxLBkRCREGT8Mu6xXP7sewCHNWa+LZfC5vq7tqO5mKPIBZAayxsE=; Received: from mail-qt1-f176.google.com ([209.85.160.176]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) id 1mT9YL-00060Q-Rk for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:18 +0000 Received: by mail-qt1-f176.google.com with SMTP id c19so4147353qte.7 for ; Wed, 22 Sep 2021 14:13:17 -0700 (PDT) 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=lcAgHugMmOBwOl4Q7tieqwAD9mSI425n6ReCoSWD7nk=; b=P5jMVOUE2+pqbdqicpPI4rG7ZmcUwLP58TGOgPEaYEAZJ6WrXeF2LEoGsTeNwRSFAH h/gX0KEvo/3KKm6B9ITd7mnnw3fH1uviqxeMW376k1qazJQ3NToqAVdpG6qUk3NHf7YA l9NMmZnAE2EG7jc4tcva9e1kc3NDXD5OKQKykBT6ONCijduHe7XtVkVqaSMz1n9ek8it llofJ4PKL2svP6D3Fhd+5/U9GOIU1MGE/Kgospofc2d0b2qu0KOL6NyyWGZk4pQDh3ev EkpoKgyGjhINR9MkumFxGc48VGf8Fo2Xu/qRF5W93v2yQ8g1QHssvXvSpuHHFd6R/B5p z0oA== 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=lcAgHugMmOBwOl4Q7tieqwAD9mSI425n6ReCoSWD7nk=; b=Wf3HpzTUrHUOVkPnoTmtnM8ex+ba98Ckb27CVR2IbJGrFWQLgpY7+DoN71iLjkbhVI vHSecw597oZV10ye7ZvIobjAno7JLDkKirlQfvlCZPQ8dbmj2qfbllZWXkBXzlARp8Wu EXDsG+uWa9T/e5cf6XzhCYJOVKdNCnkF7znjpA9TS18l6VvZ/dsg8MTgYbMDzLok5KbU DQxBixBAKU3/W2Q13JXV2+9KB6wU5nQf4JkhPikD5EvcPHPnTJ57zW2LK7GFzsUiP5xV nzpDFSjkwReZxnrGwu9YZqNpcEXewnBF14yWQOZ0wb3xSqSF/EP3fRF/cdoTXJZSk5dW keYw== X-Gm-Message-State: AOAM532CFJtpesjnq6FkP6J9pSFe8K0mEiECghRwVGKa+X95/2bGr44J Ny1t435kOLgbc7s9XyYOzXxGiLsNVa8= X-Google-Smtp-Source: ABdhPJztlzrOU2M1y/hyaBWdKk1dH52KQu8r6U2ckjgiu7KNU4VQmaplgcuV/GG13wkhIhsmWErjoQ== X-Received: by 2002:ac8:5c44:: with SMTP id j4mr793949qtj.164.1632345190247; Wed, 22 Sep 2021 14:13:10 -0700 (PDT) Received: from uranus.home.sansel.ca (bras-vprn-tnhlon4053w-lp130-02-70-51-223-227.dsl.bell.ca. [70.51.223.227]) by smtp.gmail.com with ESMTPSA id l7sm2185243qth.19.2021.09.22.14.13.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Sep 2021 14:13:09 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Wed, 22 Sep 2021 17:12:53 -0400 Message-Id: <20210922211254.7570-9-selva.nair@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210922211254.7570-1-selva.nair@gmail.com> References: <20210922211254.7570-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 The EVP_PKEY interface as well as provider provides the raw digest to the sign() function. In case of RSA_PKCS1, our management interface expects expects an encoded hash, which has the DigestInfo head [...] Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.160.176 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.160.176 listed in wl.mailspike.net] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from 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: 1mT9YL-00060Q-Rk Subject: [Openvpn-devel] [PATCH 8/9] Add a function to encode digests with PKCS1 DigestInfo wrapper 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 The EVP_PKEY interface as well as provider provides the raw digest to the sign() function. In case of RSA_PKCS1, our management interface expects expects an encoded hash, which has the DigestInfo header added as per PKCSv1.5 specs, unless the hash algorithm is legacy MD5_SHA1. Fix this by - add a function to perform the pkcs1 encoding before passing the data to sign to the management interface. The implementation is not pretty, but should work. (Unfortunately OpenSSL does not expose a function for this). Note: 1. cryptoki interface used by pkcs11-helper also requires this to be done before calling the Sign op. This will come handy there too. 2. We have a similar function in ssl_mbedtls.c but its not prettier, and require porting. Signed-off-by: Selva Nair --- src/openvpn/xkey_common.h | 20 ++++++ src/openvpn/xkey_helper.c | 127 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h index 6a00c382..e92d4868 100644 --- a/src/openvpn/xkey_common.h +++ b/src/openvpn/xkey_common.h @@ -97,4 +97,24 @@ typedef void (XKEY_PRIVKEY_FREE_fn)(void *handle); */ EVP_PKEY *xkey_load_management_key(OSSL_LIB_CTX *libctx, EVP_PKEY *pubkey); +/** + * Add PKCS1 DigestInfo to tbs and return the result in *enc. + * + * @param enc pointer to output buffer + * @param enc_len capacity in bytes of output buffer + * @param mdname name of the hash algorithm (SHA256, SHA1 etc.) + * @param tbs pointer to digest to be encoded + * @param tbslen length of data in bytes + * + * @return false on error, true on success + * + * On return enc_len is set to actual size of the result. + * enc is NULL or enc_len is not enough to store the result, it is set + * to the required size and false is returned. + * + */ +bool +encode_pkcs1(unsigned char **enc, size_t *enc_len, const char *mdname, + const unsigned char *tbs, size_t tbslen); + #endif /* XKEY_PUBLIC_H_ */ diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c index c9e8d218..4d41631b 100644 --- a/src/openvpn/xkey_helper.c +++ b/src/openvpn/xkey_helper.c @@ -115,6 +115,17 @@ xkey_management_sign(void *unused, unsigned char *sig, size_t *siglen, /* else assume RSA key */ else if (!strcmp(alg.padmode, "pkcs1")) { + /* management interface expects a pkcs1 encoded digest -- add it */ + unsigned char enc[EVP_MAX_MD_SIZE + 32]; /* 32 bytes enough for digest inf structure */ + size_t enc_len = sizeof(enc); + + if (!encode_pkcs1((unsigned char **)&enc, &enc_len, alg.mdname, tbs, tbslen)) + { + return 0; + } + tbs = enc; + tbslen = enc_len; + strncpynt(alg_str, "RSA_PKCS1_PADDING", sizeof(alg_str)); } else if (!strcmp(alg.padmode, "none")) @@ -155,4 +166,120 @@ xkey_management_sign(void *unused, unsigned char *sig, size_t *siglen, return (*siglen > 0); } +/** + * Add PKCS1 DigestInfo to tbs and return the result in *enc. + * + * @param enc pointer to output buffer + * @param enc_len capacity in bytes of output buffer + * @param mdname name of the hash algorithm (SHA256, SHA1 etc.) + * @param tbs pointer to digest to be encoded + * @param tbslen length of data in bytes + * + * @return false on error, true on success + * + * On return enc_len is set to actual size of the result. + * enc is NULL or enc_len is not enough to store the result, it is set + * to the required size and false is returned. + * + */ +bool +encode_pkcs1(unsigned char **enc, size_t *enc_len, const char *mdname, + const unsigned char *tbs, size_t tbslen) +{ + bool ret = false; + unsigned char *ptr; + int out_len = 0; + int tmp_len; + X509_ALGOR *algor = NULL; + ASN1_STRING *digest = NULL; + + ASSERT(enc_len != NULL); + ASSERT(tbs != NULL); + + int nid = OBJ_sn2nid(mdname); + if(nid == NID_undef) + { + msg(M_WARN, "Error: encode_pkcs11: invalid digest name <%s>", mdname); + return false; + } + + if (nid == NID_md5_sha1) /* no encoding needed -- just copy */ + { + out_len = (int) tbslen; + if (enc && (*enc_len >= out_len)) + { + memcpy(*enc, tbs, out_len); + } + *enc_len = tbslen; + ret = 1; + goto cleanup; + } + + if((algor = X509_ALGOR_new()) == NULL + || X509_ALGOR_set0(algor, OBJ_nid2obj(nid), V_ASN1_NULL, NULL) <= 0 + || (digest = ASN1_STRING_type_new(V_ASN1_OCTET_STRING)) == NULL + || ASN1_STRING_set(digest, tbs, tbslen) <= 0) + { + msg(M_WARN, "Error: encode_pkcs11: failed to create ASN1 strings"); + goto cleanup; + } + + if(algor->algorithm == NULL || OBJ_length(algor->algorithm) == 0) + { + msg(M_WARN, "Error: encode_pkcs11: invalide digest type(nid = %d)", nid); + goto cleanup; + } + + /* We want DER encoding of X509_SIG = {algor, digest} which could be + * computed as i2d_X509_SIG(), but, unfortunately, the X509_SIG struct + * is opaque and has no constructor. Hence we combine the two elements + * into a sequence ourselves -- not pretty + */ + + /* find required size for the buffer */ + if((tmp_len = i2d_X509_ALGOR(algor, NULL)) < 0) + { + goto cleanup; + } + out_len = tmp_len; + + if((tmp_len = i2d_ASN1_OCTET_STRING(digest, NULL)) < 0) + { + goto cleanup; + } + out_len += tmp_len + 2 ; /* extra 2 bytes for sequence header added below */ + + if ((out_len > (int) *enc_len) || !enc) + { + *enc_len = out_len; + goto cleanup; + } + + ptr = *enc; + *ptr++ = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; + *ptr++ = out_len - 2; + + /* compute and append the DER of algor and digest to ptr */ + i2d_X509_ALGOR(algor, &ptr); /* this advances ptr */ + i2d_ASN1_OCTET_STRING(digest, &ptr); + + *enc_len = out_len; /* assignment safe as out_len is > 0 at this point */ + ret = 1; + + dmsg(D_LOW, "encode_pkcs1: digest length = %d encoded length = %d", + (int) tbslen, out_len); + +cleanup: + if(digest) + { + ASN1_STRING_free(digest); + } + if(algor) + { + X509_ALGOR_free(algor); + } + + return ret; +} + #endif /* HAVE_XKEY_PROVIDER */ From patchwork Wed Sep 22 11:12:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 1963 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director9.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id gIUZJ6WcS2FWCQAAIUCqbw (envelope-from ) for ; Wed, 22 Sep 2021 17:14:13 -0400 Received: from proxy17.mail.ord1d.rsapps.net ([172.30.191.6]) by director9.mail.ord1d.rsapps.net with LMTP id 4FrfJqWcS2HwZgAAalYnBA (envelope-from ) for ; Wed, 22 Sep 2021 17:14:13 -0400 Received: from smtp4.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy17.mail.ord1d.rsapps.net with LMTPS id +J++JqWcS2EMXAAAWC7mWg (envelope-from ) for ; Wed, 22 Sep 2021 17:14:13 -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: smtp4.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: 08acc726-1bea-11ec-ba3a-525400760ffc-1-1 Received: from [216.105.38.7] ([216.105.38.7:49676] helo=lists.sourceforge.net) by smtp4.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id DE/16-02363-4AC9B416; Wed, 22 Sep 2021 17:14:12 -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.92.3) (envelope-from ) id 1mT9YO-0006sv-VE; Wed, 22 Sep 2021 21:13:20 +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.92.3) (envelope-from ) id 1mT9YM-0006sa-3j for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:18 +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=ibPa2j6ry9g81+KhxcLWlE3vrkDn44EKybkN3H36O3w=; b=Te5DG0sf1z9bkGWLZSX9zEcYbV tUVdQ8TUVMV4zuD664ADqb89+XklvSP/ZRjvDT3eq2Tj/t4DyCbgXGvGsNfzdIxqaKv6uOiD1bOGS i75kSKLF/toXNFi2JS/9dFNKsYOw4v4NIe/xOEJnHZur5N1ByRWu+9lmv+DZg+Ggg6Jc=; 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=ibPa2j6ry9g81+KhxcLWlE3vrkDn44EKybkN3H36O3w=; b=HAKEEX/3fWskMmhOYu+tu/Zfeo 84Lr1UZ6PudlOtRsgS64yBePkyh9f4V7sejN4JuKWb6BOklJy5F1YXWpC7CbvcQ2ltmtv1R/uNp3I mceBoy+2v2l80i8PNSkfhUazwBUKAIHcn7Ct+n6aaZ8bbQLYDc/QWqXRdJp7Z1W7JtSg=; Received: from mail-qk1-f170.google.com ([209.85.222.170]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) id 1mT9YL-0022zC-Ft for openvpn-devel@lists.sourceforge.net; Wed, 22 Sep 2021 21:13:18 +0000 Received: by mail-qk1-f170.google.com with SMTP id 72so14567267qkk.7 for ; Wed, 22 Sep 2021 14:13:17 -0700 (PDT) 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=ibPa2j6ry9g81+KhxcLWlE3vrkDn44EKybkN3H36O3w=; b=E51Zzq1bywNQ6DzDIuTPwK4MdUpwtNIkASt1cYF6JlAIEK41dshZHoeVgqYB9R4PSS A07cTNGLbQ95+kjDwH7WzVhu/P2DhikKOtAiW3sWxp3gdA3Jhb1gCcaDVA7LMv28dMXV Lxz1SXBQzaMQfe4d5/9yyqeTRWuDSFWUYYQnVgkn40IP14kdJqSs14Ef1dX6lyuVyXcD /g8sMWXvfyfwuxJnh22V9IO7v3xMnLdfdE5dFPBV3cNFuD5Me9kco/IO8yBpGMfkBaH5 c7Pp4IMKHoOK+t7fgiFvwOJGo94g/JT2mUMnpOByS2pn1X8r1rNV6tbaImGgPuC0S5MI bS2w== 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=ibPa2j6ry9g81+KhxcLWlE3vrkDn44EKybkN3H36O3w=; b=AfH8cJMm88D+xWk0oQcvZScBfIfnK9ICjVXmb+tvqLP6oILMUglyt39jxVlDySRhUG 0Xp5dmF6AYHqt9HtFzIYMHx3LpJrD/k6FGCxhg+1RtdEjWRUbtVwn1QB+E8rXsqhTAwp m7Ug5rqfgv/9KRSq9VklasF9J7cgy1x09eEFcLcwERxeMc4oRLJNmj0Vr0GDkHuo1d3q y+Ufa/Je7iRiP55bWDHiHscIpCU8jQFlLhR3d3UtErv3LH7NkctqYD70e062nB/Rjf0t 48DMK2uldHUDYPbz9LnB0I0vDSumTC2JJUu+OcafCt52SWEBuX26gHpu3dJYBPuFaCZk Axgg== X-Gm-Message-State: AOAM531nrnRPpV0VcD/JSbe6SBehKK5Y58hQGnuHbYZRTzG5QKGJ8D6C stzEqXFs9kL7kVKbpDJwLlQn66l1rw0= X-Google-Smtp-Source: ABdhPJwNc3IpwwwgSYXeRJD5xog3ubiBK1aX2SvwcAeS3+lTRYFulb/tYmbSx7VYoPV76LG1OWD47w== X-Received: by 2002:a37:b805:: with SMTP id i5mr1519685qkf.167.1632345191591; Wed, 22 Sep 2021 14:13:11 -0700 (PDT) Received: from uranus.home.sansel.ca (bras-vprn-tnhlon4053w-lp130-02-70-51-223-227.dsl.bell.ca. [70.51.223.227]) by smtp.gmail.com with ESMTPSA id l7sm2185243qth.19.2021.09.22.14.13.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Sep 2021 14:13:11 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Wed, 22 Sep 2021 17:12:54 -0400 Message-Id: <20210922211254.7570-10-selva.nair@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210922211254.7570-1-selva.nair@gmail.com> References: <20210922211254.7570-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 pk-sig request from management can currently indicate support for 'nopadding' or 'pkcs1i' signatures. Add 'pss' as an option to indicate that PSS signing requests are accepted. To match, extend the algorithm string in PK_SIGN request to include the following format: 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 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.222.170 listed in wl.mailspike.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.222.170 listed in list.dnswl.org] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from 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: 1mT9YL-0022zC-Ft Subject: [Openvpn-devel] [PATCH 9/9] Allow management client to announce pss padding support 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 pk-sig request from management can currently indicate support for 'nopadding' or 'pkcs1i' signatures. Add 'pss' as an option to indicate that PSS signing requests are accepted. To match, extend the algorithm string in PK_SIGN request to include the following format: - RSA_PKCS1_PSS_PADDING,hashlag=name,saltlen=[max|digest|auto] Here 'name' is the short common name of the hash algorithm. E.g., SHA1, SHA256 etc. Signed-off-by: Selva Nair --- doc/man-sections/management-options.rst | 8 +++++++- doc/management-notes.txt | 15 +++++++++++---- src/openvpn/manage.h | 1 + src/openvpn/options.c | 7 ++++++- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/doc/man-sections/management-options.rst b/doc/man-sections/management-options.rst index de0d47e7..b173a1ea 100644 --- a/doc/man-sections/management-options.rst +++ b/doc/man-sections/management-options.rst @@ -90,9 +90,15 @@ server and client mode operations. management-external-key management-external-key nopadding management-external-key pkcs1 + management-external-key pss + + or any combination like: + :: + management-external-key nopadding pkcs1 + management-external-key pkcs1 pss - The optional parameters :code:`nopadding` and :code:`pkcs1` signal + The optional parameters :code:`nopadding` :code:`pkcs1` and :code:`pss` signal support for different padding algorithms. See :code:`doc/mangement-notes.txt` for a complete description of this feature. diff --git a/doc/management-notes.txt b/doc/management-notes.txt index 84e3d04b..27163239 100644 --- a/doc/management-notes.txt +++ b/doc/management-notes.txt @@ -1019,10 +1019,17 @@ can be indicated in the signing request only if the client version is > 2" The currently defined padding algorithms are: - - RSA_PKCS1_PADDING - PKCS1 padding and RSA signature - - RSA_NO_PADDING - No padding may be added for the signature - - ECDSA - EC signature. - + - RSA_PKCS1_PADDING - PKCS1 padding and RSA signature + - RSA_NO_PADDING - No padding may be added for the signature + - ECDSA - EC signature. + - RSA_PKCS1_PSS_PADDING,params - RSA signature with PSS padding + + params for PSS are specified as 'digest=name,saltlen=[max|digest|auto]'. + The digest names are short common names such as SHA256, SHA224, etc. + In the case of PKCS1, when the hash algorithm is not the legacy MD5-SHA1, + the digest is encoded with DigestInfo header before presening to the + management. This is identical to CKM_RSA_PKCS in cryptoki as well as + what RSA_sign() provides. COMMAND -- certificate (OpenVPN 2.4 or higher) ---------------------------------------------- diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h index 04dc98d1..5ed27c0c 100644 --- a/src/openvpn/manage.h +++ b/src/openvpn/manage.h @@ -339,6 +339,7 @@ struct management *management_init(void); #define MF_QUERY_REMOTE (1<<13) #define MF_QUERY_PROXY (1<<14) #define MF_EXTERNAL_CERT (1<<15) +#define MF_EXTERNAL_KEY_PSSPAD (1<<16) bool management_open(struct management *man, const char *addr, diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 26305a90..6e71563f 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -2213,7 +2213,8 @@ options_postprocess_verify_ce(const struct options *options, #if defined(ENABLE_MANAGEMENT) if ((tls_version_max() >= TLS_VER_1_3) && (options->management_flags & MF_EXTERNAL_KEY) - && !(options->management_flags & (MF_EXTERNAL_KEY_NOPADDING)) + && !(options->management_flags & (MF_EXTERNAL_KEY_NOPADDING) + || options->management_flags & (MF_EXTERNAL_KEY_PSSPAD)) ) { msg(M_ERR, "management-external-key with OpenSSL 1.1.1 requires " @@ -5511,6 +5512,10 @@ add_option(struct options *options, { options->management_flags |= MF_EXTERNAL_KEY_PKCS1PAD; } + else if (streq(p[j], "pss")) + { + options->management_flags |= MF_EXTERNAL_KEY_PSSPAD; + } else { msg(msglevel, "Unknown management-external-key flag: %s", p[j]);