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