diff options
author | Dan Finlay <dan@danfinlay.com> | 2016-10-12 06:09:22 +0800 |
---|---|---|
committer | Dan Finlay <dan@danfinlay.com> | 2016-10-12 06:12:23 +0800 |
commit | ea1a934c7defe7e1b077b675ae9125118f1f3d87 (patch) | |
tree | 27bfe79edeeebf659e6d0f4c0a8cce655c709079 | |
parent | f8b52a3895e0d093f7d831695b56f236a911fb0f (diff) | |
download | tangerine-wallet-browser-ea1a934c7defe7e1b077b675ae9125118f1f3d87.tar tangerine-wallet-browser-ea1a934c7defe7e1b077b675ae9125118f1f3d87.tar.gz tangerine-wallet-browser-ea1a934c7defe7e1b077b675ae9125118f1f3d87.tar.bz2 tangerine-wallet-browser-ea1a934c7defe7e1b077b675ae9125118f1f3d87.tar.lz tangerine-wallet-browser-ea1a934c7defe7e1b077b675ae9125118f1f3d87.tar.xz tangerine-wallet-browser-ea1a934c7defe7e1b077b675ae9125118f1f3d87.tar.zst tangerine-wallet-browser-ea1a934c7defe7e1b077b675ae9125118f1f3d87.zip |
Add initial KeyringController files
-rw-r--r-- | app/scripts/keyring-controller.js | 42 | ||||
-rw-r--r-- | test/unit/keyring-controller-test.js | 141 |
2 files changed, 183 insertions, 0 deletions
diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js new file mode 100644 index 000000000..b61242973 --- /dev/null +++ b/app/scripts/keyring-controller.js @@ -0,0 +1,42 @@ +const scrypt = require('scrypt-async') +const bitcore = require('bitcore-lib') +const configManager = require('./lib/config-manager') + +module.exports = class KeyringController { + + constructor (opts) { + this.configManager = opts.configManager + this.keyChains = [] + } + + getKeyForPassword(password, callback) { + let salt = this.configManager.getSalt() + + if (!salt) { + salt = generateSalt(32) + configManager.setSalt(salt) + } + + var logN = 14 + var r = 8 + var dkLen = 32 + var interruptStep = 200 + + var cb = function(derKey) { + try { + var ui8arr = (new Uint8Array(derKey)) + this.pwDerivedKey = ui8arr + callback(null, ui8arr) + } catch (err) { + callback(err) + } + } + + scrypt(password, salt, logN, r, dkLen, interruptStep, cb, null) + } + +} + +function generateSalt (byteCount) { + return bitcore.crypto.Random.getRandomBuffer(byteCount || 32).toString('base64') +} diff --git a/test/unit/keyring-controller-test.js b/test/unit/keyring-controller-test.js new file mode 100644 index 000000000..854ac5212 --- /dev/null +++ b/test/unit/keyring-controller-test.js @@ -0,0 +1,141 @@ +var assert = require('assert') +var KeyringController = require('../../app/scripts/keyring-controller') +var configManagerGen = require('../lib/mock-config-manager') +const ethUtil = require('ethereumjs-util') +const async = require('async') + +describe('KeyringController', function() { + + describe('#createNewVault', function () { + let keyringController + let password = 'password123' + let entropy = 'entripppppyy duuude' + let seedWords + let accounts = [] + let originalKeystore + + before(function(done) { + window.localStorage = {} // Hacking localStorage support into JSDom + + keyringController = new KeyringController({ + configManager: configManagerGen(), + ethStore: { + addAccount(acct) { accounts.push(ethUtil.addHexPrefix(acct)) }, + }, + }) + + keyringController.createNewVault(password, entropy, (err, seeds) => { + assert.ifError(err, 'createNewVault threw error') + seedWords = seeds + originalKeystore = keyringController._idmgmt.keyStore + done() + }) + }) + + describe('#recoverFromSeed', function() { + let newAccounts = [] + + before(function() { + window.localStorage = {} // Hacking localStorage support into JSDom + + keyringController = new KeyringController({ + configManager: configManagerGen(), + ethStore: { + addAccount(acct) { newAccounts.push(ethUtil.addHexPrefix(acct)) }, + }, + }) + }) + + it('should return the expected keystore', function (done) { + + keyringController.recoverFromSeed(password, seedWords, (err) => { + assert.ifError(err) + + let newKeystore = keyringController._idmgmt.keyStore + assert.equal(newAccounts[0], accounts[0]) + done() + }) + }) + }) + }) + + describe('#recoverFromSeed BIP44 compliance', function() { + const salt = 'lightwalletSalt' + + let password = 'secret!' + let accounts = {} + let keyringController + + var assertions = [ + { + seed: 'picnic injury awful upper eagle junk alert toss flower renew silly vague', + account: '0x5d8de92c205279c10e5669f797b853ccef4f739a', + }, + { + seed: 'radar blur cabbage chef fix engine embark joy scheme fiction master release', + account: '0xe15d894becb0354c501ae69429b05143679f39e0', + }, + { + seed: 'phone coyote caught pattern found table wedding list tumble broccoli chief swing', + account: '0xb0e868f24bc7fec2bce2efc2b1c344d7569cd9d2', + }, + { + seed: 'recycle tag bird palace blue village anxiety census cook soldier example music', + account: '0xab34a45920afe4af212b96ec51232aaa6a33f663', + }, + { + seed: 'half glimpse tape cute harvest sweet bike voyage actual floor poet lazy', + account: '0x28e9044597b625ac4beda7250011670223de43b2', + }, + { + seed: 'flavor tiger carpet motor angry hungry document inquiry large critic usage liar', + account: '0xb571be96558940c4e9292e1999461aa7499fb6cd', + }, + ] + + before(function() { + window.localStorage = {} // Hacking localStorage support into JSDom + + keyringController = new KeyringController({ + configManager: configManagerGen(), + ethStore: { + addAccount(acct) { accounts[acct] = acct}, + del(acct) { delete accounts[acct] }, + }, + }) + }) + + it('should enforce seed compliance with TestRPC', function (done) { + this.timeout(10000) + const tests = assertions.map((assertion) => { + return function (cb) { + + keyringController.recoverFromSeed(password, assertion.seed, (err) => { + assert.ifError(err) + + var expected = assertion.account.toLowerCase() + var received = accounts[expected].toLowerCase() + assert.equal(received, expected) + + keyringController.tryPassword(password, function (err) { + + assert.ok(keyringController._isUnlocked(), 'should unlock the id store') + + keyringController.submitPassword(password, function(err, account) { + assert.ifError(err) + assert.equal(account, expected) + assert.equal(Object.keys(keyringController._getAddresses()).length, 1, 'only one account on restore') + cb() + }) + }) + }) + } + }) + + async.series(tests, function(err, results) { + assert.ifError(err) + done() + }) + }) + }) +}) |