From patchwork Wed Feb 7 01:10:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10204385 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 13E7C6037E for ; Wed, 7 Feb 2018 01:16:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 063A828D8B for ; Wed, 7 Feb 2018 01:16:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EEEE828D98; Wed, 7 Feb 2018 01:15:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 831F928D8B for ; Wed, 7 Feb 2018 01:15:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932230AbeBGBP6 (ORCPT ); Tue, 6 Feb 2018 20:15:58 -0500 Received: from mail-io0-f193.google.com ([209.85.223.193]:39447 "EHLO mail-io0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932154AbeBGBP5 (ORCPT ); Tue, 6 Feb 2018 20:15:57 -0500 Received: by mail-io0-f193.google.com with SMTP id b198so183794iof.6; Tue, 06 Feb 2018 17:15:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=aFpcz6AFsbm4s6XRX2j3VxiA9yHbQQgTUUyN9kwQe7k=; b=JwQPm5L0xXMrcTo1GZvP6ywHO3Vk0GeUmn73AAhre7okDKKQxyOVZZBhoya25F1UL2 xhQuECPMIh3GvyArxVqLQ5b3sOIfZiOtTtPpEpgBwqf6PAvwHRj+KLCC+8cSGiDjR99k cXwwROGhqXfHL9QeIbwrTmTvHCWdzd5/J5zFMniX3/RSQRyRq/m5gq+vQeZVvVyNm+8P 5oM+zlSsYJC1tXpXzQCOc0u3WCJ4csJ4GMo2X0jBbIuYvriPQSLC9O52k4zoaDrNINvV hWpQxpWgSSrWZXLBay9Lvp4TIwzcykkfwiyBNXGB5vJ1egiK3sAm6wUUghSo/2ecy4gg CTwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=aFpcz6AFsbm4s6XRX2j3VxiA9yHbQQgTUUyN9kwQe7k=; b=JST4ESJvUdq54aea72rb8LCnkSHjnX365fACi4w4PSA8fWiw+hxMXEVa+ZA3NZ6o8C gKaVT/pra0ij9eUYstZqnxXdPHCdTy8DS97O4RpoU96fnzFpNzTPRnMjSgC1SWkmixTn rXPdinm+SqUK471K+n5ubnMtb/4ytqrcyIUKM9owPvfP6/vXTX7TiNdJkEbXWOEAV95Y ntop3sm5AXofUB++Pez4SW7RIo7M6bkiW0HyK6Lct9D9x5no70p7keUGvUJozWVVb0zF KJhZuT3AM7vGrHXMzwvCBhKNmuI2wo+zgTeYtT+FanyQ5O0+hSGnhAEOojnmJyA89ZT6 +/ww== X-Gm-Message-State: APf1xPCRn30seFbNzzdG27JTQSuihl1spGGNj/rZotY0wdI+PDCJKuWX /h0R3ghJfqjpLlOHZpNHaJPuumex X-Google-Smtp-Source: AH8x226ooS1dSqHbwxR9FSvJXVZA0e1QB7xMXbbYWtjXXpxa7zsZB9U14twlx2TG1ACvtHtdwOZdrw== X-Received: by 10.107.50.210 with SMTP id y201mr5342994ioy.224.1517966156546; Tue, 06 Feb 2018 17:15:56 -0800 (PST) Received: from ebiggers-linuxstation.kir.corp.google.com ([2620:15c:17:3:dc28:5c82:b905:e8a8]) by smtp.gmail.com with ESMTPSA id c9sm186364iod.5.2018.02.06.17.15.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 17:15:56 -0800 (PST) From: Eric Biggers To: David Howells , keyrings@vger.kernel.org Cc: linux-crypto@vger.kernel.org, Michael Halcrow , Eric Biggers , stable@vger.kernel.org Subject: [PATCH 1/9] PKCS#7: fix certificate chain verification Date: Tue, 6 Feb 2018 17:10:04 -0800 Message-Id: <20180207011012.5928-2-ebiggers3@gmail.com> X-Mailer: git-send-email 2.16.0.rc1.238.g530d649a79-goog In-Reply-To: <20180207011012.5928-1-ebiggers3@gmail.com> References: <20180207011012.5928-1-ebiggers3@gmail.com> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers When pkcs7_verify_sig_chain() is building the certificate chain for a SignerInfo using the certificates in the PKCS#7 message, it is passing the wrong arguments to public_key_verify_signature(). Consequently, when the next certificate is supposed to be used to verify the previous certificate, the next certificate is actually used to verify itself. An attacker can use this bug to create a bogus certificate chain that has no cryptographic relationship between the beginning and end. Fortunately I couldn't quite find a way to use this to bypass the overall signature verification, though it comes very close. Here's the reasoning: due to the bug, every certificate in the chain beyond the first actually has to be self-signed (where "self-signed" here refers to the actual key and signature; an attacker might still manipulate the certificate fields such that the self_signed flag doesn't actually get set, and thus the chain doesn't end immediately). But to pass trust validation (pkcs7_validate_trust()), either the SignerInfo or one of the certificates has to actually be signed by a trusted key. Since only self-signed certificates can be added to the chain, the only way for an attacker to introduce a trusted signature is to include a self-signed trusted certificate. But, when pkcs7_validate_trust_one() reaches that certificate, instead of trying to verify the signature on that certificate, it will actually look up the corresponding trusted key, which will succeed, and then try to verify the *previous* certificate, which will fail. Thus, disaster is narrowly averted (as far as I could tell). Fixes: 6c2dc5ae4ab7 ("X.509: Extract signature digest and make self-signed cert checks earlier") Cc: # v4.7+ Signed-off-by: Eric Biggers --- crypto/asymmetric_keys/pkcs7_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c index 39e6de0c2761..2f6a768b91d7 100644 --- a/crypto/asymmetric_keys/pkcs7_verify.c +++ b/crypto/asymmetric_keys/pkcs7_verify.c @@ -270,7 +270,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, sinfo->index); return 0; } - ret = public_key_verify_signature(p->pub, p->sig); + ret = public_key_verify_signature(p->pub, x509->sig); if (ret < 0) return ret; x509->signer = p;