Repository navigation
fix(core): accept pathlen:0 on the issuing CA - #45
Merged
Merged
Conversation
verifyCertificateChain compared pathLenConstraint against the certificate's chain index, but the leaf does not count towards the limit (RFC 5280 4.2.1.9). An issuing CA at index 1 with pathlen:0 was therefore rejected as 'Certificate 1 basic constraints: path length constraint violated', even though pathlen:0 is the common way for a CA to allow only end-entity certificates. Compare against i - 1 instead. Genuine violations are still rejected. Fixtures: root -> issuing CA (pathlen:0) -> leaf; a four-cert chain at the boundary (root -> int1 pathlen:1 -> int2 pathlen:0 -> leaf); and a real violation (root pathlen:0 -> intermediate -> leaf). Verified against @didx509/core 0.1.2 (the new fixtures reproduce the report) and with the fix: 144/144 tests, typecheck, lint, build, npm pack. Fixes #44 Signed-off-by: Ajay Jadhav <ajay@ayanworks.com>
The path-length fix in the previous commit lets chains resolve that used to fail early, which exposed a masked divergence in the parity suite: `san:email:user@example.com` was accepted, while the specification and the C++ reference resolver reject it (reserved characters must be escaped). Add decodeScalar(), which enforces the reference resolver's grammar: only unreserved characters (A-Za-z0-9-._~) and %XX escapes, non-empty, and the decoded value must be valid UTF-8. Use it for subject, SAN, EKU and Fulcio-issuer predicate values instead of decodeURIComponent, which accepts raw reserved characters. Regenerate the parity report: 16 vectors move from 'unexpected-failure' to 'document-mismatch' (they now resolve; the remaining difference is the known JWK key_ops/ext divergence), and predicate-value-must-be-percent-encoded stops diverging. Total known divergences stay at 112, with no new risky entries. Verified: 149/149 tests, typecheck, lint, build; REQUIRE_CORE=true parity suite 222/222. Signed-off-by: Ajay Jadhav <ajay@ayanworks.com>
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.
Fixes #44.
Bug
verifyCertificateChaincomparedpathLenConstraintagainst the certificate's chain index:The leaf is at index 0 and does not count towards the limit (RFC 5280 §4.2.1.9), so an issuing CA at index 1 with
pathlen:0was always rejected:pathlen:0on the issuing CA is the normal way for a CA to say "I issue only end-entity certificates", so this rejected common real-world chains.Fix
An issuer at index
ihasi - 1intermediates below it. Genuine violations are still rejected.Tests
Three static fixtures in
typescript/shared-test-data/(P-256, 10-year validity), plustypescript/test/pathlen.test.ts:pathlen0-chain.pempathlen:0) → leafpathlen-boundary-chain.pempathlen:1) → int2 (pathlen:0) → leafpathlen-violation-chain.pempathlen:0) → intermediate → leafThe first two reproduce the reported error on
@didx509/core0.1.2 and pass with the fix.Second fix: predicate encoding
The native parity suite caught a masked divergence: with the chain no longer failing early,
…::san:email:user@example.comresolved even though the spec and the C++ reference require reserved characters to be percent-encoded.decodeScalar()now enforces the reference grammar (unreserved characters or%XX, valid UTF-8) for subject, SAN, EKU and Fulcio-issuer values. DIDs produced withpctEncodeare unaffected.npm run parity:reportwas regenerated: 16 vectors move fromunexpected-failuretodocument-mismatch(they now resolve; the rest is the known JWKkey_ops/extdivergence), the unencoded-predicate vector stops diverging, and the total stays at 112 known divergences with no new risky entries.Release
Bumps core to
0.1.3.@didx509/credodoes not need a release: the published 0.1.2 depends on^0.1.2, which matches0.1.3.Verification
tsc --noEmit, ESLint (no errors), 149/149 tests, tsup buildnpm pack --dry-run:didx509-core-0.1.3.tgz, 19 filesREQUIRE_CORE=truenative parity suite: 222/222