More improvements to authenticode-js error handling.
Ylian Saint-Hilaire committed
Jun 23, 2022 at 16:23 UTC
339e3efbefac28e2a24d88a00798e24fed95b223
1 file changed
+99
-95
authenticode.js
+99
-95
@@ -415,91 +415,93 @@ function createAuthenticodeHandler(path) {
415
416
// Decode the timestamp signature block
417
var timepkcs7der = null;
418
- try { timepkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(data, 'base64').toString('binary'))); } catch (ex) { func('' + ex); return; }
418
+ try { timepkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(data, 'base64').toString('binary'))); } catch (ex) { func("Unable to parse time-stamp response: " + ex); return; }
419
420
// Decode the executable signature block
421
var pkcs7der = null;
422
- try { pkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(obj.getRawSignatureBlock(), 'base64').toString('binary'))); } catch (ex) { func('' + ex); return; }
423
-
424
- // Get the ASN1 certificates used to sign the timestamp and add them to the certs in the PKCS7 of the executable
425
- // TODO: We could look to see if the certificate is already present in the executable
426
- const timeasn1Certs = timepkcs7der.value[1].value[0].value[3].value;
427
- for (var i in timeasn1Certs) { pkcs7der.value[1].value[0].value[3].value.push(timeasn1Certs[i]); }
428
-
429
- // Remove any existing time stamp signatures
430
- var newValues = [];
431
- for (var i in pkcs7der.value[1].value[0].value[4].value[0].value) {
432
- const j = pkcs7der.value[1].value[0].value[4].value[0].value[i];
433
- if ((j.tagClass != 128) || (j.type != 1)) { newValues.push(j); } // If this is not a time stamp, add it to out new list.
434
- }
435
- pkcs7der.value[1].value[0].value[4].value[0].value = newValues; // Set the new list
422
+ try {
423
+ var pkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(obj.getRawSignatureBlock(), 'base64').toString('binary')));
424
437
- // Get the time signature and add it to the executables PKCS7
438
- const timeasn1Signature = timepkcs7der.value[1].value[0].value[4];
439
- const countersignatureOid = asn1.oidToDer('1.2.840.113549.1.9.6').data;
440
- const asn1obj2 =
441
- asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [
442
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
443
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, countersignatureOid),
444
- timeasn1Signature
445
- ])
446
- ]);
447
- pkcs7der.value[1].value[0].value[4].value[0].value.push(asn1obj2);
448
-
449
- // Re-encode the executable signature block
450
- const p7signature = Buffer.from(forge.asn1.toDer(pkcs7der).data, 'binary');
425
+ // Get the ASN1 certificates used to sign the timestamp and add them to the certs in the PKCS7 of the executable
426
+ // TODO: We could look to see if the certificate is already present in the executable
427
+ const timeasn1Certs = timepkcs7der.value[1].value[0].value[3].value;
428
+ for (var i in timeasn1Certs) { pkcs7der.value[1].value[0].value[3].value.push(timeasn1Certs[i]); }
429
452
- // Open the output file
453
- var output = null;
454
- try { output = fs.openSync(args.out, 'w+'); } catch (ex) { }
455
- if (output == null) return false;
456
- var tmp, written = 0;
457
- var executableSize = obj.header.sigpos ? obj.header.sigpos : this.filesize;
430
+ // Remove any existing time stamp signatures
431
+ var newValues = [];
432
+ for (var i in pkcs7der.value[1].value[0].value[4].value[0].value) {
433
+ const j = pkcs7der.value[1].value[0].value[4].value[0].value[i];
434
+ if ((j.tagClass != 128) || (j.type != 1)) { newValues.push(j); } // If this is not a time stamp, add it to out new list.
435
+ }
436
+ pkcs7der.value[1].value[0].value[4].value[0].value = newValues; // Set the new list
437
459
- // Compute pre-header length and copy that to the new file
460
- var preHeaderLen = (obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16));
461
- var tmp = readFileSlice(written, preHeaderLen);
462
- fs.writeSync(output, tmp);
463
- written += tmp.length;
438
+ // Get the time signature and add it to the executables PKCS7
439
+ const timeasn1Signature = timepkcs7der.value[1].value[0].value[4];
440
+ const countersignatureOid = asn1.oidToDer('1.2.840.113549.1.9.6').data;
441
+ const asn1obj2 =
442
+ asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [
443
+ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
444
+ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, countersignatureOid),
445
+ timeasn1Signature
446
+ ])
447
+ ]);
448
+ pkcs7der.value[1].value[0].value[4].value[0].value.push(asn1obj2);
449
465
- // Quad Align the results, adding padding if necessary
466
- var len = executableSize + p7signature.length;
467
- var padding = (8 - ((len) % 8)) % 8;
450
+ // Re-encode the executable signature block
451
+ const p7signature = Buffer.from(forge.asn1.toDer(pkcs7der).data, 'binary');
452
469
- // Write the signature header
470
- var addresstable = Buffer.alloc(8);
471
- addresstable.writeUInt32LE(executableSize);
472
- addresstable.writeUInt32LE(8 + p7signature.length + padding, 4);
473
- fs.writeSync(output, addresstable);
474
- written += addresstable.length;
453
+ // Open the output file
454
+ var output = null;
455
+ try { output = fs.openSync(args.out, 'w+'); } catch (ex) { }
456
+ if (output == null) return false;
457
+ var tmp, written = 0;
458
+ var executableSize = obj.header.sigpos ? obj.header.sigpos : this.filesize;
459
476
- // Copy the rest of the file until the start of the signature block
477
- while ((executableSize - written) > 0) {
478
- tmp = readFileSlice(written, Math.min(executableSize - written, 65536));
460
+ // Compute pre-header length and copy that to the new file
461
+ var preHeaderLen = (obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16));
462
+ var tmp = readFileSlice(written, preHeaderLen);
463
fs.writeSync(output, tmp);
464
written += tmp.length;
481
- }
465
483
- // Write the signature block header and signature
484
- var win = Buffer.alloc(8); // WIN CERTIFICATE Structure
485
- win.writeUInt32LE(p7signature.length + padding + 8); // DWORD length
486
- win.writeUInt16LE(512, 4); // WORD revision
487
- win.writeUInt16LE(2, 6); // WORD type
488
- fs.writeSync(output, win);
489
- fs.writeSync(output, p7signature);
490
- if (padding > 0) { fs.writeSync(output, Buffer.alloc(padding, 0)); }
491
- written += (p7signature.length + padding + 8);
492
-
493
- // Compute the checksum and write it in the PE header checksum location
494
- var tmp = Buffer.alloc(4);
495
- tmp.writeUInt32LE(runChecksumOnFile(output, written, ((obj.header.peOptionalHeaderLocation + 64) / 4)));
496
- fs.writeSync(output, tmp, 0, 4, obj.header.peOptionalHeaderLocation + 64);
497
-
498
- // Close the file
499
- fs.closeSync(output);
500
-
501
- // Indicate we are done
502
- func(null);
466
+ // Quad Align the results, adding padding if necessary
467
+ var len = executableSize + p7signature.length;
468
+ var padding = (8 - ((len) % 8)) % 8;
469
+
470
+ // Write the signature header
471
+ var addresstable = Buffer.alloc(8);
472
+ addresstable.writeUInt32LE(executableSize);
473
+ addresstable.writeUInt32LE(8 + p7signature.length + padding, 4);
474
+ fs.writeSync(output, addresstable);
475
+ written += addresstable.length;
476
+
477
+ // Copy the rest of the file until the start of the signature block
478
+ while ((executableSize - written) > 0) {
479
+ tmp = readFileSlice(written, Math.min(executableSize - written, 65536));
480
+ fs.writeSync(output, tmp);
481
+ written += tmp.length;
482
+ }
483
+
484
+ // Write the signature block header and signature
485
+ var win = Buffer.alloc(8); // WIN CERTIFICATE Structure
486
+ win.writeUInt32LE(p7signature.length + padding + 8); // DWORD length
487
+ win.writeUInt16LE(512, 4); // WORD revision
488
+ win.writeUInt16LE(2, 6); // WORD type
489
+ fs.writeSync(output, win);
490
+ fs.writeSync(output, p7signature);
491
+ if (padding > 0) { fs.writeSync(output, Buffer.alloc(padding, 0)); }
492
+ written += (p7signature.length + padding + 8);
493
+
494
+ // Compute the checksum and write it in the PE header checksum location
495
+ var tmp = Buffer.alloc(4);
496
+ tmp.writeUInt32LE(runChecksumOnFile(output, written, ((obj.header.peOptionalHeaderLocation + 64) / 4)));
497
+ fs.writeSync(output, tmp, 0, 4, obj.header.peOptionalHeaderLocation + 64);
498
+
499
+ // Close the file
500
+ fs.closeSync(output);
501
+
502
+ // Indicate we are done
503
+ func(null);
504
+ } catch (ex) { func('' + ex); return; }
505
});
506
}
507
@@ -1315,30 +1317,32 @@ function createAuthenticodeHandler(path) {
1317
1318
// Decode the timestamp signature block
1319
var timepkcs7der = null;
1318
- try { timepkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(data, 'base64').toString('binary'))); } catch (ex) { func('' + ex); return; }
1320
+ try { timepkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(data, 'base64').toString('binary'))); } catch (ex) { func("Unable to parse time-stamp response: " + ex); return; }
1321
1320
- // Get the ASN1 certificates used to sign the timestamp and add them to the certs in the PKCS7 of the executable
1321
- // TODO: We could look to see if the certificate is already present in the executable
1322
- const timeasn1Certs = timepkcs7der.value[1].value[0].value[3].value;
1323
- for (var i in timeasn1Certs) { pkcs7der.value[1].value[0].value[3].value.push(timeasn1Certs[i]); }
1324
-
1325
- // Get the time signature and add it to the executables PKCS7
1326
- const timeasn1Signature = timepkcs7der.value[1].value[0].value[4];
1327
- const countersignatureOid = asn1.oidToDer('1.2.840.113549.1.9.6').data;
1328
- const asn1obj2 =
1329
- asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [
1330
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
1331
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, countersignatureOid),
1332
- timeasn1Signature
1333
- ])
1334
- ]);
1335
- pkcs7der.value[1].value[0].value[4].value[0].value.push(asn1obj2);
1322
+ try {
1323
+ // Get the ASN1 certificates used to sign the timestamp and add them to the certs in the PKCS7 of the executable
1324
+ // TODO: We could look to see if the certificate is already present in the executable
1325
+ const timeasn1Certs = timepkcs7der.value[1].value[0].value[3].value;
1326
+ for (var i in timeasn1Certs) { pkcs7der.value[1].value[0].value[3].value.push(timeasn1Certs[i]); }
1327
+
1328
+ // Get the time signature and add it to the executables PKCS7
1329
+ const timeasn1Signature = timepkcs7der.value[1].value[0].value[4];
1330
+ const countersignatureOid = asn1.oidToDer('1.2.840.113549.1.9.6').data;
1331
+ const asn1obj2 =
1332
+ asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [
1333
+ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
1334
+ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, countersignatureOid),
1335
+ timeasn1Signature
1336
+ ])
1337
+ ]);
1338
+ pkcs7der.value[1].value[0].value[4].value[0].value.push(asn1obj2);
1339
1337
- // Re-encode the executable signature block
1338
- const p7signature = Buffer.from(forge.asn1.toDer(pkcs7der).data, 'binary');
1340
+ // Re-encode the executable signature block
1341
+ const p7signature = Buffer.from(forge.asn1.toDer(pkcs7der).data, 'binary');
1342
1340
- // Write the file with the signature block
1341
- signEx(args, p7signature, obj.filesize, func);
1343
+ // Write the file with the signature block
1344
+ signEx(args, p7signature, obj.filesize, func);
1345
+ } catch (ex) { func('' + ex); }
1346
});
1347
}
1348
}
@@ -1715,7 +1719,7 @@ function createAuthenticodeHandler(path) {
1719
1720
// Decode the timestamp signature block
1721
var timepkcs7der = null;
1718
- try { timepkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(data, 'base64').toString('binary'))); } catch (ex) { func('' + ex); return; }
1722
+ try { timepkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(data, 'base64').toString('binary'))); } catch (ex) { func("Unable to parse time-stamp response: " + ex); return; }
1723
1724
// Get the ASN1 certificates used to sign the timestamp and add them to the certs in the PKCS7 of the executable
1725
// TODO: We could look to see if the certificate is already present in the executable