Closed 0x0ACB closed 4 months ago
osslsigncode
supports equivalent but not identical functionality:
Use the "extract-data" command to extract a data content to be signed:
$ ./osslsigncode extract-data -ph -in unsigned.exe -out data.der
Calculated page hash : 0000000043CE7BFD7EEA479340D0EA3F8B5903D3F85BB18AE184A662372C64F8 ...
Succeeded
You can parse this data content using openssl asn1parse
:
$ openssl asn1parse -i -inform der -in data.der
0:d=0 hl=4 l=1191 cons: SEQUENCE
4:d=1 hl=2 l= 9 prim: OBJECT :pkcs7-signedData
15:d=1 hl=4 l=1176 cons: cont [ 0 ]
19:d=2 hl=4 l=1172 cons: SEQUENCE
23:d=3 hl=2 l= 1 prim: INTEGER :01
26:d=3 hl=2 l= 0 cons: SET
28:d=3 hl=4 l=1161 cons: SEQUENCE
32:d=4 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.311.2.1.4
44:d=4 hl=4 l=1145 cons: cont [ 0 ]
48:d=5 hl=4 l=1141 cons: SEQUENCE
52:d=6 hl=4 l=1086 cons: SEQUENCE
56:d=7 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.311.2.1.15
68:d=7 hl=4 l=1070 cons: SEQUENCE
72:d=8 hl=2 l= 2 prim: BIT STRING
76:d=8 hl=4 l=1062 cons: cont [ 0 ]
80:d=9 hl=4 l=1058 cons: cont [ 1 ]
84:d=10 hl=2 l= 16 prim: OCTET STRING [HEX DUMP]:A6B586D5B4A12466AE05A217DA8E60D6
102:d=10 hl=4 l=1036 prim: OCTET STRING [HEX DUMP]:3182040830820404060A2B060104018237020302318203F4048203F00000000043CE7BFD7EEA479340D0EA3F8B5903D3F85BB18AE184A662372C64F8B5C65A850006000011A0B495758896A678943B08A3FEF6FC706E71E107A99C1BF8CC20B806D5B30A0016000051FB1A5F0953BB94C24C7ADE3BE40DD9C64F36B7E8BD6FAD721963879B49ED6400260000E7E1CFEAD5790A9648CED313941E72B2A65B8BA268EA4FE5BB996AB2721957C100360000789A4DB4E373AC67E19BE9106F61B66F6AB41EB5933B594E0FA9DBAAD887CF5B00460000CD1280F1996316158ACC379186FEF17863EF4F71D6DF4E58B72528AD94BCB99F0056000069AA4335602DDD63D0F3D74AEEEEC0682661E58B387C73E5CE74793FC1312FCC0066000029E21E3CA008B6FB8569FBD36A3A96C7DAADAD0A773FA3C6786D31D4D2200FF10072000084D357D930C8ED4B2D721FDF117631363E7CBCFE0C43A03D8613C851AE552F0C007400009085BD3FA0307838E79C8E95286AB9796441875BE3EB515E77B730828D10A85300840000A2E458D6F82B3D7339F5E65763073844492CF730E71FD0319972C6C970E9551900880000B2DB0EDE8B3BE555196F4B280EF801230D454E185224A4566B25983FF38D694D008E00007CE4D267182837D2404FEEDA02DD62CC05E5D4035533D750F2B39B95333EFDC1009400008AD3A571A7E1F3DCBD1724307F857090CD3DA17AE4B50287F13BE1448BACAB71009C0000BC2DCA9F2258BD041C221FB2030DDBBECE79DDEA737377697D14B9E785DC9F38009E0000AD7FACB2586FC6E966C004D7D1D16B024F5805FF7CB47C7A85DABD8B48892CA700A000008212B120FDB5F4D12FC41E179B7825626E0C4CAC1D5B62732E4E61A87A52477F00A20000583053AA6F5EDDCE62321C0ACC5834A700612D194785E39841AAC0B766DDC2CC00B20000A0DC042307D09BEF0B43B5038D9395900149C7437AB87F46706E5022B4F9735600C20000942F4564CEEF5B749938E5519C644EEF18271882BB680CDBD4B0915EC4BB827600D200003F17E75461DA0DF9E2D3F930AD40007BF0829D8508D7063F843CC4A49F0600DD00DA0000FA6352CA03941DD7C181C7B11C83954304BF876606E0E99B66B5EE8C91DAFFE800E200005E873D950A0BA238B8CE31E47003045A8AE491A4CCBDA5DA9A7D5F8820C79FA600EA00002F6F07B6AF66160727694C22EC616F37BEBB88FF278AF37D6944BA1885CA37F200EC0000F84FB7423BEC6A02D07F4AF43DB43DC819DAF7AF6AA460C412D5DAF57B79C4C500F00000A1876491A1818615B50F0B63829169A3A56A3346FF1F202F18A2D7B90FC7088E00F80000B76878512F16F5A749AFB1653B0CED6FECE3E92A0BE3E09314D760965C92178100FA00000000000000000000000000000000000000000000000000000000000000000000
1142:d=6 hl=2 l= 49 cons: SEQUENCE
1144:d=7 hl=2 l= 13 cons: SEQUENCE
1146:d=8 hl=2 l= 9 prim: OBJECT :sha256
1157:d=8 hl=2 l= 0 prim: NULL
1159:d=7 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:2D2C7B382C8163A419B9FF214A7B651C33F9EA43335907F11377290C5158A7A4
1193:d=3 hl=2 l= 0 cons: SET
Sign extracted data on the signing server (use the private key), add a timestamp (optionally), create completed PKCS#7 signature:
$ ./osslsigncode sign -certs cert.pem -key key.pem -in data.der -out signed_data.der
Succeeded
Use the "attach-signature" command to attach the PKCS#7 signature to the file:
$ ./osslsigncode attach-signature -in unsigned.exe -sigin signed_data.der -out signed.exe -CAfile CACert.pem
PE checksum : 0001E9CF
Signature Index: 0 (Primary Signature)
Message digest algorithm : SHA256
Current message digest : 2D2C7B382C8163A419B9FF214A7B651C33F9EA43335907F11377290C5158A7A4
Calculated message digest : 2D2C7B382C8163A419B9FF214A7B651C33F9EA43335907F11377290C5158A7A4
Page hash algorithm : SHA256
Page hash : 0000000043CE7BFD7EEA479340D0EA3F8B5903D3F85BB18AE184A662372C64F8 ...
Calculated page hash : 0000000043CE7BFD7EEA479340D0EA3F8B5903D3F85BB18AE184A662372C64F8 ...
Signer's certificate:
------------------
Signer #0:
Subject: /C=PL/ST=Mazovia Province/L=Warsaw/O=osslsigncode/OU=CSP/CN=Certificate/emailAddress=osslsigncode@example.com
Issuer : /C=PL/O=osslsigncode/OU=Certification Authority/CN=Intermediate CA
Serial : 68C6F0E7ECD2F051581799BE7C8A37158783BE20
Certificate expiration date:
notBefore : Jan 1 00:00:00 2018 GMT
notAfter : Dec 31 00:00:00 2024 GMT
Message digest algorithm: SHA256
(...)
Signature verification: ok
Number of verified signatures: 1
Signature successfully attached
Succeeded
Oh thank you that is perfect.
The signtool from microsoft offers the options
Generates the digest to be signed and the unsigned PKCS7 files
Creates the signature by ingesting the signed digest to the unsigned PKCS7 file
andSigns the digest only
Which can be used for easier integration in CI/CD pipelines since it is not neccessary to send potantially large binaries to the signing server. From looking at the doc and code it doesn't seem like this is supported by osslsigncode. This is an option that we would be interested in since code signing certificates are required to be on a hardware token now and the cloud HSM solutions are quite expensive. As such we would like to have a small local signing server that just does the code signing step while still using the gh action runners to do the actual building.
If this option is currently not available and I am not just missing something, would you be interested in a PR to implement this? And if so would you be kind enough to point me in the right direction? From a quick inspection of the code it seems I would just need to use https://github.com/mtrojnar/osslsigncode/blob/42e97339167282cb1e9b55c4d3b4e6485fed13ea/pe.c#L446 this function here (and the matching ones for the other file formats) to generate the signature itself. Would just need to figure out how to parse the digest into the hash BIO I guess.