diff --git a/app/scripts/background.js b/app/scripts/background.js index b58be5ebf..c5dc0cea6 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -29,7 +29,6 @@ const rawFirstTimeState = require('./first-time-state') const setupSentry = require('./lib/setupSentry') const reportFailedTxToSentry = require('./lib/reportFailedTxToSentry') const setupMetamaskMeshMetrics = require('./lib/setupMetamaskMeshMetrics') -const EdgeEncryptor = require('./edge-encryptor') const getFirstPreferredLangCode = require('./lib/get-first-preferred-lang-code') const getObjStructure = require('./lib/getObjStructure') const setupEnsIpfsResolver = require('./lib/ens-ipfs/setup') @@ -55,12 +54,6 @@ global.METAMASK_NOTIFIER = notificationManager const release = platform.getVersion() const sentry = setupSentry({ release }) -// browser check if it is Edge - https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser -// Internet Explorer 6-11 -const isIE = !!document.documentMode -// Edge 20+ -const isEdge = !isIE && !!window.StyleMedia - let popupIsOpen = false let notificationIsOpen = false const openMetamaskTabsIDs = {} @@ -247,7 +240,6 @@ function setupController (initState, initLangCode) { initLangCode, // platform specific api platform, - encryptor: isEdge ? new EdgeEncryptor() : undefined, getRequestAccountTabIds: () => { return requestAccountTabIds }, diff --git a/app/scripts/edge-encryptor.js b/app/scripts/edge-encryptor.js deleted file mode 100644 index d086a854d..000000000 --- a/app/scripts/edge-encryptor.js +++ /dev/null @@ -1,99 +0,0 @@ -const asmcrypto = require('asmcrypto.js') -const Unibabel = require('browserify-unibabel') - -/** - * A Microsoft Edge-specific encryption class that exposes - * the interface expected by eth-keykeyring-controller - */ -class EdgeEncryptor { - /** - * Encrypts an arbitrary object to ciphertext - * - * @param {string} password Used to generate a key to encrypt the data - * @param {Object} dataObject Data to encrypt - * @returns {Promise} Promise resolving to an object with ciphertext - */ - encrypt (password, dataObject) { - const salt = this._generateSalt() - return this._keyFromPassword(password, salt) - .then(function (key) { - const data = JSON.stringify(dataObject) - const dataBuffer = Unibabel.utf8ToBuffer(data) - const vector = global.crypto.getRandomValues(new Uint8Array(16)) - const resultbuffer = asmcrypto.AES_GCM.encrypt(dataBuffer, key, vector) - - const buffer = new Uint8Array(resultbuffer) - const vectorStr = Unibabel.bufferToBase64(vector) - const vaultStr = Unibabel.bufferToBase64(buffer) - return JSON.stringify({ - data: vaultStr, - iv: vectorStr, - salt: salt, - }) - }) - } - - /** - * Decrypts an arbitrary object from ciphertext - * - * @param {string} password Used to generate a key to decrypt the data - * @param {string} text Ciphertext of an encrypted object - * @returns {Promise} Promise resolving to copy of decrypted object - */ - decrypt (password, text) { - const payload = JSON.parse(text) - const salt = payload.salt - return this._keyFromPassword(password, salt) - .then(function (key) { - const encryptedData = Unibabel.base64ToBuffer(payload.data) - const vector = Unibabel.base64ToBuffer(payload.iv) - return new Promise((resolve, reject) => { - let result - try { - result = asmcrypto.AES_GCM.decrypt(encryptedData, key, vector) - } catch (err) { - return reject(new Error('Incorrect password')) - } - const decryptedData = new Uint8Array(result) - const decryptedStr = Unibabel.bufferToUtf8(decryptedData) - const decryptedObj = JSON.parse(decryptedStr) - resolve(decryptedObj) - }) - }) - } - - /** - * Retrieves a cryptographic key using a password - * - * @private - * @param {string} password Password used to unlock a cryptographic key - * @param {string} salt Random base64 data - * @returns {Promise} Promise resolving to a derived key - */ - _keyFromPassword (password, salt) { - - const passBuffer = Unibabel.utf8ToBuffer(password) - const saltBuffer = Unibabel.base64ToBuffer(salt) - const iterations = 10000 - const length = 32 // SHA256 hash size - return new Promise((resolve) => { - const key = asmcrypto.Pbkdf2HmacSha256(passBuffer, saltBuffer, iterations, length) - resolve(key) - }) - } - - /** - * Generates random base64 encoded data - * - * @private - * @returns {string} Randomized base64 encoded data - */ - _generateSalt (byteCount = 32) { - const view = new Uint8Array(byteCount) - global.crypto.getRandomValues(view) - const b64encoded = btoa(String.fromCharCode.apply(null, view)) - return b64encoded - } -} - -module.exports = EdgeEncryptor diff --git a/package.json b/package.json index 89035b832..6a5b8ad58 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "@zxing/library": "^0.8.0", "abi-decoder": "^1.2.0", "abortcontroller-polyfill": "^1.3.0", - "asmcrypto.js": "^2.3.2", "await-semaphore": "^0.1.1", "bignumber.js": "^4.1.0", "bip39": "^2.2.0", @@ -73,7 +72,6 @@ "bn.js": "^4.11.7", "browser-passworder": "^2.0.3", "browserify-derequire": "^0.9.4", - "browserify-unibabel": "^3.0.0", "c3": "^0.6.7", "classnames": "^2.2.5", "clone": "^2.1.2", diff --git a/test/unit/app/edge-encryptor-test.js b/test/unit/app/edge-encryptor-test.js deleted file mode 100644 index 3f2e8830a..000000000 --- a/test/unit/app/edge-encryptor-test.js +++ /dev/null @@ -1,101 +0,0 @@ -const assert = require('assert') - -const EdgeEncryptor = require('../../../app/scripts/edge-encryptor') - -const password = 'passw0rd1' -const data = 'some random data' - -global.crypto = global.crypto || { - getRandomValues: function (array) { - for (let i = 0; i < array.length; i++) { - array[i] = Math.random() * 100 - } - return array - }, -} - -describe('EdgeEncryptor', function () { - - const edgeEncryptor = new EdgeEncryptor() - describe('encrypt', function () { - - it('should encrypt the data.', function (done) { - edgeEncryptor.encrypt(password, data) - .then(function (encryptedData) { - assert.notEqual(data, encryptedData) - assert.notEqual(encryptedData.length, 0) - done() - }).catch(function (err) { - done(err) - }) - }) - - it('should return proper format.', function (done) { - edgeEncryptor.encrypt(password, data) - .then(function (encryptedData) { - const encryptedObject = JSON.parse(encryptedData) - assert.ok(encryptedObject.data, 'there is no data') - assert.ok(encryptedObject.iv && encryptedObject.iv.length !== 0, 'there is no iv') - assert.ok(encryptedObject.salt && encryptedObject.salt.length !== 0, 'there is no salt') - done() - }).catch(function (err) { - done(err) - }) - }) - - it('should not return the same twice.', function (done) { - - const encryptPromises = [] - encryptPromises.push(edgeEncryptor.encrypt(password, data)) - encryptPromises.push(edgeEncryptor.encrypt(password, data)) - - Promise.all(encryptPromises).then((encryptedData) => { - assert.equal(encryptedData.length, 2) - assert.notEqual(encryptedData[0], encryptedData[1]) - assert.notEqual(encryptedData[0].length, 0) - assert.notEqual(encryptedData[1].length, 0) - done() - }) - }) - }) - - describe('decrypt', function () { - it('should be able to decrypt the encrypted data.', function (done) { - - edgeEncryptor.encrypt(password, data) - .then(function (encryptedData) { - edgeEncryptor.decrypt(password, encryptedData) - .then(function (decryptedData) { - assert.equal(decryptedData, data) - done() - }) - .catch(function (err) { - done(err) - }) - }) - .catch(function (err) { - done(err) - }) - }) - - it('cannot decrypt the encrypted data with wrong password.', function (done) { - - edgeEncryptor.encrypt(password, data) - .then(function (encryptedData) { - edgeEncryptor.decrypt('wrong password', encryptedData) - .then(function () { - assert.fail('could decrypt with wrong password') - done() - }) - .catch(function (err) { - assert.ok(err instanceof Error) - assert.equal(err.message, 'Incorrect password') - done() - }) - }) - .catch(function (err) { - done(err) - }) - }) - }) -})