@@ -1001,4 +1001,77 @@ contract NitroValidatorIndefiniteLengthTest is Test {
10011001 assertEq (p.cabundle.length , 0 , "cabundle empty " );
10021002 assertEq (p.digest.length (), SYNTH_DIGEST_LEN, "digest after empty cabundle parsed " );
10031003 }
1004+
1005+ // ── Composite definite/indefinite encodings (BLOCKSEC-5249 I-03) ──
1006+ //
1007+ // The audit noted there were no tests mixing definite- and indefinite-length encodings across
1008+ // the outer payload map and the nested `pcrs` map / `cabundle` array. These exercise that matrix:
1009+ // the same logical attestation is encoded with every combination of outer-map / pcrs-map /
1010+ // cabundle-array length forms, and must parse to identical field pointers each time.
1011+
1012+ /// @dev Builds the standard 9-entry synthetic attestation body, independently selecting the
1013+ /// length form of the nested `pcrs` map and `cabundle` array while keeping their logical
1014+ /// content identical to `_entries()` (1 PCR of 48B, 1 cabundle cert of 4B).
1015+ function _compositeEntries (bool indefinitePcrs , bool indefiniteCabundle ) internal pure returns (bytes memory ) {
1016+ bytes memory head = abi.encodePacked (
1017+ hex "696d6f64756c655f6964 " , // module_id
1018+ hex "6474657374 " ,
1019+ hex "66646967657374 " , // digest
1020+ hex "66534841333834 " ,
1021+ hex "6974696d657374616d70 " , // timestamp
1022+ hex "1a000f4240 "
1023+ );
1024+ bytes memory pcrs = indefinitePcrs
1025+ ? abi.encodePacked (hex "6470637273 " , CBOR_MAP_INDEFINITE, hex "005830 " , new bytes (SYNTH_PCR_LEN), CBOR_BREAK)
1026+ : abi.encodePacked (hex "6470637273 " , hex "a1005830 " , new bytes (SYNTH_PCR_LEN));
1027+ bytes memory cert = abi.encodePacked (hex "6b6365727469666963617465 " , hex "4400000000 " );
1028+ bytes memory cabundle = indefiniteCabundle
1029+ ? abi.encodePacked (hex "68636162756e646c65 " , CBOR_ARRAY_INDEFINITE, hex "4400000000 " , CBOR_BREAK)
1030+ : abi.encodePacked (hex "68636162756e646c65 " , hex "814400000000 " );
1031+ bytes memory tail = abi.encodePacked (
1032+ hex "6a7075626c69635f6b6579 " , // public_key
1033+ hex "f6 " ,
1034+ hex "69757365725f64617461 " , // user_data
1035+ hex "f6 " ,
1036+ hex "656e6f6e6365 " , // nonce
1037+ hex "f6 "
1038+ );
1039+ return abi.encodePacked (head, pcrs, cert, cabundle, tail);
1040+ }
1041+
1042+ function _compositeTbs (bool indefiniteOuter , bool indefinitePcrs , bool indefiniteCabundle )
1043+ internal
1044+ pure
1045+ returns (bytes memory )
1046+ {
1047+ bytes memory entries = _compositeEntries (indefinitePcrs, indefiniteCabundle);
1048+ if (indefiniteOuter) {
1049+ return _buildTbs (abi.encodePacked (CBOR_MAP_INDEFINITE, entries, CBOR_BREAK));
1050+ }
1051+ return _buildTbs (abi.encodePacked (hex "a9 " , entries)); // 0xA9 = definite 9-entry map
1052+ }
1053+
1054+ function test_composite_definiteOuter_indefinitePcrs_definiteCabundle () public view {
1055+ _assertSyntheticFields (validator.parseAttestation (_compositeTbs (false , true , false )));
1056+ }
1057+
1058+ function test_composite_definiteOuter_definitePcrs_indefiniteCabundle () public view {
1059+ _assertSyntheticFields (validator.parseAttestation (_compositeTbs (false , false , true )));
1060+ }
1061+
1062+ function test_composite_definiteOuter_indefinitePcrs_indefiniteCabundle () public view {
1063+ _assertSyntheticFields (validator.parseAttestation (_compositeTbs (false , true , true )));
1064+ }
1065+
1066+ function test_composite_indefiniteOuter_indefinitePcrs_definiteCabundle () public view {
1067+ _assertSyntheticFields (validator.parseAttestation (_compositeTbs (true , true , false )));
1068+ }
1069+
1070+ function test_composite_indefiniteOuter_definitePcrs_indefiniteCabundle () public view {
1071+ _assertSyntheticFields (validator.parseAttestation (_compositeTbs (true , false , true )));
1072+ }
1073+
1074+ function test_composite_indefiniteOuter_indefinitePcrs_indefiniteCabundle () public view {
1075+ _assertSyntheticFields (validator.parseAttestation (_compositeTbs (true , true , true )));
1076+ }
10041077}
0 commit comments