How does CVE-2021-43527 impact certificate chains?

39 views
Skip to first unread message

Andrew Cagney

unread,
Dec 3, 2021, 11:40:51 AM12/3/21
to mozilla's crypto code discussion list
I'm trying to understand CVE-2021-43527 and how it impacts verifying
an untrusted end cert starting with a trusted root cert.

In the blog https://googleprojectzero.blogspot.com/2021/12/this-shouldnt-have-happened.html
the example uses a self signed certificate. This means we have:

vfy_CreateContext(key=untrusted, sig=untrusted)
sigLen = SECKEY_SignatureLen(key);
...
if (sig->len != sigLen) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);

i.e., both SECKEY_SignatureLen(key) and sig-len are coming from the
wire (untrusted source).

However, when calling this function via CERT_PKIXVerifyCert(), the
calls look more like:

vfy_CreateContext(key=trusted, sig=untrusted)

(trusted is either the root cert, or a previously authenticated
certificate) which would mean that the (sig->len != sigLen) does the
right thing?

Andrew Cagney

unread,
Dec 3, 2021, 11:41:04 AM12/3/21
to dev-tec...@mozilla.org
(hopefully the correct address)

Andrew Cagney

unread,
Dec 3, 2021, 12:50:13 PM12/3/21
to ry...@sleevi.com, dev-tec...@mozilla.org
Thanks! I'll need to build a chain with one good and two broken certs.

On Fri, 3 Dec 2021 at 11:55, Ryan Sleevi <ry...@sleevi.com> wrote:
>
> (Will probably forget to send from the right address myself and end up double posting 😅)
> Not quite.
>
> The calls aren’t exactly vfy_CreateContext(key=trusted, sig=untrusted). That’s because that approach only works if you’ve already constructed the entire path to a trust anchor, which hasn’t really been a thing since The Directory (X.500) failed in the 80s/early 90s.
>
> Instead, you work from the leaf cert (untrusted), doing a depth first search of certificates, trying to see if you can build a chain that terminates in a trust anchor. As a consequence, you’re doing vfy_CreateContext(key=maybe-trusted-maybe-not, sig=untrusted).
>
> That’s what the logic at
> https://searchfox.org/mozilla-central/source/security/nss/lib/certhigh/certvfy.c#740-750 is doing - CERT_FindCertIssuer will return the first available issuer, which be untrusted and sent by the peer (i.e. via TLS), might be untrusted and sent by another peer (e.g. in the NSS memory cache of certificates), might be untrusted from the local DB, or might be trusted. The design of the code itself is assuming the issuer is untrusted, since (except for the trust anchor), all the issuers in the path are.
>
> You can read more about such approaches at
> https://medium.com/@sleevi_/path-building-vs-path-verifying-the-chain-of-pain-9fbab861d7d6 and RFC 4158. Legacy NSS (i.e. not LibPkix or mozilla::pkix) performs a simple depth-first search with no backtracking. However, despite differences in their path building approach, both Legacy NSS and LibPkix are affected by this.
>
> I’m not presently aware of any implementations in wide use that verify from trusted->untrusted (i.e. “root first”). That approach was more for X.500 where The Directory provided “the” cert chain. As used by TLS and the PKIs in practice, you generally start leaf first (most ignoring the order of other certs sent in the TLS handshake, a widespread practice recognized by TLS 1.3), and then continue building untrusted until you find trusted.
Reply all
Reply to author
Forward
0 new messages