Updated padding, updated signing
Bryan Roe committed
May 25, 2022 at 22:26 UTC
21b35662145cdb5533f3cb8e8c730bf523eaba82
1 file changed
+49
-3
authenticode.js
+49
-3
@@ -53,6 +53,7 @@ function createAuthenticodeHandler(path) {
53
if (obj.fd != null) return;
54
55
// Open the file descriptor
56
+ obj.path = path;
57
obj.fd = fs.openSync(path);
58
obj.stats = fs.fstatSync(obj.fd);
59
obj.filesize = obj.stats.size;
@@ -82,10 +83,20 @@ function createAuthenticodeHandler(path) {
83
obj.header.siglen = buf.readUInt32LE(4);
84
obj.header.signed = ((obj.header.sigpos != 0) && (obj.header.siglen != 0));
85
85
- if (obj.header.signed) {
86
+ if (obj.header.signed)
87
+ {
88
// Read signature block
87
- // TODO: The 3 bytes at the end may be padding we need to remove, not a contant.
88
- var pkcs7raw = readFileSlice(obj.header.sigpos + 8, obj.header.siglen - 8 - 3);
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
+ }
99
+
100
var pkcs7der = forge.asn1.fromDer(forge.util.createBuffer(pkcs7raw));
101
102
// To work around ForgeJS PKCS#7 limitation
@@ -198,6 +209,40 @@ function createAuthenticodeHandler(path) {
209
p7.sign();
210
var p7signature = Buffer.from(forge.pkcs7.messageToPem(p7).split('-----BEGIN PKCS7-----')[1].split('-----END PKCS7-----')[0], 'base64');
211
console.log('p7signature', p7signature.toString('base64'));
212
+
213
+
214
+ var len = this.filesize + p7signature.length;
215
+ var padding = (8 - ((len) % 8)) % 8; // Quad Align the results, adding padding if necessary
216
+
217
+ var addresstable = Buffer.alloc(8);
218
+ addresstable.writeUInt32LE(this.filesize);
219
+ addresstable.writeUInt32LE(8 + p7signature.length + padding, 4);
220
+
221
+ var b = this.path.split('.');
222
+ b[b.length - 2] += '-jsigned';
223
+
224
+ var output = fs.openSync(b.join('.'), 'w');
225
+ var written = 0;
226
+ var bytesLeft = this.filesize;
227
+ var tmp;
228
+
229
+ while ((this.filesize - written) > 0)
230
+ {
231
+ tmp = readFileSlice(written, (this.filesize - written) > 65535 ? 65535 : this.filesize - written);
232
+ fs.writeSync(output, tmp);
233
+ written += tmp.length;
234
+ }
235
+
236
+ var win = Buffer.alloc(8); // WIN CERTIFICATE Structure
237
+ win.writeUInt32LE(p7signature.length + padding + 8); // DWORD length
238
+ win.writeUInt16LE(512, 4); // WORD revision
239
+ win.writeUInt16LE(2, 6); // WORD type
240
+
241
+ fs.writeSync(output, win);
242
+ fs.writeSync(output, p7signature);
243
+ if (padding > 0) { fs.writeSync(output, Buffer.alloc(padding, 0)); }
244
+ fs.writeSync(output, addresstable, 0, addresstable.length, this.header.header_size + 152 + (this.header.pe32plus * 16));
245
+ fs.closeSync(output);
246
}
247
248
openFile();
@@ -241,6 +286,7 @@ function start() {
286
if (exe.fileHashSigned != null) { console.log('fileHashSigned', exe.fileHashSigned.toString('hex')); }
287
if (exe.fileHashActual != null) { console.log('fileHashActual', exe.fileHashActual.toString('hex')); }
288
if (exe.signatureBlock) { console.log('Signature', exe.signatureBlock.toString('hex')); }
289
+ console.log('FileLen: ' + exe.filesize);
290
}
291
292
if (command == 'sign') {