diff --git a/LICENSE b/LICENSE index 4b98d8f..2f791c8 100644 --- a/LICENSE +++ b/LICENSE @@ -402,39 +402,6 @@ Library. - sjcl - -------------------- - License: BSD - - http://opensource.org/licenses/BSD-2-Clause - - Copyright (c) 2009-2015, Emily Stark, Mike Hamburg and Dan Boneh at - Stanford University. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - window -------------------- License: MIT diff --git a/lib/FetchRequest.js b/lib/FetchRequest.js index 241bafd..ec84657 100644 --- a/lib/FetchRequest.js +++ b/lib/FetchRequest.js @@ -1,5 +1,5 @@ const fetch = require('make-fetch-happen'); -const sjcl = require("sjcl"); +const crypto = require("crypto"); const URL = require('url').URL; function FetchRequest(param) { @@ -91,8 +91,7 @@ function FetchRequest(param) { } let signMessage = function(messageString) { - let hmacFunction = new sjcl.misc.hmac(sjcl.codec.utf8String.toBits(myself.apiKeySecret), sjcl.hash.sha256);// Key, Hash - return sjcl.codec.hex.fromBits(hmacFunction.encrypt(messageString)); + return crypto.createHmac('sha256', myself.apiKeySecret).update(messageString).digest('hex'); } } diff --git a/lib/SendSafely.js b/lib/SendSafely.js index 42ec787..df4994c 100644 --- a/lib/SendSafely.js +++ b/lib/SendSafely.js @@ -4,7 +4,6 @@ Object.assign(globalThis, {ReadableStream, WritableStream, TransformStream}); const Window = require('./window'); const window = new Window(); const self = window; -const sjcl = require("sjcl"); const crypto = require("crypto"); const fs = require('fs'); const openpgp = require('openpgp'); @@ -46,29 +45,6 @@ function SendSafely(url, apiKeyId, apiKeySecret, requestAPI){ this.requestAPI = (requestAPI === undefined) ? "NODE_API" : requestAPI; this.wrapperRequest = new FetchRequest({url: url, apiKey: apiKeyId, apiKeySecret: apiKeySecret}); - sjcl.codec.utf8String.fromBits = function(a) { - var b = "", - c = sjcl.bitArray.bitLength(a), - d, - e; - for (d = 0; d < c / 8; d++) - 0 === (d & 3) && (e = a[d / 4]), - b += String.fromCharCode(e >>> 8 >>> 8 >>> 8), - e <<= 8; - - return decodeURIComponent(encodeURIComponent(b)); - } - - - sjcl.random.setDefaultParanoia(6); - //sjcl.random.startCollectors(); - var buf = crypto.randomBytes(1024 / 8) // 128 bytes - buf = new Uint32Array(new Uint8Array(buf).buffer) - sjcl.random.addEntropy(buf, 1024, "crypto.randomBytes"); - sjcl.random.addEventListener("seeded", function () { - sjcl.random.stopCollectors(); - }); - this.eventHandler = new EventHandler(myself); this.executor = new Executor(myself.eventHandler); @@ -941,9 +917,6 @@ function SendSafely(url, apiKeyId, apiKeySecret, requestAPI){ * @ignore */ this.checkAPIInitialized = function() { - if(typeof sjcl === "undefined"){ - throw "SJCL is not defined"; - } if(myself.apiKeySecret === undefined || myself.apiKeyId === undefined){ throw "API not initialized - From API"; } @@ -1070,10 +1043,7 @@ function SignedRequest(eventHandler, url, apiKey, apiKeySecret, requestAPI) { }; this.signMessage = function (messageString) { - var hmacFunction = new sjcl.misc.hmac(sjcl.codec.utf8String.toBits(myself.apiKeySecret), sjcl.hash.sha256);// Key, Hash - - return sjcl.codec.hex.fromBits(hmacFunction.encrypt(messageString)); - + return crypto.createHmac('sha256', myself.apiKeySecret).update(messageString).digest('hex'); }; /** @@ -1723,32 +1693,12 @@ function ConvertRSAKey(eventHandler) { function seedRandomness(data, callback) { - if(sjcl.random.isReady(6) == 0) - { - sjcl.random.addEventListener("seeded", function () { - startWorker(data, callback); - }); - sjcl.random.addEventListener("progress", function(evt) { - var entropyPercent = 0; - if(evt != undefined && evt != 1 && !isNaN(evt)) { - entropyPercent = (evt*100); - myself.eventHandler.raise('sendsafely.entropy.progress', {entropy: entropyPercent}); - } else { - myself.eventHandler.raise('sendsafely.entropy.ready', {}); - } - }); - } - else { - myself.eventHandler.raise('sendsafely.entropy.ready', {}); - startWorker(data, callback); - } + myself.eventHandler.raise('sendsafely.entropy.ready', {}); + startWorker(data, callback); } function startWorker(data, callback) { - var randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(1024,6)); - - // Create the worker. - //var worker = new Worker(myself.serverWorkerURI); + var randomness = crypto.randomBytes(1024 * 4).toString('latin1'); window.addEventListener('message', function(e) { @@ -1761,7 +1711,7 @@ function ConvertRSAKey(eventHandler) { } break; case 'randBuff': - randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(data.bytes,6)); + randomness = crypto.randomBytes(data.bytes * 4).toString('latin1'); window.postMessage({'cmd': 'randBuff', 'randomness': randomness},'*'); break; case 'debug': @@ -2023,47 +1973,12 @@ function CreatePackage(eventHandler, request) { }); } - if(sjcl.random.isReady(6) == 0) - { - //Set progress to zero to reveal the dialog - myself.eventHandler.raise('sendsafely.entropy.progress', {entropy: 0}); - sjcl.random.addEventListener("seeded", function () { - populateAndSendReturnData(); - }); - sjcl.random.addEventListener("progress", function(evt) { - var entropyPercent = 0; - if(evt != undefined && evt != 1 && !isNaN(evt)) { - entropyPercent = (evt*100); - myself.eventHandler.raise('sendsafely.entropy.progress', {entropy: entropyPercent}); - } else { - myself.eventHandler.raise('sendsafely.entropy.ready', {}); - } - }); - } - else { - populateAndSendReturnData(); - } + populateAndSendReturnData(); }, myself.CREATE_PACKAGE_FAILED); }; this.createKeycode = function(callback) { - if(sjcl.random.isReady(6) == 0) - { - sjcl.random.addEventListener("seeded", function () { - myself.eventHandler.raise('sendsafely.entropy.ready'); - callback(urlSafeBase64(sjcl.codec.base64.fromBits(sjcl.random.randomWords(8,6)))); - }); - sjcl.random.addEventListener("progress", function(evt) { - var entropyPercent = 0; - if(evt != undefined && evt != 1 && !isNaN(evt)) { - entropyPercent = (evt*100); - myself.eventHandler.raise('sendsafely.entropy.progress', {entropy: entropyPercent}); - } - }); - } - else { - callback(urlSafeBase64(sjcl.codec.base64.fromBits(sjcl.random.randomWords(8,6)))); - } + callback(urlSafeBase64(crypto.randomBytes(32).toString('base64'))); } } @@ -2100,16 +2015,12 @@ function DecryptKeycode (eventHandler) { function seedRandomness(privateKey, keyCode, callback) { - var useBlinding = sjcl.random.isReady(6) !== 0; myself.eventHandler.raise('sendsafely.entropy.ready', {}); - decryptKeycode(privateKey, keyCode, useBlinding, callback); + decryptKeycode(privateKey, keyCode, true, callback); } function decryptKeycode(privateKey, keyCode, useBlinding, callback) { - var randomness = []; - if(useBlinding) { - randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(512,6)); - } + var randomness = useBlinding ? crypto.randomBytes(512 * 4).toString('latin1') : []; var messageListener = function (e) { var data = e.data; @@ -2121,7 +2032,7 @@ function DecryptKeycode (eventHandler) { } break; case 'randBuff': - randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(data.bytes,6)); + randomness = crypto.randomBytes(data.bytes * 4).toString('latin1'); window.postMessage({'cmd': 'randBuff', 'randomness': randomness},'*'); break; case 'error': @@ -2152,8 +2063,8 @@ function DecryptMessage (eventHandler) { {'cmd': 'decrypt_message', 'serverSecret': urlSafeBase64(serverSecret), 'keycode': urlSafeBase64(keyCode), - 'salt': sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(2,6)), - 'iv': sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(16,6)), + 'salt': crypto.randomBytes(2 * 4).toString('latin1'), + 'iv': crypto.randomBytes(16 * 4).toString('latin1'), 'message': ciphertext }; @@ -2174,7 +2085,7 @@ function DecryptMessage (eventHandler) { } break; case 'randBuff': - window.postMessage({'cmd': 'randBuff', 'iv': sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(64,6))},'*'); + window.postMessage({'cmd': 'randBuff', 'iv': crypto.randomBytes(64 * 4).toString('latin1')},'*'); break; } }; @@ -2626,7 +2537,7 @@ function DownloadAndDecryptFile (eventHandler, request, serverWorkerURI) { { updateState(fileObj.fileId, fileObj.part, myself.states.DECRYPTING); //var worker = myself.workerPool.getWorker(); - var randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(16,6)); + var randomness = crypto.randomBytes(16 * 4).toString('latin1'); window.postMessage({'cmd': 'decrypt_file', 'decryptionKey': fileObj.fileKey||generateDecryptionKey(fileObj.serverSecret, fileObj.keycode), 'randomness': randomness, @@ -2830,10 +2741,7 @@ function DownloadAndDecryptFile (eventHandler, request, serverWorkerURI) { } function createChecksum(keyCode, packageCode) { - keyCode = sjcl.codec.utf8String.toBits(urlSafeBase64(keyCode)); - packageCode = sjcl.codec.utf8String.toBits(urlSafeBase64(packageCode)); - - return sjcl.codec.hex.fromBits(sjcl.misc.pbkdf2(keyCode, packageCode, 1024, 256)); + return crypto.pbkdf2Sync(urlSafeBase64(keyCode), urlSafeBase64(packageCode), 1024, 32, 'sha256').toString('hex'); } } @@ -3227,7 +3135,7 @@ function EncryptAndUploadFile (eventHandler, request) { this.sendFileToWorker = function (fileObject, packageId, directoryId, fileSize, statusCb, done, nextCb) { function postStartMessage() { - var randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(16,6)); + var randomness = crypto.randomBytes(16 * 4).toString('latin1'); var key = myself.getEncryptionKey(packageId); window.postMessage({'cmd': 'start', @@ -3250,25 +3158,7 @@ function EncryptAndUploadFile (eventHandler, request) { } function sendWorkerFile() { - if(sjcl.random.isReady(6) == 0) - { - sjcl.random.addEventListener("seeded", function () { - myself.eventHandler.raise('sendsafely.entropy.ready'); - postStartMessage(); - }); - sjcl.random.addEventListener("progress", function(evt) { - var entropyPercent = 0; - if(evt != undefined && evt != 1 && !isNaN(evt)) { - entropyPercent = (evt*100); - myself.eventHandler.raise('sendsafely.entropy.progress', {entropy: entropyPercent}); - } else { - myself.eventHandler.raise('sendsafely.entropy.ready'); - } - }); - } - else { - postStartMessage(); - } + postStartMessage(); } var worker = myself.getWorker(statusCb, nextCb, done); @@ -3338,7 +3228,7 @@ function EncryptAndUploadFile (eventHandler, request) { myself.eventHandler.raise(myself.UPLOAD_ERROR_EVENT, {error: data.msg, message: data.debug}); break; case 'randBuff': - window.postMessage({'cmd': 'randBuff', 'iv': sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(64,6))},'*'); + window.postMessage({'cmd': 'randBuff', 'iv': crypto.randomBytes(64 * 4).toString('latin1')},'*'); break; case 'upload': myself.segmentsCurrentlyEncrypting--; @@ -3584,13 +3474,13 @@ function EncryptAndUploadKeycodes(eventHandler, request) { } break; case 'keycode_decrypted': - var randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(1024,6)); + var randomness = crypto.randomBytes(1024 * 4).toString('latin1'); window.postMessage({'cmd': 'encrypt_keycode', 'publicKey': publicKey.key, 'keyCode': data.decryptedKeycode, 'randomness': randomness},'*'); break; } }, false); - var randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(512,6)); + var randomness = crypto.randomBytes(512 * 4).toString('latin1'); window.postMessage({'cmd': 'decrypt_keycode', 'privateKey': privateKey, 'keyCode': keyCode, 'randomness': randomness, useBlinding: useBlinding},'*'); } @@ -3615,7 +3505,7 @@ function EncryptKeycode (eventHandler) { function startWorker(publicKey, keyCode, callback) { - var randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(256,6)); + var randomness = crypto.randomBytes(256 * 4).toString('latin1'); var processMessage = function(e) { var data = e.data; @@ -3628,7 +3518,7 @@ function EncryptKeycode (eventHandler) { } break; case 'randBuff': - randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(data.bytes,6)); + randomness = crypto.randomBytes(data.bytes * 4).toString('latin1'); window.postMessage({'cmd': 'randBuff', 'randomness': randomness},'*'); break; } @@ -3639,25 +3529,8 @@ function EncryptKeycode (eventHandler) { function seedRandomness(publicKey, keyCode, callback) { - if(sjcl.random.isReady(6) == 0) - { - sjcl.random.addEventListener("seeded", function () { - startWorker(publicKey, keyCode, callback); - }); - sjcl.random.addEventListener("progress", function(evt) { - var entropyPercent = 0; - if(evt != undefined && evt != 1 && !isNaN(evt)) { - entropyPercent = (evt*100); - myself.eventHandler.raise('sendsafely.entropy.progress', {entropy: entropyPercent}); - } else { - myself.eventHandler.raise('sendsafely.entropy.ready', {}); - } - }); - } - else { - myself.eventHandler.raise('sendsafely.entropy.ready', {}); - startWorker(publicKey, keyCode, callback); - } + myself.eventHandler.raise('sendsafely.entropy.ready', {}); + startWorker(publicKey, keyCode, callback); } } function EncryptMessage (eventHandler) { @@ -3669,7 +3542,7 @@ function EncryptMessage (eventHandler) { this.execute = function (message, packageId, keyCode, serverSecret, callback) { function postStartMessage() { - var randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(16,6)); + var randomness = crypto.randomBytes(16 * 4).toString('latin1'); message = (message === undefined) ? "" : message; var workerParameters = @@ -3684,25 +3557,7 @@ function EncryptMessage (eventHandler) { } function startWorker() { - if(sjcl.random.isReady(6) == 0) - { - sjcl.random.addEventListener("seeded", function () { - myself.eventHandler.raise('sendsafely.entropy.ready'); - postStartMessage(); - }); - sjcl.random.addEventListener("progress", function(evt) { - var entropyPercent = 0; - if(evt != undefined && evt != 1 && !isNaN(evt)) { - entropyPercent = (evt*100); - myself.eventHandler.raise('sendsafely.entropy.progress', {entropy: entropyPercent}); - } else { - myself.eventHandler.raise('sendsafely.entropy.ready'); - } - }); - } - else { - postStartMessage(); - } + postStartMessage(); } /* myself.messageWorker = undefined; @@ -3730,7 +3585,7 @@ function EncryptMessage (eventHandler) { } break; case 'randBuff': - window.postMessage({'cmd': 'randBuff', 'iv': sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(64,6))},'*'); + window.postMessage({'cmd': 'randBuff', 'iv': crypto.randomBytes(64 * 4).toString('latin1')},'*'); break; } }; @@ -3787,10 +3642,7 @@ function FinalizePackage(eventHandler, request) { }; this.createChecksumFalse = function(keyCode, packageCode) { - keyCode = sjcl.codec.utf8String.toBits(urlSafeBase64(keyCode)); - packageCode = sjcl.codec.utf8String.toBits(urlSafeBase64(packageCode)); - - return sjcl.codec.hex.fromBits(sjcl.misc.pbkdf2(keyCode, packageCode, 1024, 256)); + return crypto.pbkdf2Sync(urlSafeBase64(keyCode), urlSafeBase64(packageCode), 1024, 32, 'sha256').toString('hex'); }; function finalizePackage(packageId, packageCode, keyCode, async, finished) { @@ -3895,29 +3747,12 @@ function GenerateKeyPair(eventHandler) { function seedRandomness(callback) { - if(sjcl.random.isReady(6) == 0) - { - sjcl.random.addEventListener("seeded", function () { - startWorker(callback); - }); - sjcl.random.addEventListener("progress", function(evt) { - var entropyPercent = 0; - if(evt != undefined && evt != 1 && !isNaN(evt)) { - entropyPercent = (evt*100); - myself.eventHandler.raise('sendsafely.entropy.progress', {entropy: entropyPercent}); - } else { - myself.eventHandler.raise('sendsafely.entropy.ready', {}); - } - }); - } - else { - myself.eventHandler.raise('sendsafely.entropy.ready', {}); - startWorker(callback); - } + myself.eventHandler.raise('sendsafely.entropy.ready', {}); + startWorker(callback); } function startWorker(callback) { - var randomness = sjcl.codec.utf8String.fromBits(sjcl.random.randomWords(512,6)); + var randomness = crypto.randomBytes(512 * 4).toString('latin1'); // Create the worker. //var worker = new Worker(myself.serverWorkerURI); @@ -4565,25 +4400,8 @@ function SyncKeycodes (eventHandler, request) { raiseProgressEvent(res.keycodes.length, 0); - if(sjcl.random.isReady(8) == 0) - { - sjcl.random.addEventListener("seeded", function () { - encryptKeycodes(res, privateKey, callback); - }); - sjcl.random.addEventListener("progress", function(evt) { - var entropyPercent = 0; - if(evt != undefined && evt != 1 && !isNaN(evt)) { - entropyPercent = (evt*100); - myself.eventHandler.raise('sendsafely.entropy.progress', {entropy: entropyPercent}); - } else { - myself.eventHandler.raise('sendsafely.entropy.ready', {}); - } - }); - } - else { - myself.eventHandler.raise('sendsafely.entropy.ready', {}); - encryptKeycodes(res, privateKey, callback); - } + myself.eventHandler.raise('sendsafely.entropy.ready', {}); + encryptKeycodes(res, privateKey, callback); }, myself.customErrorEvent); }; @@ -4875,10 +4693,7 @@ function GetPackageMessage (eventHandler, request) { } function createChecksum(keyCode, packageCode) { - keyCode = sjcl.codec.utf8String.toBits(urlSafeBase64(keyCode)); - packageCode = sjcl.codec.utf8String.toBits(urlSafeBase64(packageCode)); - - return sjcl.codec.hex.fromBits(sjcl.misc.pbkdf2(keyCode, packageCode, 1024, 256)); + return crypto.pbkdf2Sync(urlSafeBase64(keyCode), urlSafeBase64(packageCode), 1024, 32, 'sha256').toString('hex'); } } diff --git a/package.json b/package.json index 613c846..000422e 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "jsdom": "^26.0.0", "make-fetch-happen": "^15.0.3", "openpgp": "6.3.0", - "sjcl": "1.0.8", "xmlhttprequest": "^1.8.0" }, "repository": {