CVSROOT:        /cvs
Module name:    src
Changes by:     [email protected]    2026/09/15 17:51:49

Modified files:
        lib/libcrypto/x509: x509_addr.c x509_asid.c 

Log message:
RFC 3779: fix inheritance for leaves

It's been publicly known at least since Frank Denis's "security audit"
dumps back in May that the RFC 3779 inheritance handling in libcrypto's
path validation is broken. Namely, if the certificate to be validated
inherits resources, X509v3_asid_validate_path(3) and friends can succeed
even if one of the certs on the path does not have the corresponding
resource delegation extension at all. RFC 3779's sections 2.3 and 3.3
clearly require that every cert on the entire validating path have the
relevant INR delegation extensions. Frank Denis flagged this for ASIDs,
but it is obvious that IP addresses have the same problem.

For rpki-client, one of the very few (the only?) consumers of this code
in libcrypto, this doesn't matter all that much because it duplicates
much of the work on INR validation. Per the specification, EE certs with
inherit elements are only in MFTs, TAKs (of which there are none) and
the no longer supported GBRs (of which there is one - malformed).
Correct nesting and presence of RFC 3779 extensions is ensured by
rpki-client (until recently inheriting leaves were skipped due to a
similar bug).

RFC 9286, section 5.1, says this for manifest EE certs:

This EE certificate MUST describe its Internet Number Resources
(INRs) using the "inherit" attribute, rather than an explicit
description of a resource set (see [RFC3779]).  (RPs are required
to verify this.)

which is the exact wording of RFC 6486 up to the last parenthesis. This
does not explicitly say both resource extensions must be present. It
could probably have been a bit more explicit that it is not required
and indeed not possible if the issuing CA misses one of the two
resources. Perhaps the following mistake would have been avoided.

About 1/3 (~16k) of all manifest EE certs have both RFC 3779 extensions
(with inherit element) despite the fact that their issuing certificate
lacks one of the two. Blindly fixing this to be strictly RFC 3779
compliant is therefore quite devastating for the RPKI: about 130,000
validated ROA payloads (out of roughly one million) would disappear as
well as about 600 validated ASPA payloads (out of ~3,000).

The fix below is very ugly. Due to inconsistencies between asid and addr
the logic is quite different-looking (but equivalent): allow inheritance
for leaves that are also EE certs even if the direct issuer misses the
relevant resource extension. The exception carved out for EE certs works
for the X509v3_{addr,asid}_validate_path() APIs also used in the
verifier, but it does not apply to the resource set validation API
(because we can't recognize the EE cert situation). That's annoying, but
we're dealing with both, broken APIs and a broken ecosystem.

The use of X509_check_ca() (also ugly) is justified by the fact that
resource certificates have stringent rules on extensions (RFC 6487).
An EE cert has exactly the digitalSignature bit set in its keyUsage, so
X509_check_ca() returns 0 due to the ku_reject() bit checking for
keyCertSign, while for CA certs it returns 1 because the keyCertSign bit
is set and the Basic Constraints must be present with cA bit set to
true. These things are checked by rpki-client before it calls
X509_verify_cert(). Extensions are cached with a X509_check_purpose()
call by rpki-client before doing anything with a cert.

Furthermore, as mentioned already, only MFTs are really relevant to this
discussion. If an MFT references ROAs, the latter all contain an EE cert
with explicit IP resources and no AS resources, so to validate that, the
issuing CA must have IP resources. Similarly, if an MFT references any
ASPAs, the latter must all contain an EE cert with explicit AS resources
and no IP resources, so to validate those, the issuing CA must have AS
resources. The impact of this bug and the workaround are therefore quite
minimal.

ok beck kenjiro

Reply via email to