Closed panekmaciej closed 1 year ago
Related to issue https://github.com/mtrojnar/osslsigncode/issues/51
It looks like the digest algorithm isn't checked, only the one specified in AppxBlockMap.xml
can be used. Jsign uses that by default and ignores the one specified on the command line.
Also if I may suggest, maybe a separate source file with all the zip specific code would make the code easier to browse.
It looks like the digest algorithm isn't checked, only the one specified in
AppxBlockMap.xml
can be used. Jsign uses that by default and ignores the one specified on the command line.
At the very least, a discrepancy should be reported as an error.
Also if I may suggest, maybe a separate source file with all the zip specific code would make the code easier to browse.
Only when we need a compression layer for other file formats. Until then, I recommend leaving it as it is.
It looks like the digest algorithm isn't checked, only the one specified in
AppxBlockMap.xml
can be used. Jsign uses that by default and ignores the one specified on the command line.At the very least, a discrepancy should be reported as an error.
Added HashMethod parsing to determine the md type.
My understanding is that the APPX hash always uses SHA-256, and the algorithm specified in AppxBlockMap.xml
is only used in the PKCS#7 signature. That would be interesting to check with a package having a different algorithm in AppxBlockMap.xml
.
It's great that you contribute to the project. Could you please enable CMAKE_BUILD_TYPE=Debug and squash compiler warnings in appx.c We prefer C89/C90 coding style. ISO C90 forbids mixed declarations and code. Please correct it.
Will, do, but will need few days, so probably after the 4th July weekend. Do you expect full C89 compliance (including getting rid of stdbool etc.) or just the variable declarations? Do you want me to do any other code changes?
:sweat_smile:
It's great if you can do it, but there's nothing urgent around here. It would be kind if you could use the consistent style in this project.
MakeAppx.exe packager with /h
option allows to specify the hash algorithm to use when creating the block map with one of the algorithms: SHA256 (default), SHA384 or SHA512.
AppxBlockMap.xml
+<BlockMap HashMethod="http://www.w3.org/2001/04/xmlenc#sha512" xmlns="http://schemas.microsoft.com/appx/2010/blockmap">
The hashes calculation looks good <3
Hash method is SHA512
Checking Block Map hashes:
Message digest algorithm : SHA512
Current message digest : A933C624A881D9C186C87E2C340455060EA53476865866437AB13852BAB653A0E29439F86A49EB78D9FC42E258C0F71DFEA723A9E75C0ECF38D7F586AF0664CB
Calculated message digest : A933C624A881D9C186C87E2C340455060EA53476865866437AB13852BAB653A0E29439F86A49EB78D9FC42E258C0F71DFEA723A9E75C0ECF38D7F586AF0664CB
Checking Content Types hashes:
Message digest algorithm : SHA512
Current message digest : 4966B087865353B32DA0F17F6A83ED99C32600313AAB27DD5C83AD936DFE320E2B3BD5E7451F6E921E0076EFB7E39C4D11230BBC678131C1AAB89F730CB3EEAA
Calculated message digest : 4966B087865353B32DA0F17F6A83ED99C32600313AAB27DD5C83AD936DFE320E2B3BD5E7451F6E921E0076EFB7E39C4D11230BBC678131C1AAB89F730CB3EEAA
Checking Data hashes:
Message digest algorithm : SHA512
Current message digest : 180C823FD655263105768B43D5DBC73534C93A146BBF901AACAC7D9831D0ACDCFD4CD3E4F2B0750E3A9CC4D70897FC8944FA851EF0E6C68431484BA07E75D570
Calculated message digest : 180C823FD655263105768B43D5DBC73534C93A146BBF901AACAC7D9831D0ACDCFD4CD3E4F2B0750E3A9CC4D70897FC8944FA851EF0E6C68431484BA07E75D570
Checking Central Directory hashes:
Message digest algorithm : SHA512
Current message digest : 07023A8AFC390C3BDCD2397F0150797010945CEAD845658628FD5ABC2C2FA8B21A4453EA099CE8CA5275AE065670F474E2E1DAEAE6E8C34D6E4829007B9A6E3B
Calculated message digest : 07023A8AFC390C3BDCD2397F0150797010945CEAD845658628FD5ABC2C2FA8B21A4453EA099CE8CA5275AE065670F474E2E1DAEAE6E8C34D6E4829007B9A6E3B
Yeah, I wrote the ZIP layer first, then starting adding it to osslsigncode which has totally different code style, so it does not look well.
I have been using this branch in production for the past week, and so far so good, so I will work on styling changes and hope it can be merged so more people can use it :)
MakeAppx.exe packager with /h option allows to specify the hash algorithm to use when creating the block map with one of the algorithms: SHA256 (default), SHA384 or SHA512.
Thank you for the hint, I used the MSIX Packaging Tool to generate the test file and there was no option to change the algorithm.
I can confirm the APPX hash algorithm is aligned on the block map hash.
It looks like the digest algorithm isn't checked, only the one specified in
AppxBlockMap.xml
can be used. Jsign uses that by default and ignores the one specified on the command line.At the very least, a discrepancy should be reported as an error.
Mixing of different digest algorithms is accepted.
AppxBlockMap.xml
+<BlockMap HashMethod="http://www.w3.org/2001/04/xmlenc#sha512" xmlns="http://schemas.microsoft.com/appx/2010/blockmap">
Let's sign this SHA512
appx file with -h sha256
option and then extract the newly created signature:
$ osslsigncode sign -h sha256 -in unsigned_sha512.appx -out signed_sha512.appx -certs (...)
Hash method is SHA512
Signing as a package
Succeeded
$ ./osslsigncode extract-signature -in signed_sha512.appx -out signed_sha512.der
Hash method is SHA512
Succeeded
Parsed PKCS#7 signature:
$ openssl asn1parse -i -inform DER -in signed_sha512.der
0:d=0 hl=4 l=3982 cons: SEQUENCE
4:d=1 hl=2 l= 9 prim: OBJECT :pkcs7-signedData
15:d=1 hl=4 l=3967 cons: cont [ 0 ]
19:d=2 hl=4 l=3963 cons: SEQUENCE
23:d=3 hl=2 l= 1 prim: INTEGER :01
26:d=3 hl=2 l= 15 cons: SET
28:d=4 hl=2 l= 13 cons: SEQUENCE
30:d=5 hl=2 l= 9 prim: OBJECT :sha256
41:d=5 hl=2 l= 0 prim: NULL
43:d=3 hl=4 l= 374 cons: SEQUENCE
47:d=4 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.311.2.1.4
59:d=4 hl=4 l= 358 cons: cont [ 0 ]
63:d=5 hl=4 l= 354 cons: SEQUENCE
67:d=6 hl=2 l= 53 cons: SEQUENCE
69:d=7 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.311.2.1.30
81:d=7 hl=2 l= 39 cons: SEQUENCE
83:d=8 hl=2 l= 4 prim: INTEGER :01010000
89:d=8 hl=2 l= 16 prim: OCTET STRING [HEX DUMP]:4BDFC50A07CEE24DB76E23C839A09FD1
107:d=8 hl=2 l= 1 prim: INTEGER :00
110:d=8 hl=2 l= 1 prim: INTEGER :00
113:d=8 hl=2 l= 1 prim: INTEGER :00
116:d=8 hl=2 l= 1 prim: INTEGER :00
119:d=8 hl=2 l= 1 prim: INTEGER :00
122:d=6 hl=4 l= 295 cons: SEQUENCE
126:d=7 hl=2 l= 13 cons: SEQUENCE
128:d=8 hl=2 l= 9 prim: OBJECT :sha512
139:d=8 hl=2 l= 0 prim: NULL
141:d=7 hl=4 l= 276 prim: OCTET STRING [HEX DUMP]:415050584158504343D994AC5B76542429C63699D6B827ABEFDDEB457A8A7315501963C9342C67CD99B3AC01966D08248BA53ECF4DB6F3FC9DEBBA6BA2A3F581A03B42A0E996ACE4415843447A98B78EA9FD335B6ED3CB8ACF57323F2E2EE8F27D787F03730604F0FBECAC8851071B96B3395A1F3260299E3E9F8846AF22D8A3683CB85DEDB55A33893A7AE6415843544BBB511EC72C65BC656F668F3E461CD760D6413606A649D09D6C303C372EC709C40E16ECFF0EEF7933D67F8A09C808577F62D206E07034F91B0CAC1F63B5ECF44158424D553C7617C9C9972302406EDCF4A1A43A947CD64DC7C259D92AD6B7FD7DEB4C21350D438301C09B54E75256F197E7C65955C62A70A07013652F3647FB39C1A08D
(...)
3490:d=5 hl=2 l= 13 cons: SEQUENCE
3492:d=6 hl=2 l= 9 prim: OBJECT :sha256
3503:d=6 hl=2 l= 0 prim: NULL
3505:d=5 hl=3 l= 203 cons: cont [ 0 ]
3508:d=6 hl=2 l= 25 cons: SEQUENCE
3510:d=7 hl=2 l= 9 prim: OBJECT :contentType
3521:d=7 hl=2 l= 12 cons: SET
3523:d=8 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.311.2.1.4
3535:d=6 hl=2 l= 28 cons: SEQUENCE
3537:d=7 hl=2 l= 9 prim: OBJECT :signingTime
3548:d=7 hl=2 l= 15 cons: SET
3550:d=8 hl=2 l= 13 prim: UTCTIME :190501000000Z
3565:d=6 hl=2 l= 28 cons: SEQUENCE
3567:d=7 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.311.2.1.11
3579:d=7 hl=2 l= 14 cons: SET
3581:d=8 hl=2 l= 12 cons: SEQUENCE
3583:d=9 hl=2 l= 10 prim: OBJECT :Microsoft Commercial Code Signing
3595:d=6 hl=2 l= 47 cons: SEQUENCE
3597:d=7 hl=2 l= 9 prim: OBJECT :messageDigest
3608:d=7 hl=2 l= 34 cons: SET
3610:d=8 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:4139B08892D75702296943EA02B01C927771F85230E811D669064AC7C86E8A5D
3644:d=6 hl=2 l= 65 cons: SEQUENCE
3646:d=7 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.311.2.1.12
3658:d=7 hl=2 l= 51 cons: SET
3660:d=8 hl=2 l= 49 cons: SEQUENCE
3662:d=9 hl=2 l= 14 cons: cont [ 0 ]
3664:d=10 hl=2 l= 12 prim: cont [ 1 ]
3678:d=9 hl=2 l= 31 cons: cont [ 1 ]
3680:d=10 hl=2 l= 29 prim: cont [ 0 ]
3711:d=5 hl=2 l= 13 cons: SEQUENCE
3713:d=6 hl=2 l= 9 prim: OBJECT :rsaEncryption
3724:d=6 hl=2 l= 0 prim: NULL
3726:d=5 hl=4 l= 256 prim: OCTET STRING [HEX DUMP]:6F397EB9982ECECFC17FD2DF20CFE659AC957B1C9CF201F9FE523FB8360DCCCDDA4F3796CD0A4A425113F8A97A117C72DF605FC281316A89BADF6719D1C3D581CDC5FD886B8A9A78F82AF70B4FE7B52D697D42A7776BDAABED2C8FBC78BF3AFF1F11874B0067432B4C6849C5BA916202F089735C1417DCB1EBEE1A302572AF56397CA5A7805B8858CA55F5421C71A272F5452E24D71BFA3586C3D705FDA86D856E48F8B9DA9FAE8E6C0E21F79FD5691DEC8BAA53655F951862E3F1231FD58CB4F018D74756604DBC3BBA47DF4ABAFD52BA176BE3A4BB8563B91D35AA7F333C7931A226E2B5D2B78614E160A48E7D56B3372B09A1413621F1BEA0619F2F662B8D
Signtool accepts this signature:
>signtool verify /pa /v signed_sha512.appx
(...)
Signature Index: 0 (Primary Signature)
Hash of file (sha512): 415050584158504343D994AC5B76542429C63699D6B827ABEFDDEB457A8A7315501963C9342C67CD99B3AC01966D08248BA53ECF4DB6F3FC9DEBBA6BA2A3F581A03B42A0E996ACE4415843447A98B78EA9FD335B6ED3CB8ACF57323F2E2EE8F27D787F03730604F0FBECAC8851071B96B3395A1F3260299E3E9F8846AF22D8A3683CB85DEDB55A33893A7AE6415843544BBB511EC72C65BC656F668F3E461CD760D6413606A649D09D6C303C372EC709C40E16ECFF0EEF7933D67F8A09C808577F62D206E07034F91B0CAC1F63B5ECF44158424D553C7617C9C9972302406EDCF4A1A43A947CD64DC7C259D92AD6B7FD7DEB4C21350D438301C09B54E75256F197E7C65955C62A70A07013652F3647FB39C1A08D
Signing Certificate Chain:
Issued to: Root CA
Issued by: Root CA
Expires: Tue Nov 10 02:00:00 2026
SHA1 hash: 7DE2629C73A86B21114C234B2DFEBC29A940DC41
(...)
Number of files successfully Verified: 1
Number of warnings: 0
Number of errors: 0
Mixing of different digest algorithms is accepted
Just checked and that's absolutely correct. Curiously signtool refuses to use a different algorithm when signing (an error code 0x8007000B is returned ), but this isn't enforced when verifying the signature.
@panekmaciej Would you please resolve the received review comments, so that I can merge your PR?
@panekmaciej is no longer responsive, so I took the liberty of creating https://github.com/mtrojnar/osslsigncode/tree/appx to continue working on the appx branch before it can be merged to the master branch.
I am on vacation until the end of this week and had no access to hw token to verify the code functionality. You are welcome to close the PR and finish the work yourself, all what's left is cosmetics.
You are welcome to close the PR and finish the work yourself,
Thank you for your work.
all what's left is cosmetics.
I'm not so sure about it. At least some of the memory corruption issues seem to be exploitable. One of the osslsigncode applications is signature verification of untrusted files, so an exploitable memory corruption results in remote code execution (RCE). This is definitely not cosmetics.
I'm not so sure about it. At least some of the memory corruption issues seem to be exploitable. One of the osslsigncode applications is signature verification of untrusted files, so an exploitable memory corruption results in remote code execution (RCE). This is definitely not cosmetics.
Agreed, but I do not have enough experience in the cybersecurity, so thank you for taking over and working towards merging it into the master branch.
BTW at the time it was the 1st working 3rd party appx signing code (even before JSign :P )
Added support of appx/msix. Still fresh and probably buggy.
Know issues / limitations: -Adds zlib dependency -uses BIO api to write files, which is 32 bit api, so 2GB file limit, as it uses BIO_tell to write LH offsets / CD offset in ZIP files -ZIP implementation is embedded, which limits external dependencies, but increases the code complexity and probably brings some bugs. It could also be separated from appx.c, but this is up to you. -There are grey areas in requirements for the ZIP headers, so the file will verify properly. We have already found few, but there might be more.
See the discussion for the details and more info about the APPX structure / signing: https://github.com/ebourg/jsign/issues/81