From patchwork Tue Mar 14 12:21:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 3127 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7300:2310:b0:9f:bfa4:120f with SMTP id r16csp2229102dye; Tue, 14 Mar 2023 05:23:01 -0700 (PDT) X-Google-Smtp-Source: AK7set+BdhklgXxWUXXB8ifUzeYBK91QZeTFGqcTNWdt9hMqdvUt9xx9CxVxPKyaejUOCpNl/49g X-Received: by 2002:a17:90b:224a:b0:237:c7ed:8f4d with SMTP id hk10-20020a17090b224a00b00237c7ed8f4dmr37386455pjb.15.1678796580876; Tue, 14 Mar 2023 05:23:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1678796580; cv=none; d=google.com; s=arc-20160816; b=q8iEsGGIMiq1V7rCV+yc+ctf0RPLKy3LD5tuDSt+c0gu+XuoI2+WVj7D8pUOWIpZZJ nbsl2V6ag2AwBNiD1nxSJby/+OllRShzBnnOtZmyZzFdLvEHk36Q/rtG0HuSzAKiZF3P 1K9qN0O/x8RASAt7tHBY/MAX00FcJsASS15WeDGvWkIpRoll//bezYHbOEi7MLs8JK0d h5ngsj7aYXV6A72S6MCMpPCMkXvrmpz/mYpXw9yj+07QxxXw+iq5DrYd6YCIuolVijjT 465s2XkMHYytNBOEjddmczB0sDDqtYyX0iYrPAq6AZXFkuUMw2YK+1JmbXDVp0miDNY4 RNrQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:content-transfer-encoding:cc:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature; bh=uytDoR9W0dR4RxCDN9H292cYIZl3P8ibNmJaEGzL8Nw=; b=EKEdcH3Lj6LWlrXWWXKV7hMZBS+1IpWXtuCZksJwtj26kEGyHu8PR7KMjDuhRmFUJW 6sz/xg4fDFnHHfdqUxy1V4QwcvjFyYNK4zbKAw6JVstfJK4ApAFyPoxzqjv2NiJj9Pt8 XKNciVPe9IBxG5d+mFnpG4iSQEiZqbOl5ETQ0kNEYk+oOfjDIlTAweZbu4GtBEhTRSeE Wil7tYRlec8eagMm6hTH7OOWsa+5Ebk5NVNb+AtISs8OEhteB/t34sgD7DNCbujgWxav BpdHhhQRMYZhMtoz+D6fF0QJH1gbT/zMeVC6x24iUGozL/UF1qHIwYQylSpkGsmelAfR Pcdg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Fp8iIiEB; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=ZlXG7kKu; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=l5kxPlIH; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id jc11-20020a17090325cb00b001994711ddfbsi2279355plb.127.2023.03.14.05.23.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 Mar 2023 05:23:00 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Fp8iIiEB; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=ZlXG7kKu; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=l5kxPlIH; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com 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.95) (envelope-from ) id 1pc3fL-00011k-54; Tue, 14 Mar 2023 12:22:08 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1pc3fK-00011e-6R for openvpn-devel@lists.sourceforge.net; Tue, 14 Mar 2023 12:22:07 +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=nUfxOrIqeO15Zq1SbRyyAGp7oRqRI9Wsy5jshV5F5e4=; b=Fp8iIiEBT6Xcq7kF0St4r2VT94 deTYFX/PLG+oyQkRV1J7al+FHiOFCutk9xPbXiuC1KQKuCibqyvY9UyKLI0iQD+CmrF1XVqhV2Gem kANObzccCgykxeU4sUQbS4GLQ613DDTY//MU/lpDHE2Ryhz0bkTjGH/JndeTyUp5s8S4=; 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=nUfxOrIqeO15Zq1SbRyyAGp7oRqRI9Wsy5jshV5F5e4=; b=ZlXG7kKuCn96UxVXAUdPxXDlfo 6Jzxc2X+Tk4+83BQ0woIeZ67Pppqq0rjghid6jbFYRN1HrQafXW7Yp2cSvTnbWudSgw44O+EJJyi0 bXQh3KuCxdrb5GgvZ5JdFDRni4sLLBnMy/HVlPiMIFh21QwyclUvXRknuJQYVCl6XHWQ=; Received: from mail-il1-f172.google.com ([209.85.166.172]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1pc3fH-0003um-V7 for openvpn-devel@lists.sourceforge.net; Tue, 14 Mar 2023 12:22:07 +0000 Received: by mail-il1-f172.google.com with SMTP id h7so8533343ila.5 for ; Tue, 14 Mar 2023 05:22:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678796518; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nUfxOrIqeO15Zq1SbRyyAGp7oRqRI9Wsy5jshV5F5e4=; b=l5kxPlIHX0dM7mAGRKPXE8QMEthD1mkzYVvXNgeuoEChgmyGTlD4WmVRXQehXK6zyS 9BXoQhjkpUIukPGXQ1cpztJOPaJHG1PzomLLTSbpC1YiVrhANmzXXjWawBQK+O48VENb Cvbyeb46TBPCcXmeqXJnEhEGiaN/SZ5mO3S39VSeVKVTo8mAcMOt4TREIYG0F1jxaJZX djOF+Cq4DGpT6sUaPwWnHkoRdEBNwZEkY74+qDJMT0dY7ai+Q5cqfsBCOj2KBgMwo1VM yaK8v/eUdll5nhbQLG2Q8IcpGnmNEymYs8KUH0OlhAPTNRbheOhXPLgw+CLd0r/1Q5XK hKVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678796518; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nUfxOrIqeO15Zq1SbRyyAGp7oRqRI9Wsy5jshV5F5e4=; b=L001faLU2r0iz5F7o+3Hc0d09Uj6LPXEdc8wF+s3GK4icmZiopGzIvsq6iuXSl7B+d 2U6GaSk+4nd+UPO9ksVqQKzsNLfj9b8EwXObLHLi5MipPQq1efWgG5ZxN3RtWopX+J5t dke3TpD0bhBFX/e6RHBmmIhiAMz+Qckm+UdaDr5ZrmZMlD77PZXo5WUBnWO82f8uPQxL Ob+unUFDsiJt7J2OCfBn62egPqLaqOUkga1PVuIYWYaMG1QppS9GDEj3uhpNOEOXt9bU Dc4NZqDHpYFJURTfREgp+3nar3t6tRJ+rgt1PHpcxLMv36xTkTIPHsvjmkXta8Jijqmm DWTg== X-Gm-Message-State: AO0yUKUUOvoqlAcgj2osrvtK+XZ5rBiSRM2oG8BpCK5SWQ/40Bi1zYA5 ELr8DQSsYt2oXEpO/Jvco10HKFjjjnM= X-Received: by 2002:a92:d186:0:b0:323:504:cff6 with SMTP id z6-20020a92d186000000b003230504cff6mr3738271ilz.3.1678796518054; Tue, 14 Mar 2023 05:21:58 -0700 (PDT) Received: from uranus.sansel.ca (bras-vprn-tnhlon4053w-lp130-01-70-51-222-66.dsl.bell.ca. [70.51.222.66]) by smtp.gmail.com with ESMTPSA id i21-20020a02b695000000b003ab21c8fa84sm723442jam.121.2023.03.14.05.21.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Mar 2023 05:21:57 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Tue, 14 Mar 2023 08:21:34 -0400 Message-Id: <20230314122134.1248576-1-selva.nair@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230311052403.1154030-1-selva.nair@gmail.com> References: <20230311052403.1154030-1-selva.nair@gmail.com> MIME-Version: 1.0 X-Spam-Score: -0.2 (/) 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 - With OpenSSL 3.0 and xkey-provider, we use pkcs11h_certificate_signAny_ex() which returns EC signature as raw r|s concatenated. But OpenSSL expects a DER encoded ASN.1 structure. 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.166.172 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.166.172 listed in wl.mailspike.net] -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.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain X-Headers-End: 1pc3fH-0003um-V7 Subject: [Openvpn-devel] [PATCH v2] Bugfix: Convert ECDSA signature form pkcs11-helper to DER encoded form 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: , Cc: Florian Apolloner Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1760047734662907228?= X-GMAIL-MSGID: =?utf-8?q?1760345803068879888?= From: Selva Nair - With OpenSSL 3.0 and xkey-provider, we use pkcs11h_certificate_signAny_ex() which returns EC signature as raw r|s concatenated. But OpenSSL expects a DER encoded ASN.1 structure. Do this conversion as done in cryptoapi.c. For code re-use, ecdsa_bin2sig() is consolidated with sig to DER conversion as ecdsa_bin2der() and moved to xkey_helper.c In the past when we used OpenSSL hooks installed by pkcs11-helper, such a conversion was not required as it was internally handled by the library. Reported by: Tom Also see: https://bugzilla.redhat.com/show_bug.cgi?id=2177834 Tested-by: Florian Apolloner Change-Id: Ie20cf81edd643ab8ef3c41321353d11fd66c188c Signed-off-by: Selva Nair Acked-By: Arne Schwabe --- Same as v1 with Tested by: and link to redhat bugzilla ticket added src/openvpn/cryptoapi.c | 61 +++++------------------------------- src/openvpn/pkcs11_openssl.c | 23 ++++++++++++-- src/openvpn/xkey_common.h | 15 +++++++++ src/openvpn/xkey_helper.c | 45 ++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 56 deletions(-) diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c index 136c6ffc..022f53d4 100644 --- a/src/openvpn/cryptoapi.c +++ b/src/openvpn/cryptoapi.c @@ -146,40 +146,6 @@ CAPI_DATA_free(CAPI_DATA *cd) free(cd); } -/** - * Helper to convert ECDSA signature returned by NCryptSignHash - * to an ECDSA_SIG structure. - * On entry 'buf[]' of length len contains r and s concatenated. - * Returns a newly allocated ECDSA_SIG or NULL (on error). - */ -static ECDSA_SIG * -ecdsa_bin2sig(unsigned char *buf, int len) -{ - ECDSA_SIG *ecsig = NULL; - DWORD rlen = len/2; - BIGNUM *r = BN_bin2bn(buf, rlen, NULL); - BIGNUM *s = BN_bin2bn(buf+rlen, rlen, NULL); - if (!r || !s) - { - goto err; - } - ecsig = ECDSA_SIG_new(); /* in openssl 1.1 this does not allocate r, s */ - if (!ecsig) - { - goto err; - } - if (!ECDSA_SIG_set0(ecsig, r, s)) /* ecsig takes ownership of r and s */ - { - ECDSA_SIG_free(ecsig); - goto err; - } - return ecsig; -err: - BN_free(r); /* it is ok to free NULL BN */ - BN_free(s); - return NULL; -} - /** * Parse a hex string with optional embedded spaces into * a byte array. @@ -287,12 +253,11 @@ static int xkey_cng_ec_sign(CAPI_DATA *cd, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) { - BYTE buf[1024]; /* large enough for EC keys upto 1024 bits */ - DWORD len = _countof(buf); + DWORD len = *siglen; msg(D_LOW, "Signing using NCryptSignHash with EC key"); - DWORD status = NCryptSignHash(cd->crypt_prov, NULL, (BYTE *)tbs, tbslen, buf, len, &len, 0); + DWORD status = NCryptSignHash(cd->crypt_prov, NULL, (BYTE *)tbs, tbslen, sig, len, &len, 0); if (status != ERROR_SUCCESS) { @@ -301,26 +266,14 @@ xkey_cng_ec_sign(CAPI_DATA *cd, unsigned char *sig, size_t *siglen, const unsign return 0; } - /* NCryptSignHash returns r|s -- convert to OpenSSL's ECDSA_SIG */ - ECDSA_SIG *ecsig = ecdsa_bin2sig(buf, len); - if (!ecsig) + /* NCryptSignHash returns r|s -- convert to DER encoded buffer expected by OpenSSL */ + int derlen = ecdsa_bin2der(sig, (int) len, *siglen); + if (derlen <= 0) { - msg(M_NONFATAL, "Error in cryptopicert: Failed to convert ECDSA signature"); return 0; } - - /* convert internal signature structure 's' to DER encoded byte array in sig */ - if (i2d_ECDSA_SIG(ecsig, NULL) > EVP_PKEY_size(cd->pubkey)) - { - ECDSA_SIG_free(ecsig); - msg(M_NONFATAL, "Error in cryptoapicert: DER encoded ECDSA signature is too long"); - return 0; - } - - *siglen = i2d_ECDSA_SIG(ecsig, &sig); - ECDSA_SIG_free(ecsig); - - return (*siglen > 0); + *siglen = derlen; + return 1; } /** Sign hash in tbs using RSA key in cd and NCryptSignHash */ diff --git a/src/openvpn/pkcs11_openssl.c b/src/openvpn/pkcs11_openssl.c index 5c1de44e..eee86e17 100644 --- a/src/openvpn/pkcs11_openssl.c +++ b/src/openvpn/pkcs11_openssl.c @@ -168,6 +168,7 @@ xkey_pkcs11h_sign(void *handle, unsigned char *sig, unsigned char buf[EVP_MAX_MD_SIZE]; size_t buflen; + size_t siglen_max = *siglen; unsigned char enc[EVP_MAX_MD_SIZE + 32]; /* 32 bytes enough for DigestInfo header */ size_t enc_len = sizeof(enc); @@ -234,8 +235,26 @@ xkey_pkcs11h_sign(void *handle, unsigned char *sig, ASSERT(0); /* coding error -- we couldnt have created any such key */ } - return CKR_OK == pkcs11h_certificate_signAny_ex(cert, &mech, - tbs, tbslen, sig, siglen); + if (CKR_OK != pkcs11h_certificate_signAny_ex(cert, &mech, + tbs, tbslen, sig, siglen)) + { + return 0; + } + if (strcmp(sigalg.keytype, "EC")) + { + return 1; + } + + /* For EC keys, pkcs11 returns signature as r|s: convert to der encoded */ + int derlen = ecdsa_bin2der(sig, (int) *siglen, siglen_max); + + if (derlen <= 0) + { + return 0; + } + *siglen = derlen; + + return 1; } /* wrapper for handle free */ diff --git a/src/openvpn/xkey_common.h b/src/openvpn/xkey_common.h index 07b70c08..51cdb5b7 100644 --- a/src/openvpn/xkey_common.h +++ b/src/openvpn/xkey_common.h @@ -33,6 +33,7 @@ #define HAVE_XKEY_PROVIDER 1 #include #include +#include /** * Initialization function for OpenVPN external key provider for OpenSSL @@ -170,6 +171,20 @@ xkey_max_saltlen(int modBits, int hLen) return emLen - hLen - 2; } + +/** + * @brief Convert raw ECDSA signature to DER encoded + * This function converts ECDSA signature provided as a buffer + * containing r|s to DER encoded ASN.1 expected by OpenSSL + * @param buf signature containing r|s. + * @param len size of signature in bytes + * @param capacity max space in the buffer buf in bytes + * @returns the size of the converted signature or <= 0 on error. + * On success, buf is overwritten by its DER encoding + */ +int +ecdsa_bin2der(unsigned char *buf, int len, size_t capacity); + #endif /* HAVE_XKEY_PROVIDER */ #endif /* ENABLE_CRYPTO_OPENSSL */ diff --git a/src/openvpn/xkey_helper.c b/src/openvpn/xkey_helper.c index 052c60c4..ee9677ab 100644 --- a/src/openvpn/xkey_helper.c +++ b/src/openvpn/xkey_helper.c @@ -401,4 +401,49 @@ done: return ret; } +/** + * Helper to convert ECDSA signature with r and s concatenated + * to a DER encoded format used by OpenSSL. + * Returns the size of the converted signature or <= 0 on error. + * On success, buf is overwritten by the DER encoded signature. + */ +int +ecdsa_bin2der(unsigned char *buf, int len, size_t capacity) +{ + ECDSA_SIG *ecsig = NULL; + int rlen = len/2; + BIGNUM *r = BN_bin2bn(buf, rlen, NULL); + BIGNUM *s = BN_bin2bn(buf+rlen, rlen, NULL); + if (!r || !s) + { + goto err; + } + ecsig = ECDSA_SIG_new(); /* this does not allocate r, s */ + if (!ecsig) + { + goto err; + } + if (!ECDSA_SIG_set0(ecsig, r, s)) /* ecsig takes ownership of r and s */ + { + ECDSA_SIG_free(ecsig); + goto err; + } + + int derlen = i2d_ECDSA_SIG(ecsig, NULL); + if (derlen > (int) capacity) + { + ECDSA_SIG_free(ecsig); + msg(M_NONFATAL, "Error: DER encoded ECDSA signature is too long (%d)\n", derlen); + return 0; + } + derlen = i2d_ECDSA_SIG(ecsig, &buf); + ECDSA_SIG_free(ecsig); + return derlen; + +err: + BN_free(r); /* it is ok to free NULL BN */ + BN_free(s); + return 0; +} + #endif /* HAVE_XKEY_PROVIDER */