diff --git a/public/electron.js b/public/electron.js index 511bc7b..2cbb403 100644 --- a/public/electron.js +++ b/public/electron.js @@ -17,32 +17,6 @@ require.extensions['.sh'] = function (module, filename) { }; const detectScript = require('./detect_linux.sh'); const installScript = require('./update_linux.sh'); -const publicKey = - '-----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-----'; // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. @@ -718,7 +692,7 @@ ipcMain.on(Constants.IPC_Install_Upgrade, (event, data) => { const hasHash = data.Sha256 && (data.Sha256.length > 0); if (hasSignature) { try { - const files = helpers.createSignatureFiles(data.Signature, publicKey); + const files = helpers.createSignatureFiles(data.Signature, Constants.DEV_PUBLIC_KEY); tempPub = files.PublicKeyFile; tempSig = files.SignatureFile; } catch (e) { diff --git a/src/constants.js b/src/constants.js index 1bc3503..5ccf561 100644 --- a/src/constants.js +++ b/src/constants.js @@ -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', diff --git a/src/helpers.js b/src/helpers.js index ec19112..57491f9 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -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())) } }); }; \ No newline at end of file diff --git a/src/helpers.test.js b/src/helpers.test.js new file mode 100644 index 0000000..bbeeba6 --- /dev/null +++ b/src/helpers.test.js @@ -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(); +}); \ No newline at end of file diff --git a/test/test_create_signature.sig.b64 b/test/test_create_signature.sig.b64 new file mode 100644 index 0000000..5b71ff1 --- /dev/null +++ b/test/test_create_signature.sig.b64 @@ -0,0 +1,18 @@ +Bdn0B2sR/fk0iSelC1hsKlovJkT6Y981WrtHjLfLgheEAkIM4L/63KeI4fmzWbZXGej8dB84cpfS +CPF5+PgWyasafHfv/LuuyJz9j1Vy0z5ipeZghgjBvrRRDrnrunSGzugfP+FILcS5zVAZLNCOXh+o +FdHzwH6aHJ32X9tQXzc6TZ+4FOKsxnuKTcEFEVV5fEsGLJx8Co7P9OSLJxfpCxdaGgW6nj7mpT1L +D2SppbBdI0vEu9ppPI3sXdVlBihwuYpEqS7g5wwiAiIuLljGzf9b7dkDUFql6xWYRwebPG7DAl8T +43R0kCkbrb6pIW5/xHZpDl3n1ueWIUIpTM3Mmkewte70gEykJ+Kvdo7NJ2TrTCfcFwcJXsQCtUDs +/SKxJa5b8Azl3iv8gYs+nEYLoNHS0djkst5y/F3mpfV2oVFigIxUrh6PuNS1y8REmnjHuDueOqZl +xau2HI/PZenM20kOlO0oz4hQ0KZuZkvqheMsCVYQZGAZawIeQy4pPKx8Bpd27b4E/tskeyrQWbOL +os304xMsgpSOCjZn6IJNfBY7jjl0YC3CY4YlT5l1QvHLgmQVrdNZK/Ymk0nfd8JyYJU6bQpB310f +uPxaVU/lwbphSsJ7Af4N34IfhvuFUfdHGlNTuoEu8w02vWadPO7s91xu84wiOVnQCpM1/D6xsW9r +JwZg146PNm7Kz6IeSSt+Mo6lUJMBFI3p39wltL0ACc/oEGlQrYjgslBe3SSwDQ2XDHyu0ThusCoR +VO3WLq2q44a1GYFWZsjRIk/dAA2ZCDfUXMGQszNec7V0PQplpqoL4vvTzYJ/lanPARrqzGdH5q21 +XnaWZBk04MDRG1PUMC2u9xQSpcZ69rGE4i6em0j5lk5mo03tLGGqghNTLw4d241iv5832AVcKDxp +WfhfDj5ltjkTnWjXWpA2fCzICuLewhAVcCunYZ3wZcahXl+nbtgCKIIxk4ITu95T2otoNF235KDe +vJmFrHWkcfz8cRaZvAAIf5OmqTULukZcAbj+JCj+wnZIHLzSumxLVtQxafZExJWrOyafBtKEHbeA +d/sn5Xi3lbkTqZJZHbINdlQS8YHZVSFwfeHnHYM8Acrd/c439wYRvzNHbJ6L1mgpvyZWdpii6A+R +2YZdBGvr+Bx1I4/5r9/viIrhfWX9oIin9l3ooCZaLKqlTeSGPjJn9XN5kFp158060u39hpc1VS1h +rWRNIv3b5pF25vvDHegXonecRhK8pObLGo8BlNiy1tUvHjopbIOA+P/ccMMUZP2IFpw/V5tAOjlM +T8A2gcEuuptEkW22hgmNiJEmehtYwue8m9c94BIU3JNZ/E9BMCCFIIMltzYab6A8xq9bawnwsqY= diff --git a/test/test_verify_sha256.dat b/test/test_verify_sha256.dat new file mode 100644 index 0000000..048c2a8 --- /dev/null +++ b/test/test_verify_sha256.dat @@ -0,0 +1 @@ +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 diff --git a/test/test_verify_sha256.dat.sha256 b/test/test_verify_sha256.dat.sha256 new file mode 100644 index 0000000..4c15b77 --- /dev/null +++ b/test/test_verify_sha256.dat.sha256 @@ -0,0 +1 @@ +6afe52b4c1c017f7e93ed994996e1abad0912f26e53d10d1dd8ce7382ca62b3f \ No newline at end of file diff --git a/test/test_verify_sha256_fail.dat b/test/test_verify_sha256_fail.dat new file mode 100644 index 0000000..bb83b0a --- /dev/null +++ b/test/test_verify_sha256_fail.dat @@ -0,0 +1 @@ +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 diff --git a/test/test_verify_signature.dat b/test/test_verify_signature.dat new file mode 100644 index 0000000..048c2a8 --- /dev/null +++ b/test/test_verify_signature.dat @@ -0,0 +1 @@ +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 diff --git a/test/test_verify_signature.dat.sig b/test/test_verify_signature.dat.sig new file mode 100644 index 0000000..3a3294c Binary files /dev/null and b/test/test_verify_signature.dat.sig differ diff --git a/test/test_verify_signature_fail.dat b/test/test_verify_signature_fail.dat new file mode 100644 index 0000000..bb83b0a --- /dev/null +++ b/test/test_verify_signature_fail.dat @@ -0,0 +1 @@ +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