From patchwork Tue May 28 17:28:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "plaisthos (Code Review)" X-Patchwork-Id: 3714 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:a49c:b0:57d:b2cb:6cf with SMTP id gz28csp12090mab; Tue, 28 May 2024 10:28:52 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWleeR2Od1cygol3+UaI4lz1mwQcKW8SSWHbfactHS/AUICiGUmmPsV/GMpsjAsf9YDaKsJOUT3CIuJ8D1JRkMyDSQt72A= X-Google-Smtp-Source: AGHT+IGLMBXkqHCbbFTweWDEHVBS8lxmcQoha+sH648RVympbrI/4LVAfTrdXjPuutW5+tueKxRu X-Received: by 2002:a05:6358:99a9:b0:192:5236:b1d9 with SMTP id e5c5f4694b2df-197e556460dmr1371823755d.2.1716917331895; Tue, 28 May 2024 10:28:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1716917331; cv=none; d=google.com; s=arc-20160816; b=Zr+3xkEhvrrZps+hgeKPB7UER5GlKs8j2zsx4JWoEd76jxV7dYdxKR1WGlYm6leknw zCTYtsdcmN0rsOMQuTc0zFTI7Gf/w4fQidqFfHM968ptBhn2viYhgEZZDa0kZpBZM9NY TvoQNT1vdAR7sJcE+jjVPhhkWdFWDuJZ31weJdlzjSgk1rEax0sOfQzKdQ36mw9aEFKA jFIJsdKw2EmAQUjUOTKPJix1gMXIRfPh+hjEXecQrGKpxjrf/5O3pLqIlK2gqeCYCqwI E6p5M9k6PQMRHSsuk6y5ulBXpp79PPqQ1I+anL2elScnngFf+dLJF8DcAyq+lPhAsa/m +VLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:cc:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:user-agent :mime-version:message-id:references:auto-submitted:to:date:from :dkim-signature:dkim-signature:dkim-signature; bh=vz7VAVnFoyMVpXE3vDhW7oHRDet7E8WQmmDrSaSwsjI=; fh=U7wEyxtwz2o5+UdevFSA47vNeG9knhWH0KV//QhD5a0=; b=dRRbHEJrIKTZDAufQOt/SPTF14Frp8xTVy1OjK0bNdze4w9e+TNFyFChrk5Dl9RPfw RW7ubWCIpcWZpLqAe3yBn9jHXUDF3vkvSjQMh97J5E74TxcMM788CCxgnZ1iVctTmDxp J4osvpeehYffG4grnRUv8oBLUktB5yeKIrzqJDVCs+64M3XwZ2TOUA3WXf5HoCPAbMBA fgI8ljRPo+t7TRXGf1mW1lAa33cn0y7q+6stJUUdwW/hgn/rXCdYcGICXhgsmhXV8BwG o6H1yQJJBWQQXG42DKEy9CWn15S0+V1ObWjqhdUySy0Gn7sGATwAnslY8WeaelPYJGmv Ph8w==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=mP4csyR3; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="LFwneN/c"; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=cqeotf74; 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=NONE dis=NONE) header.from=openvpn.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 41be03b00d2f7-6849c50cf46si8108373a12.332.2024.05.28.10.28.51 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 May 2024 10:28:51 -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=mP4csyR3; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="LFwneN/c"; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=cqeotf74; 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=NONE dis=NONE) header.from=openvpn.net 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.95) (envelope-from ) id 1sC0cR-0002mu-R8; Tue, 28 May 2024 17:28:16 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1sC0cN-0002mZ-R6 for openvpn-devel@lists.sourceforge.net; Tue, 28 May 2024 17:28:12 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:Content-Transfer-Encoding:MIME-Version :Message-ID:Reply-To:References:Subject:List-Unsubscribe:List-Id:Cc:To:Date: From:Sender:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help: List-Subscribe:List-Post:List-Owner:List-Archive; bh=gScFGY43CxJVO4Ry9A/fsQClK98VKTsqFLmz8qmY6vs=; b=mP4csyR3HvmiwKe6zyrQQenVVC NL004hUk5vuYypBtCp7UolPSo5AjxRj+8GhvN/vEYrfduA018CYuBluga78rd7mCRyHiEIxJWzow/ U6+/axof3wsTYx1IDNy2dNKWHcmKVlR0sFVoI8rcdAtyhQe+EPeGJeeeefgfyD0G88cM=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:Content-Transfer-Encoding:MIME-Version:Message-ID:Reply-To: References:Subject:List-Unsubscribe:List-Id:Cc:To:Date:From:Sender:Content-ID :Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To: Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help:List-Subscribe:List-Post: List-Owner:List-Archive; bh=gScFGY43CxJVO4Ry9A/fsQClK98VKTsqFLmz8qmY6vs=; b=L FwneN/cSyWJ2OflXplI33jUMUfxpWGuShFLF4Nw5PgXK6BPXU8Dk8KXmwKCn1M6Ypadw/klygxS2r DAwggQKa+1RrofkgCFiG5hJdtvzbKn2uwPkzrhUJ3IAjRJ/qk853U1HPWpy7rzg5XJWgNxGlBeVBV if+UwMn99fKw+UVc=; Received: from mail-wm1-f45.google.com ([209.85.128.45]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1sC0cN-0002LQ-H1 for openvpn-devel@lists.sourceforge.net; Tue, 28 May 2024 17:28:12 +0000 Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-4202ca70270so12656515e9.3 for ; Tue, 28 May 2024 10:28:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvpn.net; s=google; t=1716917284; x=1717522084; darn=lists.sourceforge.net; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from:from:to:cc :subject:date:message-id:reply-to; bh=gScFGY43CxJVO4Ry9A/fsQClK98VKTsqFLmz8qmY6vs=; b=cqeotf74lNhQbsOSniz5ht7z6nqNzVffA6WMnZbhdUONN/Ubb3/tW4v6qd2xRM6Nnh lvG02Me2e7DFRmi9eYDhM7V6k7wCo6Po4yOTCVorhrp6cwxs0gNf3neV32krBOCImo8K 725lSFwAatEQ8WIlf7BNlgk8AMgQTQ3hx4vpA/aLykgdfX4t4aTDRrb4Dnf7v6ZXOhzp j8T4gUycmINz6qxIy3GBXtFsUszXecMoEcZO4hfIUI3SayKVZN5KEtfzOsrWDYwFx8ev U2jpoKxTDEx++C4+xH+ZZaI7uU1TCzqkD/wRkDxr1L2r+NQLOWvuI85CbeFcMbIMX13A aHHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716917284; x=1717522084; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gScFGY43CxJVO4Ry9A/fsQClK98VKTsqFLmz8qmY6vs=; b=h3nBueLwV8MjhG5qpcPhf0efVNyttGEVAZA1gYrwhFair2DPmEjnC/UO6jtvBltZ+u E8QkjGLnb0Yvy2uEYdfDddIxChx8ECxGvN2vayLfi1gnjAm6qX5a0J4dvcbQd9QsnoL3 iKA78BXhP89yJyCQky3i+RR24oe+kvTiTmKU76JEzXwVo2bHasYy7t/kQNf3ppcfo4H6 ngPZ5d7nCXMWoGy3MxRp03yGWdvgT2xVjArYC2rlbxL8hnFDey2aPXB0rfmIYSxOh8Cv TtEKhL9NgQd5q+p70VKXgMmeq9Ib9AnfYVSy7k2ek22up3uJXUPnPtYc/4+xN9fFz9/v 7E7g== X-Gm-Message-State: AOJu0YzAmB1Kt4adlQnrBOCEU/bWCBIfTe3oBb/vLhF+I+3gVhVQCZ0y X7x+VIWq4y7TX+Et+wB5n3VHeaWk6x2vd8G/vVQ8tpxpSIeAwAehpyABheoq6ILwCkDd+4VSj4Q G X-Received: by 2002:a05:600c:470b:b0:416:8efd:1645 with SMTP id 5b1f17b1804b1-42108a3a6e1mr122765335e9.7.1716917283895; Tue, 28 May 2024 10:28:03 -0700 (PDT) Received: from gerrit.openvpn.in (ec2-18-159-0-78.eu-central-1.compute.amazonaws.com. [18.159.0.78]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42100f591cbsm177896785e9.22.2024.05.28.10.28.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 May 2024 10:28:03 -0700 (PDT) From: "ssbssa (Code Review)" X-Google-Original-From: "ssbssa (Code Review)" X-Gerrit-PatchSet: 1 Date: Tue, 28 May 2024 17:28:02 +0000 To: plaisthos , flichtenheld Auto-Submitted: auto-generated X-Gerrit-MessageType: newchange X-Gerrit-Change-Id: Ia2c3e4c5c83ecccce1618c43b489dbe811de5351 X-Gerrit-Change-Number: 621 X-Gerrit-Project: openvpn X-Gerrit-ChangeURL: X-Gerrit-Commit: 2b1e725d8ed5905abdb0f518cb851a9c814c8f6a References: Message-ID: MIME-Version: 1.0 User-Agent: Gerrit/3.8.2 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "util-spamd-2.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: Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: openvpn.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.128.45 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [209.85.128.45 listed in sa-trusted.bondedsender.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.128.45 listed in wl.mailspike.net] 0.0 WEIRD_PORT URI: Uses non-standard port number for HTTP 0.0 HTML_MESSAGE BODY: HTML included in message -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 -0.0 T_SCC_BODY_TEXT_LINE No description available. 0.0 T_KAM_HTML_FONT_INVALID Test for Invalidly Named or Formatted Colors in HTML X-Headers-End: 1sC0cN-0002LQ-H1 Subject: [Openvpn-devel] [M] Change in openvpn[master]: Implement Windows CA template match for Crypto-API selector 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: , Reply-To: ssbssa@yahoo.de, arne-openvpn@rfc2549.org, openvpn-devel@lists.sourceforge.net, frank@lichtenheld.com Cc: openvpn-devel Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1800318307778643272?= X-GMAIL-MSGID: =?utf-8?q?1800318307778643272?= X-getmail-filter-classifier: gerrit message type newchange Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/621?usp=email to review the following change. Change subject: Implement Windows CA template match for Crypto-API selector ...................................................................... Implement Windows CA template match for Crypto-API selector The certificate selection process for the Crypto API certificates is currently fixed to match on subject or identifier. Especially if certificates that are used for OpenVPN are managed by a Windows CA, it is appropriate to select the certificate to use by the template that it is generated from, especially on domain-joined clients which automatically acquire/renew the corresponding certificate. The attached match implements the match on TMPL: with either a template name (which is looked up through CryptFindOIDInfo) or by specifying the OID of the template directly, which then is matched against the corresponding X509 extensions specifying the template that the certificate was generated from. The logic requires to walk all certificates in the underlying store and to match the certificate extensions directly. The hook which is implemented in the certificate selection logic is generic to allow other Crypto-API certificate matches to also be implemented at some point in the future. The logic to match the certificate template is taken from the implementation in the .NET core runtime, see Pal.Windows/FindPal.cs in in the implementation of System.Security.Cryptography.X509Certificates. Change-Id: Ia2c3e4c5c83ecccce1618c43b489dbe811de5351 Signed-off-by: Heiko Wundram Signed-off-by: Hannes Domani --- M doc/man-sections/windows-options.rst M src/openvpn/cryptoapi.c 2 files changed, 111 insertions(+), 3 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/21/621/1 diff --git a/doc/man-sections/windows-options.rst b/doc/man-sections/windows-options.rst index e87291f..3e66355 100644 --- a/doc/man-sections/windows-options.rst +++ b/doc/man-sections/windows-options.rst @@ -55,6 +55,12 @@ cryptoapicert "ISSUER:Sample CA" + To select a certificate based on a certificate's template name or + OID of the template: + :: + + cryptoapicert "TMPL:1.3.6.1.4..." + The first non-expired certificate found in the user's store or the machine store that matches the select-string is used. diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c index f7e5b67..0810086 100644 --- a/src/openvpn/cryptoapi.c +++ b/src/openvpn/cryptoapi.c @@ -178,6 +178,94 @@ return i; } +static void * +decode_object(struct gc_arena *gc, LPCSTR struct_type, + const CRYPT_OBJID_BLOB *val, DWORD flags, DWORD *cb) +{ + /* get byte count for decoding */ + BYTE *buf; + if (!CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, struct_type, + val->pbData, val->cbData, flags, NULL, cb)) + { + return NULL; + } + + /* do the actual decode */ + buf = gc_malloc(*cb, false, gc); + if (!CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, struct_type, + val->pbData, val->cbData, flags, buf, cb)) + { + return NULL; + } + + return buf; +} + +static const CRYPT_OID_INFO * +find_oid(DWORD keytype, const void *key, DWORD groupid, bool fallback) +{ + const CRYPT_OID_INFO *info = NULL; + + /* force resolve from local as first step */ + info = CryptFindOIDInfo(keytype, (void*)key, + groupid | CRYPT_OID_DISABLE_SEARCH_DS_FLAG); + + /* try proper resolve if not found yet, also including AD */ + if (!info) + { + info = CryptFindOIDInfo(keytype, (void*)key, groupid); + } + + /* fall back to all groups if not found yet and fallback requested */ + if (!info && fallback && groupid) + { + info = CryptFindOIDInfo(keytype, (void*)key, 0); + } + + return info; +} + +static bool +test_certificate_template(const char *cert_prop, const CERT_CONTEXT *cert_ctx) +{ + const CERT_INFO *info = cert_ctx->pCertInfo; + const CERT_EXTENSION *ext; + DWORD cbext; + void *pvext; + struct gc_arena gc = gc_new(); + const WCHAR *tmpl_name = wide_string(cert_prop, &gc); + + /* check for V2 extension (Windows 2003+) */ + ext = CertFindExtension(szOID_CERTIFICATE_TEMPLATE, info->cExtension, info->rgExtension); + if (ext) + { + pvext = decode_object(&gc, X509_CERTIFICATE_TEMPLATE, &ext->Value, 0, &cbext); + if (pvext && cbext >= sizeof(CERT_TEMPLATE_EXT)) + { + const CERT_TEMPLATE_EXT *cte = (const CERT_TEMPLATE_EXT*)pvext; + if (!stricmp(cert_prop, cte->pszObjId)) + { + /* found direct OID match with certificate property specified */ + gc_free(&gc); + return true; + } + + const CRYPT_OID_INFO *tmpl_oid = find_oid(CRYPT_OID_INFO_NAME_KEY, tmpl_name, + CRYPT_TEMPLATE_OID_GROUP_ID, true); + if (tmpl_oid && !stricmp(tmpl_oid->pszOID, cte->pszObjId)) + { + /* found OID match in extension against resolved key */ + gc_free(&gc); + return true; + } + } + } + + /* no extension found, exit */ + gc_free(&gc); + return false; +} + static const CERT_CONTEXT * find_certificate_in_store(const char *cert_prop, HCERTSTORE cert_store) { @@ -186,6 +274,7 @@ * SUBJ: * THUMB:, e.g. * THUMB:f6 49 24 41 01 b4 fb 44 0c ce f4 36 ae d0 c4 c9 df 7a b6 28 + * TMPL: