From nobody Sun Sep 28 15:29:08 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1758276727; cv=none; d=zohomail.com; s=zohoarc; b=kqnyiLOTRlJhursKreVZOlwb7xFX4ycrky4yMr3RgZxsAjTzVSj7+jT0E0ACRtxdugKZSKe3soT87Kah+1MA0py9TNAnlAsZyroNSZjAErmUEugf4vk1A7HYrzb1f/8fiBMO7jfYbVxXAdkBhERPn5sN42pM4EXhMG4WSQagc7s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758276727; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=90T0fE5TCoM86apcPD0Nr1rMxCkCs13+sdEeAAac0VA=; b=lglt9VVC1D74CAvlB1eOhTtu7Ml3YLpOZ81tEWVcTOLpdZPxxRrp9psPgqRpQmdvWM2vgbR8wCY4CqbX2OUyl/3WMUYvraWY6Y/+zw5Ndu5txLHhC0/nYNWbjdu2ykpskYXrPi9IgpuCHxgtH0BgrCRpEC5X37ZzcGn0bsfdee4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1758276727162941.770548125072; Fri, 19 Sep 2025 03:12:07 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uzY4g-0002hH-R5; Fri, 19 Sep 2025 06:10:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4c-0002fx-CE for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:38 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4Z-0007Ne-Rg for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:37 -0400 Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-520-6C6AyPVGMci2iGk7DLKAvQ-1; Fri, 19 Sep 2025 06:10:27 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6660F19560A1; Fri, 19 Sep 2025 10:10:26 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1290F1800446; Fri, 19 Sep 2025 10:10:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758276630; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=90T0fE5TCoM86apcPD0Nr1rMxCkCs13+sdEeAAac0VA=; b=aMYuBokhfwoWs6y4kPspN5KT0OUixIqzqQr4yXrm9E8VEU2JbGr6oc+dC9na6mHjKZZF2g TC2rjhAC3CgYqujgRuUU1UVdan/5FrsNW7qVOPSzFNn1dndt09IL3GsjEZLnnBW6xIN2Nt hkoSNFCAXOBEnw/xBace16YhvVNAAK0= X-MC-Unique: 6C6AyPVGMci2iGk7DLKAvQ-1 X-Mimecast-MFC-AGG-ID: 6C6AyPVGMci2iGk7DLKAvQ_1758276626 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Henry Kleynhans Subject: [PATCH v2 1/6] crypto: only verify CA certs in chain of trust Date: Fri, 19 Sep 2025 11:10:17 +0100 Message-ID: <20250919101022.1491007-2-berrange@redhat.com> In-Reply-To: <20250919101022.1491007-1-berrange@redhat.com> References: <20250919101022.1491007-1-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.005, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1758276728673116600 From: Henry Kleynhans The CA file provided to qemu may contain CA certificates which do not form part of the chain of trust for the specific certificate we are sanity checking. This patch changes the sanity checking from validating every CA certificate to only checking the CA certificates which are part of the chain of trust (issuer chain). Other certificates are ignored. Reviewed-by: Daniel P. Berrang=C3=A9 Signed-off-by: Henry Kleynhans Signed-off-by: Daniel P. Berrang=C3=A9 --- crypto/tlscredsx509.c | 57 ++++++++++++++++++++++++--- tests/unit/test-crypto-tlscredsx509.c | 25 +++++++++++- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c index cd1f504471..797854ac89 100644 --- a/crypto/tlscredsx509.c +++ b/crypto/tlscredsx509.c @@ -315,6 +315,51 @@ qcrypto_tls_creds_check_cert(QCryptoTLSCredsX509 *cred= s, return 0; } =20 +static int +qcrypto_tls_creds_check_authority_chain(QCryptoTLSCredsX509 *creds, + gnutls_x509_crt_t cert, + gnutls_x509_crt_t *cacerts, + unsigned int ncacerts, + const char *cacertFile, + bool isServer, + bool isCA, + Error **errp) +{ + gnutls_x509_crt_t *cert_to_check =3D &cert; + int checking_issuer =3D 1; + int retval =3D 0; + + while (checking_issuer) { + checking_issuer =3D 0; + + if (gnutls_x509_crt_check_issuer(*cert_to_check, + *cert_to_check)) { + /* + * The cert is self-signed indicating we have + * reached the root of trust. + */ + return qcrypto_tls_creds_check_cert( + creds, *cert_to_check, cacertFile, + isServer, isCA, errp); + } + for (int i =3D 0; i < ncacerts; i++) { + if (gnutls_x509_crt_check_issuer(*cert_to_check, + cacerts[i])) { + retval =3D qcrypto_tls_creds_check_cert( + creds, cacerts[i], cacertFile, + isServer, isCA, errp); + if (retval < 0) { + return retval; + } + cert_to_check =3D &cacerts[i]; + checking_issuer =3D 1; + break; + } + } + } + + return -1; +} =20 static int qcrypto_tls_creds_check_cert_pair(gnutls_x509_crt_t cert, @@ -499,12 +544,12 @@ qcrypto_tls_creds_x509_sanity_check(QCryptoTLSCredsX5= 09 *creds, goto cleanup; } =20 - for (i =3D 0; i < ncacerts; i++) { - if (qcrypto_tls_creds_check_cert(creds, - cacerts[i], cacertFile, - isServer, true, errp) < 0) { - goto cleanup; - } + if (cert && + qcrypto_tls_creds_check_authority_chain(creds, cert, + cacerts, ncacerts, + cacertFile, isServer, + true, errp) < 0) { + goto cleanup; } =20 if (cert && ncacerts && diff --git a/tests/unit/test-crypto-tlscredsx509.c b/tests/unit/test-crypto= -tlscredsx509.c index 3c25d75ca1..a7ea5f422d 100644 --- a/tests/unit/test-crypto-tlscredsx509.c +++ b/tests/unit/test-crypto-tlscredsx509.c @@ -589,6 +589,12 @@ int main(int argc, char **argv) true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); + TLS_CERT_REQ(cacertlevel1creq_invalid, cacertrootreq, + "UK", "qemu level 1c invalid", NULL, NULL, NULL, NULL, + true, true, true, + true, true, GNUTLS_KEY_KEY_CERT_SIGN, + false, false, NULL, NULL, + 360, 400); TLS_CERT_REQ(cacertlevel2areq, cacertlevel1areq, "UK", "qemu level 2a", NULL, NULL, NULL, NULL, true, true, true, @@ -617,16 +623,32 @@ int main(int argc, char **argv) cacertlevel2areq.crt, }; =20 + test_tls_write_cert_chain(WORKDIR "cacertchain-ctx.pem", certchain, G_N_ELEMENTS(certchain)); =20 + gnutls_x509_crt_t certchain_with_invalid[] =3D { + cacertrootreq.crt, + cacertlevel1areq.crt, + cacertlevel1breq.crt, + cacertlevel1creq_invalid.crt, + cacertlevel2areq.crt, + }; + + test_tls_write_cert_chain(WORKDIR "cacertchain-with-invalid-ctx.pem", + certchain_with_invalid, + G_N_ELEMENTS(certchain_with_invalid)); + TLS_TEST_REG(chain1, true, WORKDIR "cacertchain-ctx.pem", servercertlevel3areq.filename, false); TLS_TEST_REG(chain2, false, WORKDIR "cacertchain-ctx.pem", clientcertlevel2breq.filename, false); + TLS_TEST_REG(certchainwithexpiredcert, false, + WORKDIR "cacertchain-with-invalid-ctx.pem", + clientcertlevel2breq.filename, false); =20 /* Some missing certs - first two are fatal, the last * is ok @@ -640,7 +662,6 @@ int main(int argc, char **argv) TLS_TEST_REG(missingclient, false, cacert1req.filename, "clientcertdoesnotexist.pem", false); - ret =3D g_test_run(); =20 test_tls_discard_cert(&cacertreq); @@ -694,10 +715,12 @@ int main(int argc, char **argv) test_tls_discard_cert(&cacertrootreq); test_tls_discard_cert(&cacertlevel1areq); test_tls_discard_cert(&cacertlevel1breq); + test_tls_discard_cert(&cacertlevel1creq_invalid); test_tls_discard_cert(&cacertlevel2areq); test_tls_discard_cert(&servercertlevel3areq); test_tls_discard_cert(&clientcertlevel2breq); unlink(WORKDIR "cacertchain-ctx.pem"); + unlink(WORKDIR "cacertchain-with-invalid-ctx.pem"); =20 test_tls_cleanup(KEYFILE); rmdir(WORKDIR); --=20 2.50.1 From nobody Sun Sep 28 15:29:08 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1758276802; cv=none; d=zohomail.com; s=zohoarc; b=J9viLjKme8shUyI7IDrbwxtYNXc7zdzHwITwQfHES3GZ8CTtJk09K6FE9tvJITAxeAQAXwtNLpYaNcHgOUgrzE1bekFuk9QhcKrk5SuAz/U44MYCTbniGKhgXKJjph2TSp7/MAZyBqqQl6ISMoN45+z+1nQabAuyiQCx5DLWKlo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758276802; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=6o8AdnpvSOYyiNoi2F0wZnoPvnTju5K0FpVbmUqYKjE=; b=hRQ0WLw9rmZVIvccp5u/6hCcZ1xJ5lwRkYSaTnzrV7m4QWgByulOzkAHF98KdXWZtvMxFUj3aXDOh+T/4jD3cerJyeRt+VaFKXqnrVd1H8IgHtp+XTfMhHJ5MVvktUl1/q/iIJeTowLSeEiBAWhHOpk8WUvfQnOgAxJr6A9Ijso= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1758276802506941.2636709833188; Fri, 19 Sep 2025 03:13:22 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uzY4d-0002gJ-WD; Fri, 19 Sep 2025 06:10:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4c-0002f3-0V for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:38 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4Z-0007PZ-Pz for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:37 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-460-c-o6BCK0MrW8DVnnd2ByEw-1; Fri, 19 Sep 2025 06:10:30 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0DDF81800366; Fri, 19 Sep 2025 10:10:28 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id DE8C418004A3; Fri, 19 Sep 2025 10:10:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758276633; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6o8AdnpvSOYyiNoi2F0wZnoPvnTju5K0FpVbmUqYKjE=; b=Fqt3PlC/oTXM5F7zZjqiCGZ5nkSeQ+Bv9xMYFATIKjE15GJLDG6qGmnl+Bwfj3svENiK+1 6rETI/jz4GNF/4ZXNMZCBke+ucb4saZPGmPwGjNTCDSENdnqwFLJVIiB+EcaD8c9Uw2cdo TOwcKOWoWB6xbKux2wj3q+QqnsI2i9M= X-MC-Unique: c-o6BCK0MrW8DVnnd2ByEw-1 X-Mimecast-MFC-AGG-ID: c-o6BCK0MrW8DVnnd2ByEw_1758276629 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v2 2/6] crypto: remove extraneous pointer usage in gnutls certs Date: Fri, 19 Sep 2025 11:10:18 +0100 Message-ID: <20250919101022.1491007-3-berrange@redhat.com> In-Reply-To: <20250919101022.1491007-1-berrange@redhat.com> References: <20250919101022.1491007-1-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.005, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1758276805694116601 The 'gnutls_x509_crt_t' type is already a pointer, not a struct, so the extra level of pointer indirection is not needed. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Daniel P. Berrang=C3=A9 --- crypto/tlscredsx509.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c index 797854ac89..91d8dde633 100644 --- a/crypto/tlscredsx509.c +++ b/crypto/tlscredsx509.c @@ -325,25 +325,25 @@ qcrypto_tls_creds_check_authority_chain(QCryptoTLSCre= dsX509 *creds, bool isCA, Error **errp) { - gnutls_x509_crt_t *cert_to_check =3D &cert; + gnutls_x509_crt_t cert_to_check =3D cert; int checking_issuer =3D 1; int retval =3D 0; =20 while (checking_issuer) { checking_issuer =3D 0; =20 - if (gnutls_x509_crt_check_issuer(*cert_to_check, - *cert_to_check)) { + if (gnutls_x509_crt_check_issuer(cert_to_check, + cert_to_check)) { /* * The cert is self-signed indicating we have * reached the root of trust. */ return qcrypto_tls_creds_check_cert( - creds, *cert_to_check, cacertFile, + creds, cert_to_check, cacertFile, isServer, isCA, errp); } for (int i =3D 0; i < ncacerts; i++) { - if (gnutls_x509_crt_check_issuer(*cert_to_check, + if (gnutls_x509_crt_check_issuer(cert_to_check, cacerts[i])) { retval =3D qcrypto_tls_creds_check_cert( creds, cacerts[i], cacertFile, @@ -351,7 +351,7 @@ qcrypto_tls_creds_check_authority_chain(QCryptoTLSCreds= X509 *creds, if (retval < 0) { return retval; } - cert_to_check =3D &cacerts[i]; + cert_to_check =3D cacerts[i]; checking_issuer =3D 1; break; } --=20 2.50.1 From nobody Sun Sep 28 15:29:08 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1758276775; cv=none; d=zohomail.com; s=zohoarc; b=P+q/50bVjEacZJqWD3JsgA8rR/jTyYFbmToPJrQPgklVVKBdylBCdCcIjSQ3IsKQNXeEmFcVDGrcAeon+ASv/g/zMJeRj9JugpXnGnB08b/2JMmX24BkM4zaTTJEuHtmXawxwtE/Yhnz8Ugye68n0z0xSALotwmr2Scl6jVWhx4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758276775; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=iHpW5tObD2G4qdgSz7cmwR50mc9lkloIXwlFW6c0nNI=; b=JLVCePnR9HnHfKB+SHt/7SorHGv8vMBM30OPq/tmByywURpx1t2id740bYUpDzH0sLKSD2lSg+mk181XeNZvPCMIjM1SNB+j5pzvZhQJRp4zjb+Zh9135lqPyM/+LS9FdOI923CELOfEE3sXCwJThjkikpR5uoVOM4yJwE++B8A= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1758276775255950.1501081489224; Fri, 19 Sep 2025 03:12:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uzY4h-0002hh-F1; Fri, 19 Sep 2025 06:10:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4e-0002gh-MJ for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:40 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4a-0007QE-Dv for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:40 -0400 Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-147-bysoLm0JNZ6yYGe-AeXRfw-1; Fri, 19 Sep 2025 06:10:30 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C4AE019560B2; Fri, 19 Sep 2025 10:10:29 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 71CE118004A3; Fri, 19 Sep 2025 10:10:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758276634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iHpW5tObD2G4qdgSz7cmwR50mc9lkloIXwlFW6c0nNI=; b=h9lGUQhOqUAu5Y9g3hA5UEr9lB2X0T1vgbSfTJSiEuF8QTA8wG6y30PzU8r8L2ofz+Xnel +AsyTMoDwpr5C8f012mqvJVPwaMYMYuRJjcD3wAz6Ka7kGrMzOhLqBJjn1n747CAzuGYLJ yyCydFx11E7LF6V+rye8PASMx00FAAU= X-MC-Unique: bysoLm0JNZ6yYGe-AeXRfw-1 X-Mimecast-MFC-AGG-ID: bysoLm0JNZ6yYGe-AeXRfw_1758276630 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , matoro Subject: [PATCH v2 3/6] crypto: allow client/server cert chains Date: Fri, 19 Sep 2025 11:10:19 +0100 Message-ID: <20250919101022.1491007-4-berrange@redhat.com> In-Reply-To: <20250919101022.1491007-1-berrange@redhat.com> References: <20250919101022.1491007-1-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.005, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1758276777470116600 From: matoro The existing implementation assumes that client/server certificates are single individual certificates. If using publicly-issued certificates, or internal CAs that use an intermediate issuer, this is unlikely to be the case, and they will instead be certificate chains. While this can be worked around by moving the intermediate certificates to the CA certificate, which DOES currently support multiple certificates, this instead allows the issued certificate chains to be used as-is, without requiring the overhead of shuffling certificates around. Corresponding libvirt change is available here: https://gitlab.com/libvirt/libvirt/-/merge_requests/222 Reviewed-by: Daniel P. Berrang=C3=A9 Signed-off-by: matoro [DB: adapted for code conflicts with multi-CA patch] Signed-off-by: Daniel P. Berrang=C3=A9 --- crypto/tlscredsx509.c | 156 ++++++++++++-------------- tests/unit/test-crypto-tlscredsx509.c | 77 +++++++++++++ 2 files changed, 147 insertions(+), 86 deletions(-) diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c index 91d8dde633..311de3237d 100644 --- a/crypto/tlscredsx509.c +++ b/crypto/tlscredsx509.c @@ -317,7 +317,8 @@ qcrypto_tls_creds_check_cert(QCryptoTLSCredsX509 *creds, =20 static int qcrypto_tls_creds_check_authority_chain(QCryptoTLSCredsX509 *creds, - gnutls_x509_crt_t cert, + gnutls_x509_crt_t *certs, + unsigned int ncerts, gnutls_x509_crt_t *cacerts, unsigned int ncacerts, const char *cacertFile, @@ -325,9 +326,33 @@ qcrypto_tls_creds_check_authority_chain(QCryptoTLSCred= sX509 *creds, bool isCA, Error **errp) { - gnutls_x509_crt_t cert_to_check =3D cert; + gnutls_x509_crt_t cert_to_check =3D certs[ncerts - 1]; int checking_issuer =3D 1; int retval =3D 0; + gnutls_datum_t dn =3D {}, dnissuer =3D {}; + + for (int i =3D 0; i < (ncerts - 1); i++) { + if (!gnutls_x509_crt_check_issuer(certs[i], certs[i + 1])) { + retval =3D gnutls_x509_crt_get_dn2(certs[i], &dn); + if (retval < 0) { + error_setg(errp, "Unable to fetch cert DN: %s", + gnutls_strerror(retval)); + return -1; + } + retval =3D gnutls_x509_crt_get_dn2(certs[i + 1], &dnissuer); + if (retval < 0) { + gnutls_free(dn.data); + error_setg(errp, "Unable to fetch cert DN: %s", + gnutls_strerror(retval)); + return -1; + } + error_setg(errp, "Cert '%s' does not match issuer of cert '%s'= ", + dnissuer.data, dn.data); + gnutls_free(dn.data); + gnutls_free(dnissuer.data); + return -1; + } + } =20 while (checking_issuer) { checking_issuer =3D 0; @@ -362,7 +387,8 @@ qcrypto_tls_creds_check_authority_chain(QCryptoTLSCreds= X509 *creds, } =20 static int -qcrypto_tls_creds_check_cert_pair(gnutls_x509_crt_t cert, +qcrypto_tls_creds_check_cert_pair(gnutls_x509_crt_t *certs, + size_t ncerts, const char *certFile, gnutls_x509_crt_t *cacerts, size_t ncacerts, @@ -372,7 +398,7 @@ qcrypto_tls_creds_check_cert_pair(gnutls_x509_crt_t cer= t, { unsigned int status; =20 - if (gnutls_x509_crt_list_verify(&cert, 1, + if (gnutls_x509_crt_list_verify(certs, ncerts, cacerts, ncacerts, NULL, 0, 0, &status) < 0) { @@ -414,66 +440,14 @@ qcrypto_tls_creds_check_cert_pair(gnutls_x509_crt_t c= ert, } =20 =20 -static gnutls_x509_crt_t -qcrypto_tls_creds_load_cert(QCryptoTLSCredsX509 *creds, - const char *certFile, - bool isServer, - Error **errp) -{ - gnutls_datum_t data; - gnutls_x509_crt_t cert =3D NULL; - g_autofree char *buf =3D NULL; - gsize buflen; - GError *gerr =3D NULL; - int ret =3D -1; - int err; - - trace_qcrypto_tls_creds_x509_load_cert(creds, isServer, certFile); - - err =3D gnutls_x509_crt_init(&cert); - if (err < 0) { - error_setg(errp, "Unable to initialize certificate: %s", - gnutls_strerror(err)); - goto cleanup; - } - - if (!g_file_get_contents(certFile, &buf, &buflen, &gerr)) { - error_setg(errp, "Cannot load CA cert list %s: %s", - certFile, gerr->message); - g_error_free(gerr); - goto cleanup; - } - - data.data =3D (unsigned char *)buf; - data.size =3D strlen(buf); - - err =3D gnutls_x509_crt_import(cert, &data, GNUTLS_X509_FMT_PEM); - if (err < 0) { - error_setg(errp, isServer ? - "Unable to import server certificate %s: %s" : - "Unable to import client certificate %s: %s", - certFile, - gnutls_strerror(err)); - goto cleanup; - } - - ret =3D 0; - - cleanup: - if (ret !=3D 0) { - gnutls_x509_crt_deinit(cert); - cert =3D NULL; - } - return cert; -} - - static int -qcrypto_tls_creds_load_ca_cert_list(QCryptoTLSCredsX509 *creds, - const char *certFile, - gnutls_x509_crt_t **certs, - unsigned int *ncerts, - Error **errp) +qcrypto_tls_creds_load_cert_list(QCryptoTLSCredsX509 *creds, + const char *certFile, + gnutls_x509_crt_t **certs, + unsigned int *ncerts, + bool isServer, + bool isCA, + Error **errp) { gnutls_datum_t data; g_autofree char *buf =3D NULL; @@ -496,7 +470,9 @@ qcrypto_tls_creds_load_ca_cert_list(QCryptoTLSCredsX509= *creds, if (gnutls_x509_crt_list_import2(certs, ncerts, &data, GNUTLS_X509_FMT_PEM, 0) < 0) { error_setg(errp, - "Unable to import CA certificate list %s", + isCA ? "Unable to import CA certificate list %s" : + (isServer ? "Unable to import server certificate %s" : + "Unable to import client certificate %s"), certFile); return -1; } @@ -512,7 +488,8 @@ qcrypto_tls_creds_x509_sanity_check(QCryptoTLSCredsX509= *creds, const char *certFile, Error **errp) { - gnutls_x509_crt_t cert =3D NULL; + gnutls_x509_crt_t *certs =3D NULL; + unsigned int ncerts =3D 0; gnutls_x509_crt_t *cacerts =3D NULL; unsigned int ncacerts =3D 0; size_t i; @@ -520,41 +497,48 @@ qcrypto_tls_creds_x509_sanity_check(QCryptoTLSCredsX5= 09 *creds, =20 if (certFile && access(certFile, R_OK) =3D=3D 0) { - cert =3D qcrypto_tls_creds_load_cert(creds, - certFile, isServer, - errp); - if (!cert) { + if (qcrypto_tls_creds_load_cert_list(creds, + certFile, + &certs, + &ncerts, + isServer, + false, + errp) < 0) { goto cleanup; } } if (access(cacertFile, R_OK) =3D=3D 0) { - if (qcrypto_tls_creds_load_ca_cert_list(creds, - cacertFile, - &cacerts, - &ncacerts, - errp) < 0) { + if (qcrypto_tls_creds_load_cert_list(creds, + cacertFile, + &cacerts, + &ncacerts, + isServer, + true, + errp) < 0) { goto cleanup; } } =20 - if (cert && - qcrypto_tls_creds_check_cert(creds, - cert, certFile, isServer, - false, errp) < 0) { - goto cleanup; + for (i =3D 0; i < ncerts; i++) { + if (qcrypto_tls_creds_check_cert(creds, + certs[i], certFile, + isServer, (i !=3D 0), errp) < 0) { + goto cleanup; + } } =20 - if (cert && - qcrypto_tls_creds_check_authority_chain(creds, cert, + if (ncerts && + qcrypto_tls_creds_check_authority_chain(creds, + certs, ncerts, cacerts, ncacerts, cacertFile, isServer, true, errp) < 0) { goto cleanup; } =20 - if (cert && ncacerts && - qcrypto_tls_creds_check_cert_pair(cert, certFile, cacerts, - ncacerts, cacertFile, + if (ncerts && ncacerts && + qcrypto_tls_creds_check_cert_pair(certs, ncerts, certFile, + cacerts, ncacerts, cacertFile, isServer, errp) < 0) { goto cleanup; } @@ -562,8 +546,8 @@ qcrypto_tls_creds_x509_sanity_check(QCryptoTLSCredsX509= *creds, ret =3D 0; =20 cleanup: - if (cert) { - gnutls_x509_crt_deinit(cert); + for (i =3D 0; i < ncerts; i++) { + gnutls_x509_crt_deinit(certs[i]); } for (i =3D 0; i < ncacerts; i++) { gnutls_x509_crt_deinit(cacerts[i]); diff --git a/tests/unit/test-crypto-tlscredsx509.c b/tests/unit/test-crypto= -tlscredsx509.c index a7ea5f422d..4a32bc4d69 100644 --- a/tests/unit/test-crypto-tlscredsx509.c +++ b/tests/unit/test-crypto-tlscredsx509.c @@ -577,6 +577,12 @@ int main(int argc, char **argv) true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); + TLS_ROOT_REQ(someotherrootreq, + "UK", "some other random CA", NULL, NULL, NULL, NULL, + true, true, true, + true, true, GNUTLS_KEY_KEY_CERT_SIGN, + false, false, NULL, NULL, + 0, 0); TLS_CERT_REQ(cacertlevel1areq, cacertrootreq, "UK", "qemu level 1a", NULL, NULL, NULL, NULL, true, true, true, @@ -623,6 +629,32 @@ int main(int argc, char **argv) cacertlevel2areq.crt, }; =20 + gnutls_x509_crt_t cabundle[] =3D { + someotherrootreq.crt, + cacertrootreq.crt, + }; + + gnutls_x509_crt_t servercertchain[] =3D { + servercertlevel3areq.crt, + cacertlevel2areq.crt, + cacertlevel1areq.crt, + }; + + gnutls_x509_crt_t servercertchain_incomplete[] =3D { + servercertlevel3areq.crt, + cacertlevel2areq.crt, + }; + + gnutls_x509_crt_t servercertchain_unsorted[] =3D { + servercertlevel3areq.crt, + cacertlevel1areq.crt, + cacertlevel2areq.crt, + }; + + gnutls_x509_crt_t clientcertchain[] =3D { + clientcertlevel2breq.crt, + cacertlevel1breq.crt, + }; =20 test_tls_write_cert_chain(WORKDIR "cacertchain-ctx.pem", certchain, @@ -650,6 +682,46 @@ int main(int argc, char **argv) WORKDIR "cacertchain-with-invalid-ctx.pem", clientcertlevel2breq.filename, false); =20 + test_tls_write_cert_chain(WORKDIR "servercertchain-ctx.pem", + servercertchain, + G_N_ELEMENTS(servercertchain)); + + TLS_TEST_REG(serverchain, true, + cacertrootreq.filename, + WORKDIR "servercertchain-ctx.pem", false); + + test_tls_write_cert_chain(WORKDIR "cabundle-ctx.pem", + cabundle, + G_N_ELEMENTS(cabundle)); + + TLS_TEST_REG(multiplecaswithchain, true, + WORKDIR "cabundle-ctx.pem", + WORKDIR "servercertchain-ctx.pem", false); + + test_tls_write_cert_chain(WORKDIR "servercertchain_incomplete-ctx.pem", + servercertchain_incomplete, + G_N_ELEMENTS(servercertchain_incomplete)); + + TLS_TEST_REG(incompleteserverchain, true, + cacertrootreq.filename, + WORKDIR "servercertchain_incomplete-ctx.pem", true); + + test_tls_write_cert_chain(WORKDIR "servercertchain_unsorted-ctx.pem", + servercertchain_unsorted, + G_N_ELEMENTS(servercertchain_unsorted)); + + TLS_TEST_REG(unsortedserverchain, true, + cacertrootreq.filename, + WORKDIR "servercertchain_unsorted-ctx.pem", true); + + test_tls_write_cert_chain(WORKDIR "clientcertchain-ctx.pem", + clientcertchain, + G_N_ELEMENTS(clientcertchain)); + + TLS_TEST_REG(clientchain, false, + cacertrootreq.filename, + WORKDIR "clientcertchain-ctx.pem", false); + /* Some missing certs - first two are fatal, the last * is ok */ @@ -719,8 +791,13 @@ int main(int argc, char **argv) test_tls_discard_cert(&cacertlevel2areq); test_tls_discard_cert(&servercertlevel3areq); test_tls_discard_cert(&clientcertlevel2breq); + test_tls_discard_cert(&someotherrootreq); unlink(WORKDIR "cacertchain-ctx.pem"); unlink(WORKDIR "cacertchain-with-invalid-ctx.pem"); + unlink(WORKDIR "servercertchain-ctx.pem"); + unlink(WORKDIR "servercertchain_incomplete-ctx.pem"); + unlink(WORKDIR "servercertchain_unsorted-ctx.pem"); + unlink(WORKDIR "clientcertchain-ctx.pem"); =20 test_tls_cleanup(KEYFILE); rmdir(WORKDIR); --=20 2.50.1 From nobody Sun Sep 28 15:29:08 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1758276728; cv=none; d=zohomail.com; s=zohoarc; b=HAHMSnFirdp4sxzh9MDFYozawVj/AE6TeR4ZkHky0D+o5qXxQmJkxZbb5qu1bUK71hvEHWledJW3f2DtbVcNsZw2YqJib77kxz6ApjWDBC96GJLFNZP3+9OFLd53p9C3ar8XYuC5QAGnBvqKGZidJ/SVt8In0mo8NXgT+jN3QrQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758276728; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Ln0gbeYDAEVR4TU6/ZBixPEVPRJzGb9d/qq1+1wjRFA=; b=EnLK/uOA//1FCHCuzRoDxOb4lC+ht6JrchujPoxAdOtXgWp7fTLkFdnFzGKSC1CRBkegG0mAZHMIBrOP/YX5lRk69NezgZDCvmri+PveRRXk814SIDZest0ncZndnpyA74iOQbU4+mxY8c806fXlFba5OpnR2gyqHn2mJmskm7w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1758276728772950.744571643393; Fri, 19 Sep 2025 03:12:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uzY4i-0002ic-Lw; Fri, 19 Sep 2025 06:10:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4g-0002hJ-7f for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:42 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4a-0007Pu-NW for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:41 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-155-zdQWaTEYM-SYa1wMPi4HeA-1; Fri, 19 Sep 2025 06:10:32 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4CF45180057F for ; Fri, 19 Sep 2025 10:10:31 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 325181800446; Fri, 19 Sep 2025 10:10:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758276634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ln0gbeYDAEVR4TU6/ZBixPEVPRJzGb9d/qq1+1wjRFA=; b=ENKbykk3TjuqXil9UBCX5gttK36ThA+WdGAdNKTl2eMbE7ZZEK9bJJUA4iBR+ttCTPuAAL 0fSWAau06FoD0jtmmAZrqyhde5ldmI3xS778rWyNcduoh5/cHJmdQWclRl+wzqLLgF2wz4 4f7T9oiEB4oKXxuUlBnHUqRhmNIIfN0= X-MC-Unique: zdQWaTEYM-SYa1wMPi4HeA-1 X-Mimecast-MFC-AGG-ID: zdQWaTEYM-SYa1wMPi4HeA_1758276631 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 4/6] crypto: stop requiring "key encipherment" usage in x509 certs Date: Fri, 19 Sep 2025 11:10:20 +0100 Message-ID: <20250919101022.1491007-5-berrange@redhat.com> In-Reply-To: <20250919101022.1491007-1-berrange@redhat.com> References: <20250919101022.1491007-1-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.005, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1758276730741116600 This usage flag was deprecated by RFC8813, such that it is forbidden to be present for certs using ECDSA/ECDH algorithms, and in TLS 1.3 is conceptually obsolete. As such many valid certs will no longer have this key usage flag set, and QEMU should not be rejecting them, as this prevents use of otherwise valid & desirable algorithms. Signed-off-by: Daniel P. Berrang=C3=A9 --- crypto/tlscredsx509.c | 10 +------- docs/system/tls.rst | 13 +++------- tests/unit/crypto-tls-x509-helpers.h | 6 ++--- tests/unit/test-crypto-tlscredsx509.c | 36 +++++++++++++-------------- tests/unit/test-crypto-tlssession.c | 14 +++++------ tests/unit/test-io-channel-tls.c | 4 +-- 6 files changed, 34 insertions(+), 49 deletions(-) diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c index 311de3237d..89a8e261d5 100644 --- a/crypto/tlscredsx509.c +++ b/crypto/tlscredsx509.c @@ -144,7 +144,7 @@ qcrypto_tls_creds_check_cert_key_usage(QCryptoTLSCredsX= 509 *creds, if (status < 0) { if (status =3D=3D GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { usage =3D isCA ? GNUTLS_KEY_KEY_CERT_SIGN : - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT; + GNUTLS_KEY_DIGITAL_SIGNATURE; } else { error_setg(errp, "Unable to query certificate %s key usage: %s", @@ -171,14 +171,6 @@ qcrypto_tls_creds_check_cert_key_usage(QCryptoTLSCreds= X509 *creds, return -1; } } - if (!(usage & GNUTLS_KEY_KEY_ENCIPHERMENT)) { - if (critical) { - error_setg(errp, - "Certificate %s usage does not permit key " - "encipherment", certFile); - return -1; - } - } } =20 return 0; diff --git a/docs/system/tls.rst b/docs/system/tls.rst index e284c82801..a4f6781d62 100644 --- a/docs/system/tls.rst +++ b/docs/system/tls.rst @@ -118,7 +118,6 @@ information for each server, and use it to issue server= certificates. ip_address =3D 2620:0:cafe::87 ip_address =3D 2001:24::92 tls_www_server - encryption_key signing_key EOF # certtool --generate-privkey > server-hostNNN-key.pem @@ -134,9 +133,8 @@ the subject alt name extension data. The ``tls_www_serv= er`` keyword is the key purpose extension to indicate this certificate is intended for usage in a web server. Although QEMU network services are not in fact HTTP servers (except for VNC websockets), setting this key purpose is -still recommended. The ``encryption_key`` and ``signing_key`` keyword is -the key usage extension to indicate this certificate is intended for -usage in the data session. +still recommended. The ``signing_key`` keyword is the key usage extension +to indicate this certificate is intended for usage in the data session. =20 The ``server-hostNNN-key.pem`` and ``server-hostNNN-cert.pem`` files should now be securely copied to the server for which they were @@ -171,7 +169,6 @@ certificates. organization =3D Name of your organization cn =3D hostNNN.foo.example.com tls_www_client - encryption_key signing_key EOF # certtool --generate-privkey > client-hostNNN-key.pem @@ -187,9 +184,8 @@ the ``dns_name`` and ``ip_address`` fields are not incl= uded. The ``tls_www_client`` keyword is the key purpose extension to indicate this certificate is intended for usage in a web client. Although QEMU network clients are not in fact HTTP clients, setting this key purpose is still -recommended. The ``encryption_key`` and ``signing_key`` keyword is the -key usage extension to indicate this certificate is intended for usage -in the data session. +recommended. The ``signing_key`` keyword is the key usage extension to +indicate this certificate is intended for usage in the data session. =20 The ``client-hostNNN-key.pem`` and ``client-hostNNN-cert.pem`` files should now be securely copied to the client for which they were @@ -222,7 +218,6 @@ client and server instructions in one. ip_address =3D 2001:24::92 tls_www_server tls_www_client - encryption_key signing_key EOF # certtool --generate-privkey > both-hostNNN-key.pem diff --git a/tests/unit/crypto-tls-x509-helpers.h b/tests/unit/crypto-tls-x= 509-helpers.h index 2a0f7c04fd..7e9a508ad6 100644 --- a/tests/unit/crypto-tls-x509-helpers.h +++ b/tests/unit/crypto-tls-x509-helpers.h @@ -148,8 +148,7 @@ void test_tls_cleanup(const char *keyfile); .basicConstraintsIsCA =3D false, \ .keyUsageEnable =3D true, \ .keyUsageCritical =3D true, \ - .keyUsageValue =3D \ - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, \ + .keyUsageValue =3D GNUTLS_KEY_DIGITAL_SIGNATURE, \ .keyPurposeEnable =3D true, \ .keyPurposeCritical =3D true, \ .keyPurposeOID1 =3D GNUTLS_KP_TLS_WWW_CLIENT, \ @@ -168,8 +167,7 @@ void test_tls_cleanup(const char *keyfile); .basicConstraintsIsCA =3D false, \ .keyUsageEnable =3D true, \ .keyUsageCritical =3D true, \ - .keyUsageValue =3D \ - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, \ + .keyUsageValue =3D GNUTLS_KEY_DIGITAL_SIGNATURE, \ .keyPurposeEnable =3D true, \ .keyPurposeCritical =3D true, \ .keyPurposeOID1 =3D GNUTLS_KP_TLS_WWW_SERVER, \ diff --git a/tests/unit/test-crypto-tlscredsx509.c b/tests/unit/test-crypto= -tlscredsx509.c index 4a32bc4d69..fac6c64cad 100644 --- a/tests/unit/test-crypto-tlscredsx509.c +++ b/tests/unit/test-crypto-tlscredsx509.c @@ -166,14 +166,14 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(clientcertreq, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); =20 @@ -196,7 +196,7 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); =20 @@ -211,7 +211,7 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); =20 @@ -226,7 +226,7 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); =20 @@ -250,7 +250,7 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); /* no-basic */ @@ -264,7 +264,7 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); /* Key usage:dig-sig:critical */ @@ -278,7 +278,7 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); =20 @@ -303,7 +303,7 @@ int main(int argc, char **argv) "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T | + GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); @@ -406,7 +406,7 @@ int main(int argc, char **argv) "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T | + GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); @@ -508,21 +508,21 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(servercertexp1req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, -1); TLS_CERT_REQ(clientcertexp1req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, -1); =20 @@ -546,21 +546,21 @@ int main(int argc, char **argv) "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(servercertnew1req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 1, 2); TLS_CERT_REQ(clientcertnew1req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 1, 2); =20 @@ -611,14 +611,14 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(clientcertlevel2breq, cacertlevel1breq, "UK", "qemu client level 2b", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); =20 diff --git a/tests/unit/test-crypto-tlssession.c b/tests/unit/test-crypto-t= lssession.c index 554054e934..e8b2e0201c 100644 --- a/tests/unit/test-crypto-tlssession.c +++ b/tests/unit/test-crypto-tlssession.c @@ -472,14 +472,14 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(clientcertreq, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); =20 @@ -487,7 +487,7 @@ int main(int argc, char **argv) "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); =20 @@ -506,7 +506,7 @@ int main(int argc, char **argv) "192.168.122.1", "fec0::dead:beaf", true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); /* This intentionally doesn't replicate */ @@ -515,7 +515,7 @@ int main(int argc, char **argv) "192.168.122.1", "fec0::dead:beaf", true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); =20 @@ -619,14 +619,14 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(clientcertlevel2breq, cacertlevel1breq, "UK", "qemu client level 2b", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); =20 diff --git a/tests/unit/test-io-channel-tls.c b/tests/unit/test-io-channel-= tls.c index e036ac5df4..c2115d45fe 100644 --- a/tests/unit/test-io-channel-tls.c +++ b/tests/unit/test-io-channel-tls.c @@ -302,14 +302,14 @@ int main(int argc, char **argv) "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(clientcertreq, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, - GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMEN= T, + GNUTLS_KEY_DIGITAL_SIGNATURE, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); =20 --=20 2.50.1 From nobody Sun Sep 28 15:29:08 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1758276693; cv=none; d=zohomail.com; s=zohoarc; b=FSsls+wymrgz9s+Ns1y4tMuuqLkUZifw/PE9xxY94EDjsEPNcZHtZaQTlFtgrcIFpE7XeOAefHmcd4yhPVNkJXLv1Zlx1o+UCNeF+ozod8H9MRfH7pkbWRE1zKBYictFA5pXY2Fut0Dv+PBAothKRPifjYO7FhyylpxguUuD1Xs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758276693; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=m9nlTIL7ZY2QP2JpaM3AjUsx9DJ5uQxWhvcKzd0L4ZE=; b=aCqDQQQwK2b9BEB+Ya/XrBPQVHr5dzf8Qg2Ra1LDziS1QS1hM60nkbi4OzHCHgc2GiDRiqQxkEce657HHPiUXKymMn1ZDvLLA0oWes+DyUul+KGN4P7VwRJnedLcHRfO+abYN+pDwWj9dDuv06DZIuRa+Mo4scFRpumNXn8S+nw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1758276693846992.0676339739244; Fri, 19 Sep 2025 03:11:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uzY4m-0002kT-Ik; Fri, 19 Sep 2025 06:10:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4k-0002jD-Ix for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:46 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4c-0007St-TN for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:46 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-608-OCCRD-d2N-2LTgQfTIZ_nw-1; Fri, 19 Sep 2025 06:10:34 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id ED6E318002C8 for ; Fri, 19 Sep 2025 10:10:32 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E52CC1800446; Fri, 19 Sep 2025 10:10:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758276636; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=m9nlTIL7ZY2QP2JpaM3AjUsx9DJ5uQxWhvcKzd0L4ZE=; b=E9mkJwexw/kDd3iXKW7oR7SOrKxwcpOF80uU9oVw6eWVV9JLPGTJAO3esv5VUikx26DQlp 1OoZhqnXOk2lPokRvKo7u8QN8piHnh0uNLzCwJZ2lMGYSzufFjs4EFAGbq06TGtHIlHAbM 5wkQrHHmqCafB5MG0BJdIZ+3zQ4tiMo= X-MC-Unique: OCCRD-d2N-2LTgQfTIZ_nw-1 X-Mimecast-MFC-AGG-ID: OCCRD-d2N-2LTgQfTIZ_nw_1758276633 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 5/6] crypto: switch to newer gnutls API for distinguished name Date: Fri, 19 Sep 2025 11:10:21 +0100 Message-ID: <20250919101022.1491007-6-berrange@redhat.com> In-Reply-To: <20250919101022.1491007-1-berrange@redhat.com> References: <20250919101022.1491007-1-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.005, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1758276696342116600 The new API automatically allocates the right amount of memory to hold the distinguished name, avoiding the need to loop and realloc. Signed-off-by: Daniel P. Berrang=C3=A9 --- crypto/tlssession.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/crypto/tlssession.c b/crypto/tlssession.c index 86d407a142..0f86d1393f 100644 --- a/crypto/tlssession.c +++ b/crypto/tlssession.c @@ -409,20 +409,14 @@ qcrypto_tls_session_check_certificate(QCryptoTLSSessi= on *session, } =20 if (i =3D=3D 0) { - size_t dnameSize =3D 1024; - session->peername =3D g_malloc(dnameSize); - requery: - ret =3D gnutls_x509_crt_get_dn(cert, session->peername, &dname= Size); + gnutls_datum_t dname =3D {}; + ret =3D gnutls_x509_crt_get_dn2(cert, &dname); if (ret < 0) { - if (ret =3D=3D GNUTLS_E_SHORT_MEMORY_BUFFER) { - session->peername =3D g_realloc(session->peername, - dnameSize); - goto requery; - } error_setg(errp, "Cannot get client distinguished name: %s= ", gnutls_strerror(ret)); goto error; } + session->peername =3D (char *)g_steal_pointer(&dname.data); if (session->authzid) { bool allow; =20 --=20 2.50.1 From nobody Sun Sep 28 15:29:08 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1758276694; cv=none; d=zohomail.com; s=zohoarc; b=LFSCwEJIbDaA3+Ps1BEUxzaZHuFmKqPCUXVjXTkF9bCx3d7pH8fUvl+riEJkhH6mdca2l2+Xt8k69tu59gk6GqsS7/gB3G/aubGB3F0oQTtmN+COs5z3xyblo7omKRDb81UID96u7gvzKZCx3HT3xTY9YIpIokbsUAS4mLmw3CA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758276694; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=6TYnewD+Ae6Ha9XOvEPIoLVaogylhT50k3PXovWEMZA=; b=DHtkbsEafPMOL2VJAfodxotf+cgsaREvp8cqSJ1zQPkYBqwue7RpMAga+dYjQlTgdk1R6/7Gc6ziEK3KoZoFnpFejngTBn8YhhJbGAlZW2+R9xBZMvTGOBovnlNVFgfx005h8z58PGDpIne42++HJbs6LW4Qh7cCeLjvA0IOrWo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1758276694810786.3199926374467; Fri, 19 Sep 2025 03:11:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uzY4l-0002jv-6F; Fri, 19 Sep 2025 06:10:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4j-0002ir-RU for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:45 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uzY4c-0007Sy-BV for qemu-devel@nongnu.org; Fri, 19 Sep 2025 06:10:45 -0400 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-357-HQrxCn2RNMugJBEvIJGqEA-1; Fri, 19 Sep 2025 06:10:35 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4A56519560B5 for ; Fri, 19 Sep 2025 10:10:34 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5D8B318004A3; Fri, 19 Sep 2025 10:10:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758276636; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6TYnewD+Ae6Ha9XOvEPIoLVaogylhT50k3PXovWEMZA=; b=YTeWpg1gP2cbGqogIl0wCgTZDxZ38JG5OGNP9W93y/abeUK9LAJxsRk7gVEiXW9O/uSEZR CuU6l2U1qpKmDxOp4WvayVXDQEKgdHz36Y3QL5iD7tBSQFpktdTdyJna6+YE2TjRrCX9BV FSZdWjce/c4C9YN/S+8vvl80IGqTW+c= X-MC-Unique: HQrxCn2RNMugJBEvIJGqEA-1 X-Mimecast-MFC-AGG-ID: HQrxCn2RNMugJBEvIJGqEA_1758276634 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 6/6] crypto: fix error reporting in cert chain checks Date: Fri, 19 Sep 2025 11:10:22 +0100 Message-ID: <20250919101022.1491007-7-berrange@redhat.com> In-Reply-To: <20250919101022.1491007-1-berrange@redhat.com> References: <20250919101022.1491007-1-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.005, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1758276696370116600 The loop that checks the CA certificate chain can fail to report an error message if one of the certs in the chain has an issuer than is not present in the chain. In this case, the outer loop 'while (checking_issuer)' will terminate after failing to find the issuer, and no error message will be reported. Signed-off-by: Daniel P. Berrang=C3=A9 --- crypto/tlscredsx509.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c index 89a8e261d5..d42f2afaea 100644 --- a/crypto/tlscredsx509.c +++ b/crypto/tlscredsx509.c @@ -319,7 +319,6 @@ qcrypto_tls_creds_check_authority_chain(QCryptoTLSCreds= X509 *creds, Error **errp) { gnutls_x509_crt_t cert_to_check =3D certs[ncerts - 1]; - int checking_issuer =3D 1; int retval =3D 0; gnutls_datum_t dn =3D {}, dnissuer =3D {}; =20 @@ -346,8 +345,8 @@ qcrypto_tls_creds_check_authority_chain(QCryptoTLSCreds= X509 *creds, } } =20 - while (checking_issuer) { - checking_issuer =3D 0; + for (;;) { + gnutls_x509_crt_t cert_issuer =3D NULL; =20 if (gnutls_x509_crt_check_issuer(cert_to_check, cert_to_check)) { @@ -362,19 +361,30 @@ qcrypto_tls_creds_check_authority_chain(QCryptoTLSCre= dsX509 *creds, for (int i =3D 0; i < ncacerts; i++) { if (gnutls_x509_crt_check_issuer(cert_to_check, cacerts[i])) { - retval =3D qcrypto_tls_creds_check_cert( - creds, cacerts[i], cacertFile, - isServer, isCA, errp); - if (retval < 0) { - return retval; - } - cert_to_check =3D cacerts[i]; - checking_issuer =3D 1; + cert_issuer =3D cacerts[i]; break; } } + if (!cert_issuer) { + break; + } + + if (qcrypto_tls_creds_check_cert(creds, cert_issuer, cacertFile, + isServer, isCA, errp) < 0) { + return -1; + } + + cert_to_check =3D cert_issuer; } =20 + retval =3D gnutls_x509_crt_get_dn2(cert_to_check, &dn); + if (retval < 0) { + error_setg(errp, "Unable to fetch cert DN: %s", + gnutls_strerror(retval)); + return -1; + } + error_setg(errp, "Cert '%s' has no issuer in CA chain", dn.data); + gnutls_free(dn.data); return -1; } =20 --=20 2.50.1