resedit-cli
Version:
Command-line tool for editing Windows Resource data in executable binaries
121 lines (120 loc) • 4.16 kB
JavaScript
import * as crypto from 'crypto';
import { validateStringValue } from './utils.js';
import { CertificateSelectMode, certificateSelectModeValues, } from '../../definitions/DefinitionData.js';
const validDigestAlgorithm = (() => {
const base = [
'sha1',
'sha256',
'sha512',
'sha224',
'sha384',
'sha512-224',
'sha512-256',
'sha3-224',
'sha3-256',
'sha3-384',
'sha3-512',
'shake128',
'shake256',
];
const nodejsHashes = crypto.getHashes();
return base.filter((type) => nodejsHashes.includes(type));
})();
export function getValidDigestAlgorithm() {
return validDigestAlgorithm;
}
export function isValidDigestAlgorithm(value) {
return (typeof value === 'string' &&
validDigestAlgorithm.includes(value));
}
function validateDigestAlgorithm(value) {
if (!isValidDigestAlgorithm(value)) {
throw new Error(`Invalid data: 'sign.digestAlgorithm' is not a valid value (choices: ${validDigestAlgorithm.join(', ')})`);
}
}
export default function parseSignDefinition(data) {
if (typeof data !== 'object' || !data) {
throw new Error("Invalid data: 'sign' is not an object");
}
const keys = Object.keys(data);
let hasP12File = false;
if (keys.includes('p12File')) {
if (keys.includes('privateKeyFile') ||
keys.includes('certificateFile')) {
throw new Error("Only 'p12File' or ('privateKeyFile' and 'certificateFile') can be specified");
}
hasP12File = true;
}
else {
if (!keys.includes('privateKeyFile') ||
!keys.includes('certificateFile')) {
throw new Error("Both 'privateKeyFile' and 'certificateFile' are required if 'p12File' is not specified");
}
}
let p12File;
let privateKeyFile;
let certificateFile;
let certSelect = CertificateSelectMode.Leaf;
let password;
let digestAlgorithm = 'sha256';
let timestampServer;
keys.forEach((key) => {
const value = data[key];
switch (key) {
case 'p12File':
validateStringValue(value, 'sign.p12File');
p12File = value;
break;
case 'privateKeyFile':
validateStringValue(value, 'sign.privateKeyFile');
privateKeyFile = value;
break;
case 'certificateFile':
validateStringValue(value, 'sign.certificateFile');
certificateFile = value;
break;
case 'certSelect':
if (typeof value !== 'string' ||
!certificateSelectModeValues.includes(value)) {
throw new Error(`Invalid data: 'sign.certSelect' is not a valid value (choices: ${certificateSelectModeValues.join(', ')})`);
}
certSelect = value;
break;
case 'password':
if (typeof value !== 'undefined') {
validateStringValue(value, 'sign.password');
}
password = value;
break;
case 'digestAlgorithm':
validateDigestAlgorithm(value);
digestAlgorithm = value;
break;
case 'timestampServer':
validateStringValue(value, 'sign.timestampServer');
timestampServer = value;
break;
default:
throw new Error(`Invalid data: unknown property '${key}' on 'sign`);
}
});
if (hasP12File) {
return {
p12File: p12File,
certSelect,
password,
digestAlgorithm,
timestampServer,
};
}
else {
return {
privateKeyFile: privateKeyFile,
certificateFile: certificateFile,
certSelect,
password,
digestAlgorithm,
timestampServer,
};
}
}