1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Remove unneeded Edge-specific encryption code (#7683)

This commit is contained in:
Whymarrh Whitby 2019-12-10 16:34:50 -03:30 committed by GitHub
parent c8d8d8d93d
commit 34b674c3d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 0 additions and 210 deletions

View File

@ -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
},

View File

@ -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<string>} 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<Object>} 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<Object>} 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

View File

@ -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",

View File

@ -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)
})
})
})
})