mirror of https://github.com/keeweb/keeweb.git
signing code on a Windows VM
This commit is contained in:
parent
086f2c73db
commit
4c1dda68b5
|
@ -590,10 +590,9 @@ module.exports = function(grunt) {
|
||||||
},
|
},
|
||||||
'sign-exe': {
|
'sign-exe': {
|
||||||
options: {
|
options: {
|
||||||
spc: 'keys/keeweb.spc',
|
// algo: 'SHA256',
|
||||||
key: '01',
|
url: pkg.homepage,
|
||||||
algo: 'sha256',
|
...codeSignConfig.windows
|
||||||
url: pkg.homepage
|
|
||||||
},
|
},
|
||||||
'win32-build-x64': {
|
'win32-build-x64': {
|
||||||
options: {
|
options: {
|
||||||
|
|
|
@ -22,108 +22,53 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const { spawnSync } = require('child_process');
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
grunt.registerMultiTask(
|
grunt.registerMultiTask('sign-exe', 'Signs exe file with authenticode certificate', function() {
|
||||||
'sign-exe',
|
const opt = this.options();
|
||||||
'Signs exe file with authenticode certificate',
|
for (const [file, name] of Object.entries(opt.files)) {
|
||||||
async function() {
|
signFile(file, name, opt);
|
||||||
const opt = this.options();
|
}
|
||||||
const done = this.async();
|
});
|
||||||
if (opt.pvk) {
|
|
||||||
const keytar = require('keytar');
|
function signFile(file, name, opt) {
|
||||||
keytar
|
const fileNameWithoutFolder = path.basename(file);
|
||||||
.getPassword(opt.keytarPasswordService, opt.keytarPasswordAccount)
|
const sharePath = `${process.env.HOME}/VMShare/${fileNameWithoutFolder}`;
|
||||||
.then(password => {
|
fs.copyFileSync(file, sharePath);
|
||||||
if (!password) {
|
|
||||||
return grunt.warn('Code sign password not found');
|
const timeServer = 'http://timestamp.verisign.com/scripts/timstamp.dll';
|
||||||
}
|
|
||||||
const promises = Object.keys(opt.files).map(file =>
|
const cmd = 'VBoxManage';
|
||||||
signFile(file, opt.files[file], opt, password)
|
const args = [
|
||||||
);
|
'guestcontrol',
|
||||||
Promise.all(promises).then(done);
|
opt.vmName,
|
||||||
})
|
'--username',
|
||||||
.catch(e => {
|
opt.vmUser,
|
||||||
grunt.warn('Code sign error: ' + e);
|
'--password',
|
||||||
});
|
opt.vmPass,
|
||||||
} else {
|
'run',
|
||||||
const sign = require('../util/sign');
|
opt.vmExec,
|
||||||
const pin = await sign.getPin();
|
`sign /t ${timeServer} /d "${name}" /du ${opt.url} ${opt.vmShare}${fileNameWithoutFolder}`
|
||||||
for (const file of Object.keys(opt.files)) {
|
];
|
||||||
await signFile(file, opt.files[file], opt, pin);
|
// the algo is not working: "/fd ${opt.algo}"
|
||||||
}
|
let res = spawnSync(cmd, args);
|
||||||
done();
|
if (res.status) {
|
||||||
|
args[5] = '*';
|
||||||
|
const cmdStr = cmd + ' ' + args.join(' ');
|
||||||
|
grunt.warn(`Sign error ${file}: exit code ${res.status}.\nCommand: ${cmdStr}`);
|
||||||
|
}
|
||||||
|
res = spawnSync('osslsigncode', ['verify', sharePath]);
|
||||||
|
if (res.status) {
|
||||||
|
const hasCertHash = res.stdout.includes(`Serial : ${opt.certHash}`);
|
||||||
|
if (!hasCertHash) {
|
||||||
|
grunt.warn(
|
||||||
|
`Verify error ${file}: exit code ${res.status}.\n${res.stdout.toString()}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
fs.renameSync(sharePath, file);
|
||||||
|
grunt.log.writeln(`Signed ${file}: ${name}`);
|
||||||
function signFile(file, name, opt, password) {
|
|
||||||
const signedFile = file + '.sign';
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const pkcsArgs = opt.pvk
|
|
||||||
? []
|
|
||||||
: [
|
|
||||||
'-pkcs11engine',
|
|
||||||
'/usr/local/lib/engines/engine_pkcs11.so',
|
|
||||||
'-pkcs11module',
|
|
||||||
'/usr/local/lib/opensc-pkcs11.so'
|
|
||||||
];
|
|
||||||
const args = [
|
|
||||||
'-spc',
|
|
||||||
opt.spc,
|
|
||||||
'-key',
|
|
||||||
opt.pvk ? require('path').resolve(opt.pvk) : opt.key,
|
|
||||||
'-pass',
|
|
||||||
password,
|
|
||||||
'-h',
|
|
||||||
opt.algo,
|
|
||||||
'-n',
|
|
||||||
name,
|
|
||||||
'-i',
|
|
||||||
opt.url,
|
|
||||||
'-t',
|
|
||||||
'http://timestamp.verisign.com/scripts/timstamp.dll',
|
|
||||||
...pkcsArgs,
|
|
||||||
'-in',
|
|
||||||
file,
|
|
||||||
'-out',
|
|
||||||
signedFile
|
|
||||||
];
|
|
||||||
const spawned = grunt.util.spawn(
|
|
||||||
{
|
|
||||||
cmd: 'osslsigncode',
|
|
||||||
args
|
|
||||||
},
|
|
||||||
(error, result, code) => {
|
|
||||||
if (error || code) {
|
|
||||||
spawned.kill();
|
|
||||||
grunt.warn(`Cannot sign file ${file}, signtool error ${code}: ${error}`);
|
|
||||||
return reject();
|
|
||||||
}
|
|
||||||
grunt.util.spawn(
|
|
||||||
{
|
|
||||||
cmd: 'osslsigncode',
|
|
||||||
args: ['verify', signedFile]
|
|
||||||
},
|
|
||||||
(ex, result, code) => {
|
|
||||||
if (code) {
|
|
||||||
grunt.warn(`Verify error ${file}: \n${result.stdout.toString()}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (fs.existsSync(file)) {
|
|
||||||
fs.renameSync(signedFile, file);
|
|
||||||
}
|
|
||||||
grunt.log.writeln(`Signed ${file}: ${name}`);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// spawned.stdout.pipe(process.stdout);
|
|
||||||
spawned.stderr.pipe(process.stderr);
|
|
||||||
// spawned.stdin.setEncoding('utf-8');
|
|
||||||
// spawned.stdin.write(password);
|
|
||||||
// spawned.stdin.write('\n');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue