From ab9e15b782620002c0a2477829db3e56a25a7d5c Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 8 Dec 2016 14:22:02 -0800 Subject: Mostly added bad account detection Currently riddled with logs, because the migrator is inexplicably returning before generating the new style accounts for comparison. --- app/scripts/lib/config-manager.js | 12 ++++++++ app/scripts/lib/idStore-migrator.js | 55 +++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 6 deletions(-) (limited to 'app/scripts/lib') diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js index 59cc2b63c..efc0b4628 100644 --- a/app/scripts/lib/config-manager.js +++ b/app/scripts/lib/config-manager.js @@ -432,3 +432,15 @@ ConfigManager.prototype.setGasMultiplier = function (gasMultiplier) { data.gasMultiplier = gasMultiplier this.setData(data) } + +ConfigManager.prototype.setLostAccounts = function (lostAccounts) { + var data = this.getData() + data.lostAccounts = lostAccounts + this.setData(data) +} + +ConfigManager.prototype.getLostAccounts = function () { + var data = this.getData() + return ('lostAccounts' in data) && data.lostAccounts || [] +} + diff --git a/app/scripts/lib/idStore-migrator.js b/app/scripts/lib/idStore-migrator.js index 40b08efee..c13015b96 100644 --- a/app/scripts/lib/idStore-migrator.js +++ b/app/scripts/lib/idStore-migrator.js @@ -1,5 +1,7 @@ const IdentityStore = require('./idStore') - +const HdKeyring = require('../keyrings/hd') +const sigUtil = require('./sig-util') +const normalize = sigUtil.normalize module.exports = class IdentityStoreMigrator { @@ -12,25 +14,34 @@ module.exports = class IdentityStoreMigrator { } migratedVaultForPassword (password) { + console.log('migrating vault for password') const hasOldVault = this.hasOldVault() const configManager = this.configManager if (!this.idStore) { + console.log('initializing id store') this.idStore = new IdentityStore({ configManager }) + console.log('initialized') } if (!hasOldVault) { + console.log('no old vault recognized') return Promise.resolve(null) } + console.log('returning new promise') return new Promise((resolve, reject) => { + console.log('submitting password to idStore') this.idStore.submitPassword(password, (err) => { + console.log('returned ' + err) if (err) return reject(err) - try { - resolve(this.serializeVault()) - } catch (e) { - reject(e) - } + console.log('serializing vault') + const serialized = this.serializeVault() + console.log('migrated and serialized into') + console.dir(serialized) + this.checkForErrors(serialized) + .then(resolve) + .catch(reject) }) }) } @@ -45,6 +56,38 @@ module.exports = class IdentityStoreMigrator { } } + checkForErrors (serialized) { + console.log('checking for errors, first making hd wallet') + const hd = new HdKeyring() + return hd.deserialize(serialized) + .then(() => { + console.log('deserialized, now getting accounts') + console.dir(arguments) + return hd.getAccounts() + }) + .then((hexAccounts) => { + console.log('hd returned accounts', hexAccounts) + const newAccounts = hexAccounts.map(normalize) + const oldAccounts = this.idStore._getAddresses().map(normalize) + const lostAccounts = oldAccounts.reduce((result, account) => { + if (newAccounts.includes(account)) { + return result + } else { + result.push(account) + return result + } + }, []) + + console.log('migrator has') + console.dir({ newAccounts, oldAccounts, lostAccounts, hexAccounts }) + + return { + serialized, + lostAccounts, + } + }) + } + hasOldVault () { const wallet = this.configManager.getWallet() return wallet -- cgit From 7b9749e30c4f8228fe62c1ad81515117cf7504bc Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 9 Dec 2016 12:24:25 -0800 Subject: Got bad account detection working and added to state --- app/scripts/lib/idStore-migrator.js | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'app/scripts/lib') diff --git a/app/scripts/lib/idStore-migrator.js b/app/scripts/lib/idStore-migrator.js index c13015b96..14bd0d8b8 100644 --- a/app/scripts/lib/idStore-migrator.js +++ b/app/scripts/lib/idStore-migrator.js @@ -14,31 +14,21 @@ module.exports = class IdentityStoreMigrator { } migratedVaultForPassword (password) { - console.log('migrating vault for password') const hasOldVault = this.hasOldVault() const configManager = this.configManager if (!this.idStore) { - console.log('initializing id store') this.idStore = new IdentityStore({ configManager }) - console.log('initialized') } if (!hasOldVault) { - console.log('no old vault recognized') return Promise.resolve(null) } - console.log('returning new promise') return new Promise((resolve, reject) => { - console.log('submitting password to idStore') this.idStore.submitPassword(password, (err) => { - console.log('returned ' + err) if (err) return reject(err) - console.log('serializing vault') const serialized = this.serializeVault() - console.log('migrated and serialized into') - console.dir(serialized) this.checkForErrors(serialized) .then(resolve) .catch(reject) @@ -57,16 +47,9 @@ module.exports = class IdentityStoreMigrator { } checkForErrors (serialized) { - console.log('checking for errors, first making hd wallet') const hd = new HdKeyring() - return hd.deserialize(serialized) - .then(() => { - console.log('deserialized, now getting accounts') - console.dir(arguments) - return hd.getAccounts() - }) + return hd.deserialize(serialized.data) .then((hexAccounts) => { - console.log('hd returned accounts', hexAccounts) const newAccounts = hexAccounts.map(normalize) const oldAccounts = this.idStore._getAddresses().map(normalize) const lostAccounts = oldAccounts.reduce((result, account) => { @@ -78,9 +61,6 @@ module.exports = class IdentityStoreMigrator { } }, []) - console.log('migrator has') - console.dir({ newAccounts, oldAccounts, lostAccounts, hexAccounts }) - return { serialized, lostAccounts, -- cgit From e9bea92ac3243e58321cd8cf3f44f0df0c66aa70 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Mon, 19 Dec 2016 14:55:52 -0800 Subject: Lint. --- app/scripts/lib/idStore.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/scripts/lib') diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js index d36504f13..cf4353e48 100644 --- a/app/scripts/lib/idStore.js +++ b/app/scripts/lib/idStore.js @@ -258,7 +258,7 @@ IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDone function estimateGas (cb) { var estimationParams = extend(txParams) - query.getBlockByNumber('latest', true, function(err, block){ + query.getBlockByNumber('latest', true, function (err, block) { if (err) return cb(err) // check if gasLimit is already specified const gasLimitSpecified = Boolean(txParams.gas) @@ -267,7 +267,7 @@ IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDone estimationParams.gas = block.gasLimit } // run tx, see if it will OOG - query.estimateGas(estimationParams, function(err, estimatedGasHex){ + query.estimateGas(estimationParams, function (err, estimatedGasHex) { if (err) return cb(err.message || err) // all gas used - must be an error if (estimatedGasHex === estimationParams.gas) { -- cgit From 20d2204ce6a9e8dcd3269c588b2f4ce6ff93408b Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 19 Dec 2016 16:29:44 -0800 Subject: Made changes according to feedback. --- app/scripts/lib/config-manager.js | 3 +-- app/scripts/lib/idStore-migrator.js | 18 +++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'app/scripts/lib') diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js index efc0b4628..d36ccf0db 100644 --- a/app/scripts/lib/config-manager.js +++ b/app/scripts/lib/config-manager.js @@ -441,6 +441,5 @@ ConfigManager.prototype.setLostAccounts = function (lostAccounts) { ConfigManager.prototype.getLostAccounts = function () { var data = this.getData() - return ('lostAccounts' in data) && data.lostAccounts || [] + return data.lostAccounts || [] } - diff --git a/app/scripts/lib/idStore-migrator.js b/app/scripts/lib/idStore-migrator.js index 14bd0d8b8..2e9418376 100644 --- a/app/scripts/lib/idStore-migrator.js +++ b/app/scripts/lib/idStore-migrator.js @@ -2,6 +2,7 @@ const IdentityStore = require('./idStore') const HdKeyring = require('../keyrings/hd') const sigUtil = require('./sig-util') const normalize = sigUtil.normalize +const denodeify = require('denodeify') module.exports = class IdentityStoreMigrator { @@ -25,14 +26,13 @@ module.exports = class IdentityStoreMigrator { return Promise.resolve(null) } - return new Promise((resolve, reject) => { - this.idStore.submitPassword(password, (err) => { - if (err) return reject(err) - const serialized = this.serializeVault() - this.checkForErrors(serialized) - .then(resolve) - .catch(reject) - }) + const idStore = this.idStore + const submitPassword = denodeify(idStore.submitPassword.bind(idStore)) + + return submitPassword(password) + .then(() => { + const serialized = this.serializeVault() + return this.checkForLostAccounts(serialized) }) } @@ -46,7 +46,7 @@ module.exports = class IdentityStoreMigrator { } } - checkForErrors (serialized) { + checkForLostAccounts (serialized) { const hd = new HdKeyring() return hd.deserialize(serialized.data) .then((hexAccounts) => { -- cgit From 26f1e6cbd2af9d6bb0c58871635466c459cc87d8 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 19 Dec 2016 21:55:02 -0800 Subject: Remove encryptor in favor of external browser-passworder I broke out the encryptor lib into its own module on npm called browser-passworder. --- app/scripts/lib/encryptor.js | 156 ------------------------------------------- 1 file changed, 156 deletions(-) delete mode 100644 app/scripts/lib/encryptor.js (limited to 'app/scripts/lib') diff --git a/app/scripts/lib/encryptor.js b/app/scripts/lib/encryptor.js deleted file mode 100644 index 4770d2f54..000000000 --- a/app/scripts/lib/encryptor.js +++ /dev/null @@ -1,156 +0,0 @@ -module.exports = { - - // Simple encryption methods: - encrypt, - decrypt, - - // More advanced encryption methods: - keyFromPassword, - encryptWithKey, - decryptWithKey, - - // Buffer <-> String methods - convertArrayBufferViewtoString, - convertStringToArrayBufferView, - - // Buffer <-> Hex string methods - serializeBufferForStorage, - serializeBufferFromStorage, - - // Buffer <-> base64 string methods - encodeBufferToBase64, - decodeBase64ToBuffer, - - generateSalt, -} - -// Takes a Pojo, returns cypher text. -function encrypt (password, dataObj) { - const salt = this.generateSalt() - - return keyFromPassword(password + salt) - .then(function (passwordDerivedKey) { - return encryptWithKey(passwordDerivedKey, dataObj) - }) - .then(function (payload) { - payload.salt = salt - return JSON.stringify(payload) - }) -} - -function encryptWithKey (key, dataObj) { - var data = JSON.stringify(dataObj) - var dataBuffer = convertStringToArrayBufferView(data) - var vector = global.crypto.getRandomValues(new Uint8Array(16)) - return global.crypto.subtle.encrypt({ - name: 'AES-GCM', - iv: vector, - }, key, dataBuffer).then(function (buf) { - var buffer = new Uint8Array(buf) - var vectorStr = encodeBufferToBase64(vector) - var vaultStr = encodeBufferToBase64(buffer) - return { - data: vaultStr, - iv: vectorStr, - } - }) -} - -// Takes encrypted text, returns the restored Pojo. -function decrypt (password, text) { - const payload = JSON.parse(text) - const salt = payload.salt - return keyFromPassword(password + salt) - .then(function (key) { - return decryptWithKey(key, payload) - }) -} - -function decryptWithKey (key, payload) { - const encryptedData = decodeBase64ToBuffer(payload.data) - const vector = decodeBase64ToBuffer(payload.iv) - return crypto.subtle.decrypt({name: 'AES-GCM', iv: vector}, key, encryptedData) - .then(function (result) { - const decryptedData = new Uint8Array(result) - const decryptedStr = convertArrayBufferViewtoString(decryptedData) - const decryptedObj = JSON.parse(decryptedStr) - return decryptedObj - }) - .catch(function (reason) { - throw new Error('Incorrect password') - }) -} - -function convertStringToArrayBufferView (str) { - var bytes = new Uint8Array(str.length) - for (var i = 0; i < str.length; i++) { - bytes[i] = str.charCodeAt(i) - } - - return bytes -} - -function convertArrayBufferViewtoString (buffer) { - var str = '' - for (var i = 0; i < buffer.byteLength; i++) { - str += String.fromCharCode(buffer[i]) - } - - return str -} - -function keyFromPassword (password) { - var passBuffer = convertStringToArrayBufferView(password) - return global.crypto.subtle.digest('SHA-256', passBuffer) - .then(function (passHash) { - return global.crypto.subtle.importKey('raw', passHash, {name: 'AES-GCM'}, false, ['encrypt', 'decrypt']) - }) -} - -function serializeBufferFromStorage (str) { - var stripStr = (str.slice(0, 2) === '0x') ? str.slice(2) : str - var buf = new Uint8Array(stripStr.length / 2) - for (var i = 0; i < stripStr.length; i += 2) { - var seg = stripStr.substr(i, 2) - buf[i / 2] = parseInt(seg, 16) - } - return buf -} - -// Should return a string, ready for storage, in hex format. -function serializeBufferForStorage (buffer) { - var result = '0x' - var len = buffer.length || buffer.byteLength - for (var i = 0; i < len; i++) { - result += unprefixedHex(buffer[i]) - } - return result -} - -function unprefixedHex (num) { - var hex = num.toString(16) - while (hex.length < 2) { - hex = '0' + hex - } - return hex -} - -function encodeBufferToBase64 (buf) { - var b64encoded = btoa(String.fromCharCode.apply(null, buf)) - return b64encoded -} - -function decodeBase64ToBuffer (base64) { - var buf = new Uint8Array(atob(base64).split('') - .map(function (c) { - return c.charCodeAt(0) - })) - return buf -} - -function generateSalt (byteCount = 32) { - var view = new Uint8Array(byteCount) - global.crypto.getRandomValues(view) - var b64encoded = btoa(String.fromCharCode.apply(null, view)) - return b64encoded -} -- cgit