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

Hash of MSI files with embedded sub storages is wrong #149

Open Horcrux7 opened 1 year ago

Horcrux7 commented 1 year ago

I sign the file https://download.inetsoftware.de/cowork-server-latest.msi with jsign 4.2 with the follow command line:

java -jar jsign-4.2.jar --keystore keystore.pfx --storepass pwd -replace cowork-server-23.4.237.msi

If I verify this with:

signtool.exe verify /pa /v cowork-server-23.4.237.msi

Then it show Hash of file (sha256): 6E5891A83265A606DBE94F4A38A80FCA8D2688595C247948C10749B594A871B5 and the signature was not valid. If I sign it with:

signtool.exe sign /f keystore.pfx /p pwd /fd SHA256 cowork-server-23.4.237.msi

The the verify show Hash of file (sha256): EFA62C412C277D68AD11774E0D4F0894114CB72AB51A169DD8A940DF4FEC680A and the signature is valid.

It looks for me that the hash was calculated wrong. If I try this with smaller msi files then I get the same hash code with both tools. I have also try it with an unsigned msi file without the option -replace with the same result. But there is no download for such unsigned file.

Horcrux7 commented 1 year ago

I have look into the hashcode calculating and it look complex. Do you have any documentation that described how the hashcode is calculated?

ebourg commented 1 year ago

Thank you for reporting this issue, I have been able to reproduce it. It looks like the MSI entries aren't hashed in the right order, I'll investigate.

ebourg commented 1 year ago

I have fixed one issue affecting the cowork-server installer, the file contains sub directories and this wasn't handled properly by Jsign (each directory has a class identifier which has to be included in the hash, but Jsign hashed the one of the root directory only).

This doesn't fully solve the issue unfortunately, the signature is still rejected by Windows, I'll investigate further.

Horcrux7 commented 1 year ago

Thank you for the fix. I have test it with the cowork-server-23.4.237.msi and it work for this single file. No rejection. For a more complete test we need a released version. Do you plan a new version of jsign?

Horcrux7 commented 1 year ago

Do you want a small msi file with such sub directory structure for JUnit tests?

ebourg commented 1 year ago

Thank you for the fix. I have test it with the cowork-server-23.4.237.msi and it work for this single file. No rejection

Great! And I think I understand why now, there is an issue left when Jsign replaces an existing signature in a MSI file. But appending a signature to a file should be fine.

Do you plan a new version of jsign?

Yes Jsign 5.0 is just around the corner, I'd like to solve the remaining MSI issues first.

Do you want a small msi file with such sub directory structure for JUnit tests?

Yes that would be great. Currently the tests use a very small MSI file generated by WiX. The WiX source file is in the Git repository and I wonder if it could be modified to generate a file with sub directories. Maybe by adding a localization?

Horcrux7 commented 1 year ago

Yes, I think the directories are generated through localization. I have create a sample with SetupBuilder which use an local installed WIX. SetupBuilder use localization by default. If the sample is to large i can reduce the count of languages.

test-sub-storages.zip

ebourg commented 1 year ago

Thank you, do you have the WiX file generating this installer?

Horcrux7 commented 1 year ago

Attached but the wxs file does not contains the magic for the localizing. This is do with MsiTran.exe. See in the MsiBuilder.

test-sub-storages.wxs.zip

ebourg commented 1 year ago

I see, so the localization is defined from the command line.