@@ -30,6 +30,10 @@ contract CertManagerHarness is CertManager {
3030 function verifyBasicConstraints (bytes memory der , bool ca ) external pure returns (int64 ) {
3131 return _verifyBasicConstraintsExtension (der, der.root (), ca);
3232 }
33+
34+ function verifyExtensions (bytes memory der , bool ca ) external pure returns (int64 ) {
35+ return _verifyExtensions (der, der.root (), ca);
36+ }
3337}
3438
3539contract CertManagerTest is Test {
@@ -95,6 +99,25 @@ contract CertManagerTest is Test {
9599 certManagerHarness.verifyBasicConstraints (hex "30020400 " , false );
96100 }
97101
102+ function test_VerifyExtensionsAllowsUnknownNonCriticalExtension () public view {
103+ bytes memory unknownNameConstraints = hex "30090603551d1e04023000 " ;
104+
105+ assertEq (int256 (certManagerHarness.verifyExtensions (_clientExtensionsWith (unknownNameConstraints), false )), - 1 );
106+ }
107+
108+ function test_VerifyExtensionsAllowsUnknownCriticalFalseExtension () public view {
109+ bytes memory unknownNameConstraints = hex "300c0603551d1e01010004023000 " ;
110+
111+ assertEq (int256 (certManagerHarness.verifyExtensions (_clientExtensionsWith (unknownNameConstraints), false )), - 1 );
112+ }
113+
114+ function test_VerifyExtensionsRejectsUnknownCriticalExtension () public {
115+ bytes memory unknownNameConstraints = hex "300c0603551d1e0101ff04023000 " ;
116+
117+ vm.expectRevert ("unsupported critical extension " );
118+ certManagerHarness.verifyExtensions (_clientExtensionsWith (unknownNameConstraints), false );
119+ }
120+
98121 // Cert chain from the 2026-04-02 ~15:35 UTC dev attestation that produced the live revert.
99122 // CB0 is the AWS Nitro root (keccak256(CB0) == CertManager.ROOT_CA_CERT_HASH, pinned in the
100123 // constructor), so the chain is verified starting from CB1.
@@ -345,6 +368,16 @@ contract CertManagerTest is Test {
345368
346369 return der;
347370 }
371+
372+ function _clientExtensionsWith (bytes memory extraExtension ) internal pure returns (bytes memory ) {
373+ bytes memory body =
374+ abi.encodePacked (hex "300c0603551d130101ff04023000 " , hex "300e0603551d0f0101ff040403020780 " , extraExtension);
375+
376+ return
377+ abi.encodePacked (
378+ bytes1 (0xa3 ), bytes1 (uint8 (body.length + 2 )), bytes1 (0x30 ), bytes1 (uint8 (body.length )), body
379+ );
380+ }
348381}
349382
350383/// @dev Exposes the internal revocation-chain walk and lets tests seed the `verifiedParent`
0 commit comments