mtrojnar/osslsigncode

GAP: When signing a Appx, signtool creates AppxMetadata\CodeIntegrity.cat, osslsigncode doesn't

st-gr opened this issue · 6 comments

When signing a Appx using the Microsoft signtool then a security catalog file is added to the Appx package named AppxMetadata\CodeIntegrity.cat.

Signing the Appx with osslsigncode does not create the file.
I found a comment in your codebase that qualified the file as optional.

Here is how Claude Opus defines the file:
The AppxMetadata folder and the CodeIntegrity.cat file within it are necessary components of a compiled UWP (Universal Windows Platform) Appx package for release. The CodeIntegrity.cat file is a digital signature catalog that ensures the integrity and authenticity of the files in the Appx package.

The CodeIntegrity.cat file is automatically created by Visual Studio when you build and package your UWP app for release. It contains cryptographic hashes of the files in the Appx package, and it is digitally signed with the certificate used for code signing.

Here's how the CodeIntegrity.cat file is created during the build and packaging process:

  1. When you build your UWP app for release in Visual Studio, the build process compiles the app and generates the necessary files for packaging.

  2. During the packaging process, Visual Studio creates an Appx package that includes all the compiled files, assets, and metadata required for the app.

  3. As part of the packaging process, Visual Studio generates the AppxMetadata folder and the CodeIntegrity.cat file within it.

  4. The CodeIntegrity.cat file is created by calculating the cryptographic hashes of the files in the Appx package. These hashes are used to verify the integrity of the files and ensure that they haven't been tampered with.

  5. Visual Studio then digitally signs the CodeIntegrity.cat file using the code signing certificate specified in the project settings. This digital signature verifies the authenticity of the Appx package and ensures that it hasn't been modified after signing.

  6. The signed CodeIntegrity.cat file is included in the AppxMetadata folder within the Appx package.

When the Appx package is installed on a user's device, the Windows operating system verifies the digital signature of the CodeIntegrity.cat file to ensure the integrity and authenticity of the package. If the signature is valid and the hashes of the files match the ones recorded in the catalog, the installation proceeds. If the signature is invalid or the hashes don't match, the installation is blocked to prevent potentially malicious or tampered packages from being installed.

In summary, the CodeIntegrity.cat file is a crucial component of a UWP Appx package that ensures the integrity and authenticity of the app. Visual Studio automatically creates and signs this file during the build and packaging process for release builds.

Is this something that will be supported in future versions of osslsigncode or out of scope?

How should we test it to see the error?

Hi @mtrojnar,

Here are the steps that I took to compare the Microsoft signtool versus osslsigncode signing of an Appx.

System environment

OS: Windows 10
Compiler: Microsoft Visual Studio Community Edition 2017
NodeJS 12.18.4
Apache Cordova 11.0.0 (last version that officially supported UWP Windows apps)

Create and build cordova hello world project with a native plugin

Assuming Command Prompt (cmd.exe) on C:\

C:\cordova create test
cd test
cordova plugins add cordova-sqlite-evmax-build-free
cordova platforms add windows

cordova build --release --arch=x64 --verbose -- --packageCertificateKeyFile="C:\test\platforms\windows\CordovaApp_TemporaryKey.pfx" --packageThumbprint="1234"

Create an unsigned Appx (bypassing MSBuild signing task)

cd platforms\windows
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64\MakeAppx.exe" pack /l /h sha256 /f build\windows\bld\package.map.txt /o /p C:\test_unsigned.appx

Here is a copy of the unsigned Appx for your convenience:
test_unsigned.zip

Sign with MS signtool

make a copy for signing
copy test_unsigned.appx test-signtool-signed.appx

Sign
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64\signtool.exe" sign /fd sha256 /f C:\test\platforms\windows\CordovaApp_TemporaryKey.pfx test-signtool-signed.appx

Result: Has CodeIntegrity.cat file

test-signtool-signed.appx contains new folder AppxMetadata with file CodeIntegrity.cat
image

Sign with osslsigncode

osslsigncode.exe sign -in test_unsigned.appx -out test-osslsigncode-signed.appx -pkcs12 C:\test\platforms\windows\CordovaApp_TemporaryKey.pfx

Result: No CodeIntegrity.cat file

test-osslsigncode-signed.appx does not contain AppxMetadata\CodeIntegrity.cat

Notes on CodeIntegrity.cat

On Windows (crashes on wine) we can use the tool MakeCat to create an unsigned security catalog file based on a cdf file:
C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64\makecat.exe example.cdf

`---BEGIN example.cdf ---
[CatalogHeader]
Name=MyCodeIntegrity.cat
ResultDir=.
PublicVersion=0x1
EncodingType=0x00010001
CATATTR1=0x10010001:OSAttr:2:6.1

[CatalogFiles]
File1_Hash=.\test.txt
-- END example.cdf ---`

The file format is not documented. Possibly running many permutations of makecat could reveal the structure. The cdf format can contain many parameters, hitting the combination that signtool uses might be a challenge. However, the cat file supposedly only contains sha256 hashes of the files in the Appx.

We can use certutil -dump CodeIntegrity.cat to get the contents in human readable form. Also double clicking the cat file on Windows will show a properties dialog.

Interestingly the CodeIntegrity.cat file seems only to be created when the Appx contains additional (.dll) files in the root folder. (That is why I added the native cordova plugin to create the project).

I meant: How can I reproduce the error caused by the missing file?

Hi @mtrojnar,

The missing file does not trigger an error and passes the Windows App Certification Kit (WACK) checks.
2024-04-15_10-24-24-WACK

I haven't tested it on the MS Store as I lack an account to do so. The discrepancy was noticed during a comparison of packages between my Linux Wine Appx build and a Windows build, leading me to report it as a missing functionality relative to signtool. It appears the file is optional, maybe this will change in future?

Given that I am ok to close this for now.

It's not a trivial functionality to implement. If it ain't broke, don't fix it.

Agreed.