ebourg / jsign

Java implementation of Microsoft Authenticode for signing Windows executables, installers & scripts
https://ebourg.github.io/jsign
Apache License 2.0
250 stars 107 forks source link

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

Closed johm6340 closed 1 week ago

johm6340 commented 10 months ago

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

ebourg commented 10 months ago

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?

johm6340 commented 10 months ago

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 .

ebourg commented 10 months ago

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:

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

johm6340 commented 9 months ago

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

ebourg commented 9 months ago

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

ebourg commented 1 week ago

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

ebourg commented 1 week ago

@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.