#21: Add signature validation during installations [partial]
This commit is contained in:
@@ -1,6 +1,32 @@
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.DEV_PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----\n' +
|
||||
'MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEKfZmq5mMAtD4kSt2Gc/5J\n' +
|
||||
'H+HHTYtUZE6YYvsvz8TNG/bNL67ZtNRyaoMyhLTfIN4rPBNLUfD+owNS+u5Yk+lS\n' +
|
||||
'ZLYyOuhoCZIFefayYqKLr42G8EeuRbx0IMzXmJtN0a4rqxlWhkYufJubpdQ+V4DF\n' +
|
||||
'oeupcPdIATaadCKVeZC7A0G0uaSwoiAVMG5dZqjQW7F2LoQm3PhNkPvAybIJ6vBy\n' +
|
||||
'LqdBegS1JrDn43x/pvQHzLO+l+FIG23D1F7iF+yZm3DkzBdcmi/mOMYs/rXZpBym\n' +
|
||||
'2/kTuSGh5buuJCeyOwR8N3WdvXw6+KHMU/wWU8qTCTT87mYbzH4YR8HgkjkLHxAO\n' +
|
||||
'5waHK6vMu0TxugCdJmVV6BSbiarJsh66VRosn7+6hlq6AdgksxqCeNELZBS+LBki\n' +
|
||||
'tb5hKyL+jNZnaHiR0U7USWtmnqZG6FVVRzlCnxP7tZo5O5Ex9AAFGz5JzOzsFNbv\n' +
|
||||
'xwQ0zqaTQOze+MJbkda7JfRoC6TncD0+3hoXsiaF4mCn8PqUCn0DwhglcRucZlST\n' +
|
||||
'ZvDNDo1WAtxPJebb3aS6uymNhBIquQbVAWxVO4eTrOYEgutxwkHE3yO3is+ogp8d\n' +
|
||||
'xot7f/+vzlbsbIDyuZBDe0fFkbTIMTU48QuUUVZpRKmKZTHQloz4EHqminbfX1sh\n' +
|
||||
'M7wvDkpJEtqbc0VnG/BukUzP6e7Skvgc7eF1sI3+8jH8du2rivZeZAl7Q2f+L9JA\n' +
|
||||
'BY9pjaxttxsud7V5jeFi4tKuDHi21/XhSjlJK2c2C4AiUEK5/WhtGbQ5JjmcOjRq\n' +
|
||||
'yXFRqLlerzOcop2kbtU3Ar230wOx3Dj23Wg8++lV3LU4U9vMR/t0qnSbCSGJys7m\n' +
|
||||
'ax2JpFlTwj/0wYuTlVFoNQHZJ1cdfyRiRBY4Ou7XO0W5hcBBKiYsC+neEeMMHdCe\n' +
|
||||
'iTDIW/ojcVTdFovl+sq3n1u4SBknE90JC/3H+TPE1s2iB+fwORVg0KPosQSNDS0A\n' +
|
||||
'7iK6AZCDC3YooFo+OzHkYMt9uLkXiXMSLx70az+qlIwOzVHKxCo7W/QpeKCXUCRZ\n' +
|
||||
'MMdlYEUs1PC8x2qIRUEVHuJ0XMTKNyOHmzVLuLK93wUWbToh+rdDxnbhX+emuESn\n' +
|
||||
'XH6aKiUwX4olEVKSylRUQw8nVckZGVWXzLDlgpzDrLHC8J8qHzFt7eCqOdiqsxhZ\n' +
|
||||
'x1U5LtugxwSWncTZ7vlKl0DuC/AWB7SuDi7bGRMSVp2n+MnD1VLKlsCclHXjIciE\n' +
|
||||
'W29n3G3lJ/sOta2sxqLd0j1XBQddrFXl5b609sIY81ocHqu8P2hRu5CpqJ/sGZC5\n' +
|
||||
'mMH3segHBkRj0xJcfOxceRLj1a+ULIIR3xL/3f8s5Id25TDo/nqBoCvu5PeCpo6L\n' +
|
||||
'9wIDAQAB\n' +
|
||||
'-----END PUBLIC KEY-----';
|
||||
|
||||
exports.RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory/raw/1.0.0-beta_branch/releases.json';
|
||||
exports.DATA_LOCATIONS = {
|
||||
arch: '~/.local/repertory/ui',
|
||||
|
||||
@@ -29,7 +29,7 @@ module.exports.createSignatureFiles = (signature, publicKey) => {
|
||||
const signatureFile = path.join(os.tmpdir(), fileName1 + '.sig');
|
||||
const publicKeyFile = path.join(os.tmpdir(), fileName2 + '.pub');
|
||||
|
||||
const buffer = new Buffer(signature, 'base64');
|
||||
const buffer = Buffer.from(signature, 'base64');
|
||||
fs.writeFileSync(signatureFile, buffer);
|
||||
fs.writeFileSync(publicKeyFile, publicKey);
|
||||
|
||||
@@ -544,15 +544,45 @@ module.exports.stopMountProcessSync = (directory, version, storageType) => {
|
||||
process.unref();
|
||||
};
|
||||
|
||||
module.exports.verifyHash = (file, hash) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const platform = os.platform();
|
||||
let command;
|
||||
let args;
|
||||
if (platform === 'darwin') {
|
||||
command = 'shasum';
|
||||
args = ['-b', '-a', '256', file];
|
||||
} else if (platform === 'linux') {
|
||||
command = 'sha256sum';
|
||||
args = ['-b', file, '-z'];
|
||||
} else {
|
||||
reject(Error('Platform not supported: ' + os.platform()))
|
||||
}
|
||||
if (command) {
|
||||
execFile(command, args, (err, stdout) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
const hash2 = stdout.split(' ')[0].trim().toLowerCase();
|
||||
if (hash2 === hash.toLowerCase()) {
|
||||
resolve(hash2);
|
||||
} else {
|
||||
reject(Error('Checksum failed for file'));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.verifySignature = (file, signatureFile, publicKeyFile) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const executeVerify = openssl => {
|
||||
//openssl dgst -sha256 -verify $pubkeyfile -signature signature.sig file
|
||||
execFile(openssl, ['dgst', '-sha256', '-verify', publicKeyFile, '-signature', signatureFile], res => {
|
||||
if (res.code !== 0) {
|
||||
reject(res);
|
||||
execFile(openssl, ['dgst', '-sha256', '-verify', publicKeyFile, '-signature', signatureFile, file], (err, stdout) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
resolve(stdout);
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -575,45 +605,13 @@ module.exports.verifySignature = (file, signatureFile, publicKeyFile) => {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
reject('Failed to locate \'openssl.exe\'');
|
||||
reject(Error('Failed to locate \'openssl.exe\''));
|
||||
}
|
||||
});
|
||||
} else if (os.platform() === 'linux') {
|
||||
executeVerify('openssl');
|
||||
} else {
|
||||
reject('Platform not supported: ' + os.platform())
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.verifyHash = (file, hash) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const platform = os.platform();
|
||||
let command;
|
||||
let args;
|
||||
if (platform === 'darwin') {
|
||||
command = 'shasum';
|
||||
args = ['-b', '-a', '256', file];
|
||||
} else if (platform === 'linux') {
|
||||
command = 'sha256sum';
|
||||
args = ['-b', file, '-z'];
|
||||
}
|
||||
else {
|
||||
reject('Platform not supported: ' + os.platform())
|
||||
}
|
||||
if (command) {
|
||||
execFile(command, args, (err, stdout) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
const hash2 = stdout.split(' ')[0].trim().toLowerCase();
|
||||
if (hash2 === hash.toLowerCase()) {
|
||||
resolve();
|
||||
} else {
|
||||
reject('Checksum failed for file');
|
||||
}
|
||||
}
|
||||
});
|
||||
reject(Error('Platform not supported: ' + os.platform()))
|
||||
}
|
||||
});
|
||||
};
|
||||
58
src/helpers.test.js
Normal file
58
src/helpers.test.js
Normal file
@@ -0,0 +1,58 @@
|
||||
const helpers = require('./helpers');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const Constants = require('./constants');
|
||||
|
||||
test('verify signature success', () => {
|
||||
return helpers
|
||||
.verifySignature(
|
||||
path.resolve('test/test_verify_signature.dat'),
|
||||
path.resolve('test/test_verify_signature.dat.sig'),
|
||||
path.resolve('blockstorage_dev_public.pem'))
|
||||
.then(stdout => {
|
||||
expect(stdout).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
test('verify signature fail', () => {
|
||||
return expect(helpers
|
||||
.verifySignature(
|
||||
path.resolve('test/test_verify_signature_fail.dat'),
|
||||
path.resolve('test/test_verify_signature.dat.sig'),
|
||||
path.resolve('blockstorage_dev_public.pem')))
|
||||
.rejects
|
||||
.toThrow()
|
||||
});
|
||||
|
||||
test('create temp signature files', () => {
|
||||
const b64signature = fs.readFileSync(path.resolve('test/test_create_signature.sig.b64'), {encoding: 'utf8'}).replace(/(\r\n|\n|\r)/gm,"");
|
||||
const data = helpers
|
||||
.createSignatureFiles(
|
||||
b64signature,
|
||||
Constants.DEV_PUBLIC_KEY);
|
||||
expect(data).toBeDefined();
|
||||
expect(data.PublicKeyFile).toBeDefined();
|
||||
expect(data.SignatureFile).toBeDefined();
|
||||
|
||||
expect(fs.statSync(data.SignatureFile).isFile()).toBe(true);
|
||||
expect(fs.statSync(data.PublicKeyFile).isFile()).toBe(true);
|
||||
|
||||
const b64signature2 = fs.readFileSync(data.SignatureFile).toString('base64').replace(/(\r\n|\n|\r)/gm,"");
|
||||
expect(b64signature2).toEqual(b64signature);
|
||||
|
||||
expect(fs.readFileSync(data.PublicKeyFile, {encoding: 'utf8'})).toEqual(Constants.DEV_PUBLIC_KEY);
|
||||
fs.unlinkSync(data.PublicKeyFile);
|
||||
fs.unlinkSync(data.SignatureFile);
|
||||
});
|
||||
|
||||
test('verify sha56 success', ()=> {
|
||||
const hash = fs.readFileSync('test/test_verify_sha256.dat.sha256', {encoding: 'utf8'});
|
||||
return expect(helpers.verifyHash(path.resolve('test/test_verify_sha256.dat'), hash))
|
||||
.resolves.toBe(hash)
|
||||
});
|
||||
|
||||
test('verify sha56 fail', ()=> {
|
||||
const hash = fs.readFileSync('test/test_verify_sha256.dat.sha256', {encoding: 'utf8'});
|
||||
return expect(helpers.verifyHash(path.resolve('test/test_verify_sha256_fail.dat'), hash))
|
||||
.rejects.toThrow();
|
||||
});
|
||||
Reference in New Issue
Block a user