jsign icon indicating copy to clipboard operation
jsign copied to clipboard

MSCabinet file is corrupt: cabinet reserved area size is 6144 instead of 20- NoRetry

Open johm6340 opened this issue 1 year ago • 5 comments

Good morning .

I have a fair few of these old cabs that contain a reserved section of 6144 bytes. I believe they were created with a ddf containing set reservepercabinetsize=6144. Looking at the cab signing class , there seems to be code to handle a fixed size of 20 , but nothing more general . The reserved bytes could be any value . Is this an oversight / bug , or expected behaviour . I looked at the cab documentation and could not find anything describing specific reserve sizes . I tried working around this by allowing 6144 as well as 20 , but something deeper gets messed up . Any ideas how this can be resolved in the library ?

To duplicate, create a simple cab with makecab and a ddf containing set reservepercabinetsize=6144 .

Many thanks

John

johm6340 avatar Aug 29 '23 09:08 johm6340

Thank you for reporting this issue

Is this an oversight / bug , or expected behaviour

Jsign assumes the reserved area is either empty or contains a 20 bytes signature structure. If there is something else in the reserved area, signing the file will erase it.

The question is, how does signtool handle such a file? Is the 6K reserved area ignored and replaced by a 20 bytes signature? Is the 6K reserved area preserved but overwritten on the first 20 bytes ? Or does it trigger an error?

ebourg avatar Aug 29 '23 22:08 ebourg

Hi , Thanks for the reply Signtool doesnt seem to care . It will sign the cab with no issues . Jsign just stops and won't tolerate any other reserved size besides 20 bytes . The 6K reserved area seems to have been a practice introduced in the days of cabarc, when perhaps signtool needed the space to put signatures .

johm6340 avatar Aug 30 '23 08:08 johm6340

The question is, how does signtool handle such a file?

It looks like signtool replaces the empty reserved area with the CABSignature structure and appends the PKCS#7 signature at the end of the file. If the reserved area is not empty, different things may happen:

  • if the reserved area contains a CABSignature structure (20 bytes starting with the 00 00 10 00 sequence), the signature is replaced
  • if the reserved area isn't exactly a CABSignature structure, the first two bytes are interpreted as a size of an undefined structure
    • if it's greater than the size of the reserved area minus 2, an error is thrown
    • if it's lower, a CABSignature structure is written in the reserved area after the undefined structure, but only the last 16 bytes containing the offset and the length of the signature. The bytes 10 00 are written in the 3rd and 4th position of the reserved area, after the size of the unknown structure. The reserved area is extended, but the size of the reserved area defined in the header is not updated.

It seems that the bytes of the reserved area are interpreted as follow:

  • size of the first structure (2 bytes)
  • size of the second structure (2 bytes)
  • first structure (variable length)
  • second structure (variable length)

ebourg avatar Sep 02 '23 11:09 ebourg

Good sleuthing :-) . Any ETA on a fix ?

johm6340 avatar Sep 04 '23 09:09 johm6340

I don't have an ETA sorry. I've discovered another problem related to the per folder reserved area (using the ReservePerFolderSize directive);

  • if the file has a per cabinet and a per folder reserved area, the signature is invalid
  • if the file has a per folder reserved area but no per cabinet reserved area, an exception is thrown

ebourg avatar Sep 05 '23 09:09 ebourg

The issue with the per folder reserved area has been fixed in the version 6.0 (2a7a5c89e941c519ffed8fcc8d6c350909bb29d5)

ebourg avatar Jun 19 '24 10:06 ebourg

@johm6340 the reserve is now fully supported. If a cabinet contains a PKCS#7 signature in the reserve it's automatically moved to the end of file when a new signature is added.

The pre-allocated space in the reserve is only used to store the small 16 bytes structure that points to the location of the PKCS#7 block at the end of the file. Jsign doesn't attempt to place the block in the reserve.

The optimal value for the ReservePerCabinetSize parameter when creating a cabinet file is 20, This allows the CABSignature structure to be written without moving the data after the header, and no space will be wasted.

ebourg avatar Jun 21 '24 10:06 ebourg