Add opt-in X.509 cross-consistency checks (EKU chaining, RSA-PSS key params, critical BasicConstraints)#22
Open
Frauschi wants to merge 1 commit into
Open
Conversation
…params, critical BasicConstraints) Follow-up to the algorithm-confusion hardening in wolfSSL#10131 (SigOidMatchesKeyOid). An audit of X.509 parsing/validation found three further "logically related fields that should agree but are not cross-checked" gaps. Each fix is gated behind a new, default-off macro so existing builds are byte-for-byte unchanged (the full testsuite passes with the macros off). WOLFSSL_CHECK_EKU_CHAIN (B1): The issuing CA's extendedKeyUsage did not constrain the certs it issued (only the leaf's EKU was checked, at TLS time). Propagate the CA's effective EKU onto its Signer in FillSigner and, during chain verification, reject a certificate that asserts an EKU not permitted by the issuing CA. An absent CA EKU or anyExtendedKeyUsage imposes no restriction. WOLFSSL_CHECK_RSAPSS_KEY_PARAMS (B2): An id-RSASSA-PSS issuer key's restricting parameters (RFC 4055) were parsed and then discarded (the long-standing "TODO: store parameters so that usage can be checked" in DecodeRsaPublicKey). Capture the SPKI PSS parameters on the DecodedCert/Signer and require a signature made by that key to use the mandated hash/MGF/salt. WOLFSSL_REQUIRE_CRITICAL_BASIC_CONSTRAINTS (B7): RFC 5280 4.2.1.9 requires CA certificates to mark basicConstraints critical; wolfSSL stored the critical bit but never required it. Reject an intermediate CA whose basicConstraints is not critical. Self-signed trust anchors are exempt, as their own extensions are not processed during path validation. All three are validated with dedicated proof-of-concept programs and EKU positive/negative controls; B1+B2 pass the standard testsuite, and B7's rejections are limited to non-conforming (non-critical-BC) intermediates. https://claude.ai/code/session_01NSH5QDCbE9n1hKYQUYbKQA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
Follow-up to the algorithm-confusion hardening in wolfSSL#10131 (
SigOidMatchesKeyOid,which makes a certificate's signature-algorithm OID agree with the issuer key's
OID). An audit of the rest of wolfSSL's X.509 parsing/validation looked for the
same class of issue — logically related fields/extensions that should agree
or constrain each other but are not cross-checked — and surfaced three further
gaps. This PR drafts fixes for them.
Each fix is gated behind a new, default-off macro, so existing builds are
byte-for-byte unchanged. The full
testsuite.testpasses with the macros off,and also passes with B1+B2 on.
Changes
Files:
wolfcrypt/src/asn.c(+106),wolfssl/wolfcrypt/asn.h(+21).WOLFSSL_CHECK_EKU_CHAIN(B1)The issuing CA's
extendedKeyUsagedid not constrain the certs it issued — onlythe leaf's EKU was checked, at TLS time. The CA's effective EKU is now propagated
onto its
SignerinFillSigner, and during chain verification a certificatethat asserts an EKU not permitted by the issuing CA is rejected
(
EXTKEYUSAGE_E). An absent CA EKU oranyExtendedKeyUsageimposes norestriction; the restriction propagates transitively down the path.
WOLFSSL_CHECK_RSAPSS_KEY_PARAMS(B2)An
id-RSASSA-PSSissuer key's restricting parameters (RFC 4055) were parsed andthen discarded — the long-standing
TODO: store parameters so that usage can be checkedinDecodeRsaPublicKey. The SPKI PSS parameters are now captured onthe
DecodedCert/Signer, and a signature made by that key is required to usethe mandated hash/MGF/salt (
ASN_SIG_OID_Eon mismatch).WOLFSSL_REQUIRE_CRITICAL_BASIC_CONSTRAINTS(B7)RFC 5280 §4.2.1.9 requires CA certificates to mark
basicConstraintscritical;wolfSSL stored the critical bit but never required it. An intermediate CA
whose
basicConstraintsis not critical is now rejected (ASN_CRIT_EXT_E).Self-signed trust anchors are exempt, since their own extensions are not
processed during RFC 5280 §6.1 path validation.
Validation
testsuite.testpasses — zerobehavioral change for existing users.
OCSPSigning-only CA issuing aserverAuthleaf now fails verification (
-247); positive/negative EKU subset controlsbehave correctly;
testsuite.testpasses with B1 on.testsuite.testpasses (normal RSA-PSS certs use anrsaEncryptionSPKI, so the check is skipped). A runtime PoC is not feasiblewith the bundled certgen, which cannot emit a parameter-constrained
id-RSASSA-PSSSPKI; the gap and fix are unambiguous from source.basicConstraintsnow fails verification (-160), self-signed roots stillload.
Notes / discussion points
non-conforming-but-common certificates, which is why they are opt-in. In
particular, B7 is strict: with it enabled, wolfSSL's own intentionally
lenient (non-critical-BC) test intermediates are rejected, so the bundled
testsuite is expected to surface rejections when B7 is on.
than a hard parse rejection — happy to adjust.
inner/outer AlgorithmIdentifier parameters, serial-number positivity/length)
were left out of this PR and can be added if wanted.
https://claude.ai/code/session_01NSH5QDCbE9n1hKYQUYbKQA
Generated by Claude Code