Fixed authenticode padding.

Ylian Saint-Hilaire committed May 26, 2022 at 10:32 UTC c76aa4dd03d6be323af6af6a0d3627ee35bfc1b4
1 file changed +16 -19
authenticode.js
+16 -19
@@ -83,20 +83,15 @@ function createAuthenticodeHandler(path) {
83 obj.header.siglen = buf.readUInt32LE(4);
84 obj.header.signed = ((obj.header.sigpos != 0) && (obj.header.siglen != 0));
85
86 - if (obj.header.signed)
87 - {
86 + if (obj.header.signed) {
87 // Read signature block
89 - // Check the last 8 bytes for padding (Quad-Aligned), and remove it
90 - var pkcs7raw = readFileSlice(obj.header.sigpos + 8, obj.header.siglen - 8);
91 - var i;
92 - for (i = 0; i < 8 && pkcs7raw[pkcs7raw.length - 1 - i] == 0; ++i)
93 - {
94 - }
95 - if (i > 0)
96 - {
97 - pkcs7raw = pkcs7raw.slice(0, pkcs7raw.length - i);
98 - }
88
89 + // Remove the padding if needed
90 + var i, pkcs7raw = readFileSlice(obj.header.sigpos + 8, obj.header.siglen - 8);
91 + var derlen = forge.asn1.getBerValueLength(forge.util.createBuffer(pkcs7raw.slice(1, 5))) + 4;
92 + if (derlen != pkcs7raw.length) { pkcs7raw = pkcs7raw.slice(0, derlen); }
93 +
94 + // Decode the signature block
95 var pkcs7der = forge.asn1.fromDer(forge.util.createBuffer(pkcs7raw));
96
97 // To work around ForgeJS PKCS#7 limitation
@@ -161,8 +156,8 @@ function createAuthenticodeHandler(path) {
156 cert.validity.notAfter = new Date();
157 cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 3);
158 var attrs = [
164 - { name: 'commonName', value: 'example.org' },
165 - { name: 'countryName', value: 'US' },
159 + { name: 'commonName', value: 'example.org' },
160 + { name: 'countryName', value: 'US' },
161 { shortName: 'ST', value: 'California' },
162 { name: 'localityName', value: 'Santa Clara' },
163 { name: 'organizationName', value: 'Test' },
@@ -210,9 +205,9 @@ function createAuthenticodeHandler(path) {
205 var p7signature = Buffer.from(forge.pkcs7.messageToPem(p7).split('-----BEGIN PKCS7-----')[1].split('-----END PKCS7-----')[0], 'base64');
206 console.log('p7signature', p7signature.toString('base64'));
207
213 -
208 + // Quad Align the results, adding padding if necessary
209 var len = this.filesize + p7signature.length;
215 - var padding = (8 - ((len) % 8)) % 8; // Quad Align the results, adding padding if necessary
210 + var padding = (8 - ((len) % 8)) % 8;
211
212 var addresstable = Buffer.alloc(8);
213 addresstable.writeUInt32LE(this.filesize);
@@ -226,13 +221,15 @@ function createAuthenticodeHandler(path) {
221 var bytesLeft = this.filesize;
222 var tmp;
223
229 - while ((this.filesize - written) > 0)
230 - {
224 + // TODO: This copies the entire file including the old signature block.
225 + // Need to be fixed to only copy the file without the signature block
226 + while ((this.filesize - written) > 0) {
227 tmp = readFileSlice(written, (this.filesize - written) > 65535 ? 65535 : this.filesize - written);
228 fs.writeSync(output, tmp);
229 written += tmp.length;
230 }
235 -
231 +
232 + // Write the signature block
233 var win = Buffer.alloc(8); // WIN CERTIFICATE Structure
234 win.writeUInt32LE(p7signature.length + padding + 8); // DWORD length
235 win.writeUInt16LE(512, 4); // WORD revision