From patchwork Mon Apr 21 21:44:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Klemens Nanni X-Patchwork-Id: 4224 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:e392:b0:63e:cbae:3930 with SMTP id oe18csp1985466mab; Mon, 21 Apr 2025 14:52:31 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCX4PfiFxjou4NChLXgeBBjVjHpsZDGDtlaWrx9edXsJ3vx8GRWgYZ4G0p4t1HHn4i6mbDdffzZGKoA=@openvpn.net X-Google-Smtp-Source: AGHT+IHtLMZ99U2Y9w1xyOZ5M4ocLGcNLAd72uw35zPkVDlIqV3L/Rylh025dfonUoFDJnJVmMb+ X-Received: by 2002:a05:6e02:1a0e:b0:3d6:d3f7:8826 with SMTP id e9e14a558f8ab-3d894286298mr125964125ab.20.1745272351069; Mon, 21 Apr 2025 14:52:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1745272351; cv=none; d=google.com; s=arc-20240605; b=ZD8o6czJKpGBK9On5LAUixTXPfMDIYyq6oPKnJBa2RFllr8AJoKMVIR/buMYiHS6Lx slS7l8qTIF8Phd4FPBgclrs1i7do+DGjyVSTdCzGHZxzr0fS3ZmpcMr7arjNyAbzr24j Vn13TuIhveDz6RMBmNo3sas5RfnyqW/rDW7yBzF3zkwa6+f3aJiKfSlTWyc9Msqhuqde 33DKXgvk4tWsGQwVJPXjDCeWkf27SmPlUaJyIKlqf5nQ2OEpGDM4IZKKTUjlE8LNmgRw qSJorP8rBL/xjTcOWoI1DDMMvcvdmkx0kW0y5ovIE/Hi3WkC8nl5pF4hCmnyhhfajzIW FqUw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:content-transfer-encoding:cc:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:message-id:date:to:from:dkim-signature:dkim-signature; bh=zQnMlcLhW6c3As082mwtpADJ8cAisEbS+uTa7qlHylg=; fh=H9DkLl0NO34dAYnSbzYiT/PzSqJHpq8eFXrYk4twe60=; b=fNt/W7BYYZpThu+/0hHrlzK5G+sfd9cbvJ1Vf1sVeQn0/pXkK9bG7giNLt5y+POW59 yYYmcYpy81n0Mv3MJAL/9fu51MSLHfc2BaAcL+6y44ckRFL9DTyaZ7YvVzCeWYQAM/vC yC2S2tC4ATXAciYs3EANjQS63tkvxUrm1nShGx8VsyKyJGN9wmOHaxubKuO6V9UpxKHC fnEUamofBwLpwRK2+QmjoEbPvdqolEeGg9SzkT1t7Mc+3gICrJkkvKtLbWHgUfivHmph bvmnl5Meg/pNmosxxyDqnIzWC5RmB5l1P5L1BzbhThT9pywtaW/tiSFvResRgJHBj7mt pydg==; 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=hJk7UOfP; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=CNngHcDt; 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=yandex-team.ru Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id e9e14a558f8ab-3d821f1a67esi70691225ab.154.2025.04.21.14.52.30 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Apr 2025 14:52:30 -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=hJk7UOfP; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=CNngHcDt; 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=yandex-team.ru 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 1u6z3u-0001kH-Sn; Mon, 21 Apr 2025 21:52:23 +0000 Received: from [172.30.29.66] (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 1u6z3s-0001jw-Dc for openvpn-devel@lists.sourceforge.net; Mon, 21 Apr 2025 21:52:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Subject:Content-Transfer-Encoding:MIME-Version: Message-ID:Date: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:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=BO8MIfDIhBH68U890+Su2AZoYxuXTGeHwZu/JGrtzGs=; b=hJk7UOfPBnIS0utcJ5xTpiiWn4 dBsivYg4jjP0xSqKes96A8Pli642696TFPnYjp1zMGfuxwJ6mpVbXLXKKWq6Ox+TLLh267QJEdt2O SkHiM+5gY3FN97Kmlwiv5+8DTQH4EvH0Fqq77tSW/cBxb47e1CegkXRvo6tFvEkW2l2k=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Subject:Content-Transfer-Encoding:MIME-Version:Message-ID:Date: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:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=BO8MIfDIhBH68U890+Su2AZoYxuXTGeHwZu/JGrtzGs=; b=C NngHcDtQM/U44sBOBJnutoINaYEa9ThJrG3SYZy8moc8KRte7tO/GYGwcYT3f+Lv2IzFDiCb0MB+u L7Ml0tRjXUt9u1Nla/bWqULVr9tTGu7k0etXdVhg3Gm/bOVMhnOHP8z9WhzgIo+dXus41yPdaib4w q5KzqLAusO434+uk=; Received: from 94-29-31-189.dynamic.spd-mgts.ru ([94.29.31.189] helo=localhost) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1u6z3c-0008Hc-Lo for openvpn-devel@lists.sourceforge.net; Mon, 21 Apr 2025 21:52:21 +0000 Received: from localhost (localhost [local]) by localhost (OpenSMTPD) with ESMTPA id 9a8bde08; Tue, 22 Apr 2025 00:44:36 +0300 (MSK) From: Klemens Nanni To: openvpn-devel@lists.sourceforge.net Date: Tue, 22 Apr 2025 00:44:34 +0300 Message-ID: <20250421214434.83431-1-klemens@yandex-team.ru> X-Mailer: git-send-email 2.49.0 MIME-Version: 1.0 X-Helo-Check: bad, Not FQDN (localhost) X-Spam-Score: 8.8 (++++++++) X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has identified this incoming email as possible 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: This allows for accepting clients based on their certificate authority: x509-username-field issuer CN verify-x509-name ...CA=ExampleCA_ match-prefix `tls-verify` or `plugin` can do the equivalent, but require additional code execution and always incur overhead or may not be an option when running with reduced privileges, e.g. `chroot`. Content analysis details: (8.8 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 3.6 RCVD_IN_PBL RBL: Received via a relay in Spamhaus PBL [94.29.31.189 listed in zen.spamhaus.org] 0.0 FSL_HELO_NON_FQDN_1 No description available. 3.6 HELO_LOCALHOST No description available. 0.0 TVD_RCVD_IP Message was received from an IP address 0.0 RCVD_IN_VALIDITY_RPBL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [94.29.31.189 listed in bl.score.senderscore.com] 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. [94.29.31.189 listed in sa-accredit.habeas.com] 0.9 SPF_FAIL SPF: sender does not match SPF record (fail) [SPF failed: Rejected by SPF record] 0.4 RDNS_DYNAMIC Delivered to internal network by host with dynamic-looking rDNS 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-VA-Spam-Flag: YES X-Spam-Flag: YES X-Headers-End: 1u6z3c-0008Hc-Lo Subject: [Openvpn-devel] [SPAM] [PATCH 1/1] Accept "issuer" in `x509-username-field` for the peer certificate's issuer name 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: Klemens Nanni Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1830050700892573771?= X-GMAIL-MSGID: =?utf-8?q?1830050700892573771?= This allows for accepting clients based on their certificate authority: x509-username-field issuer CN verify-x509-name ...CA=ExampleCA_ match-prefix `tls-verify` or `plugin` can do the equivalent, but require additional code execution and always incur overhead or may not be an option when running with reduced privileges, e.g. `chroot`. Tested against - FreeBSD 13, OpenSSL 1.1.1t, OpenVPN 2.5.6 - OpenBSD 7.7-stable, LibreSSL 4.1.0, OpenVPN 2.6.4 - OpenBSD 7.7-current, LibreSSL 4.1.0, OpenVPN f7aedca7 Signed-off-by: Klemens Nanni --- doc/man-sections/tls-options.rst | 18 ++++++++++++++---- src/openvpn/ssl_verify_openssl.c | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/doc/man-sections/tls-options.rst b/doc/man-sections/tls-options.rst index 0638d095..f60b711c 100644 --- a/doc/man-sections/tls-options.rst +++ b/doc/man-sections/tls-options.rst @@ -77,9 +77,8 @@ certificates and keys: https://github.com/OpenVPN/easy-rsa CAs in the capath directory are expected to be named .. CRLs are expected to be named .r. See the ``-CApath`` option of - ``openssl verify``, and the ``-hash`` option of ``openssl x509``, - ``openssl crl`` and ``X509_LOOKUP_hash_dir()``\(3) - for more information. + ``openssl verify``, the ``-hash`` option of ``openssl x509``, ``openssl crl`` + and ``X509_LOOKUP_hash_dir(3)`` for more information. Similar to the ``--crl-verify`` option, CRLs are not mandatory - OpenVPN will log the usual warning in the logs if the relevant CRL is @@ -664,7 +663,7 @@ If the option is inlined, ``algo`` is always :code:`SHA256`. Valid syntax: :: - verify-x509 name type + verify-x509-name type Which X.509 name is compared to ``name`` depends on the setting of type. ``type`` can be :code:`subject` to match the complete subject DN @@ -768,3 +767,14 @@ If the option is inlined, ``algo`` is always :code:`SHA256`. Non-compliant symbols are being replaced with the :code:`_` symbol, same as the field separator, so concatenating multiple fields with such or :code:`_` symbols can potentially lead to username collisions. + + The special name :code:`issuer` will yield the certificate's issuer name in + *sep_comma_plus_space,sname,utf8,esc_ctrl* format, see the ``-issuer`` option + of ``openssl x509`` and ``openssl-namedisplay-options(1)`` for more information: + :: + + x509-username-field issuer CN + verify-x509-name 'C=DE, ..., CN=ExampleCA_' match-prefix + + This example prepends the default username with the certificate authority to + verify it without the need of ``--tls-verify`` or ``--plugin``. diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c index ce1e7da1..baebe63c 100644 --- a/src/openvpn/ssl_verify_openssl.c +++ b/src/openvpn/ssl_verify_openssl.c @@ -283,6 +283,32 @@ backend_x509_get_username(char *common_name, int cn_len, snprintf(common_name, cn_len, "0x%s", serial); gc_free(&gc); } + else if (strcmp("ISSUER", x509_username_field) == 0) + { + BIO *issuer_bio = BIO_new(BIO_s_mem()); + BUF_MEM *issuer_mem; + + if (!issuer_bio) + { + return FAILURE; + } + + /* match x509_get_subject() format seen in "VERIFY ..." output */ + X509_NAME_print_ex(issuer_bio, X509_get_issuer_name(peer_cert), + 0, XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN + | ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_ESC_CTRL); + + if (BIO_eof(issuer_bio) + || BIO_get_mem_ptr(issuer_bio, &issuer_mem) <= 0 + || cn_len < issuer_mem->length) + { + BIO_free(issuer_bio); + return FAILURE; + } + + strncpynt(common_name, issuer_mem->data, cn_len); + BIO_free(issuer_bio); + } else #endif /* ifdef ENABLE_X509ALTUSERNAME */ if (FAILURE == extract_x509_field_ssl(X509_get_subject_name(peer_cert),