@@ -166,6 +166,38 @@ contract CertManagerTest is Test {
166166 cm.verifyCACertWithHints (rootTwin, rootHash, hints);
167167 }
168168
169+ function test_VerifyCACertWithHints_RejectsSignatureWrapperTagSubstitution () public {
170+ vm.warp (1775145600 );
171+ CertManager cm = new CertManager (new P384Verifier ());
172+ P384HintCollector collector = new P384HintCollector ();
173+
174+ bytes32 rootHash = keccak256 (CB0);
175+ bytes memory parentPubKey = cm.loadVerified (rootHash).pubKey;
176+ bytes memory hints = collector.collectCertSignatureHints (CB1, parentPubKey);
177+
178+ bytes memory mutated = bytes .concat (CB1);
179+ (,, Asn1Ptr sigRoot ,) = _certSignaturePtrs (mutated);
180+ mutated[sigRoot.header ()] = 0x31 ; // constructed SET with the same r/s children.
181+
182+ vm.expectRevert ("invalid cert signature " );
183+ cm.verifyCACertWithHints (mutated, rootHash, hints);
184+ }
185+
186+ function test_VerifyCACertWithHints_RejectsTrailingSignatureFields () public {
187+ vm.warp (1775145600 );
188+ CertManager cm = new CertManager (new P384Verifier ());
189+ P384HintCollector collector = new P384HintCollector ();
190+
191+ bytes32 rootHash = keccak256 (CB0);
192+ bytes memory parentPubKey = cm.loadVerified (rootHash).pubKey;
193+ bytes memory hints = collector.collectCertSignatureHints (CB1, parentPubKey);
194+
195+ bytes memory mutated = _appendSignatureTrailingField (CB1);
196+
197+ vm.expectRevert ("invalid cert signature " );
198+ cm.verifyCACertWithHints (mutated, rootHash, hints);
199+ }
200+
169201 function _verifyCA (CertManager cm , P384HintCollector collector , bytes memory cert , bytes32 parentHash )
170202 internal
171203 returns (bytes32 )
@@ -212,6 +244,34 @@ contract CertManagerTest is Test {
212244 _writeDerLength (result, sigRoot, _addDelta (sigRoot.length (), delta));
213245 }
214246
247+ function _appendSignatureTrailingField (bytes memory certificate ) internal pure returns (bytes memory result ) {
248+ (Asn1Ptr root , Asn1Ptr sigPtr , Asn1Ptr sigRoot ,) = _certSignaturePtrs (certificate);
249+ bytes memory extraInteger = hex "020100 " ;
250+ int256 delta = int256 (extraInteger.length );
251+ result = _insertBytes (certificate, sigRoot.content () + sigRoot.length (), extraInteger);
252+
253+ _writeDerLength (result, root, _addDelta (root.length (), delta));
254+ _writeDerLength (result, sigPtr, _addDelta (sigPtr.length (), delta));
255+ _writeDerLength (result, sigRoot, _addDelta (sigRoot.length (), delta));
256+ }
257+
258+ function _insertBytes (bytes memory input , uint256 offset , bytes memory inserted )
259+ internal
260+ pure
261+ returns (bytes memory result )
262+ {
263+ result = new bytes (input.length + inserted.length );
264+ for (uint256 i = 0 ; i < offset; ++ i) {
265+ result[i] = input[i];
266+ }
267+ for (uint256 i = 0 ; i < inserted.length ; ++ i) {
268+ result[offset + i] = inserted[i];
269+ }
270+ for (uint256 i = offset; i < input.length ; ++ i) {
271+ result[i + inserted.length ] = input[i];
272+ }
273+ }
274+
215275 function _certSignaturePtrs (bytes memory certificate )
216276 internal
217277 pure
0 commit comments