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
> (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
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
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.