Skip to content

Commit

Permalink
Protect the seed by refactoring the application as two independent pr…
Browse files Browse the repository at this point in the history
…ocesses running on a microkernel.
  • Loading branch information
Empowerful committed Aug 28, 2019
1 parent 1331093 commit def8476
Show file tree
Hide file tree
Showing 172 changed files with 4,583 additions and 2,928 deletions.
2 changes: 2 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
},
"rules": {
"camelcase": 0,
"no-undef": "error",
"no-unused-vars": "warn",
"generator-star-spacing": ["error", {"before": true, "after": true}],
"jest/no-disabled-tests": 1,
"jest/no-focused-tests": 2,
Expand Down
2 changes: 1 addition & 1 deletion config/env/production.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ module.exports = {
ROOT_URL: 'https://blockchain.info',
THE_PIT_URL: 'https://pit.blockchain.com',
WEB_SOCKET_URL: 'wss://ws.blockchain.info',
WALLET_HELPER_DOMAIN: 'https://wallet-helper.blockchain.info',
WALLET_HELPER_DOMAIN: 'https://wallet-helper.blockchain.com',
VERIFF_URL: 'https://magic.veriff.me'
}
1 change: 0 additions & 1 deletion config/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const resolveRoot = relativePath => path.resolve(appDirectory, relativePath)
module.exports = {
appBuild: resolveRoot('lib'),
ciBuild: resolveRoot('dist'),
src: resolveRoot('packages/blockchain-wallet-v4-frontend/src'),
pkgJson: resolveRoot('package.json'),
envConfig: resolveRoot('config/env'),
sslConfig: resolveRoot('config/ssl')
Expand Down
53 changes: 32 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,42 +57,49 @@
]
},
"scripts": {
"analyze": "yarn workspace blockchain-wallet-v4-frontend analyze",
"build": "yarn workspace blockchain-wallet-v4-frontend build:dev",
"build:prod": "yarn workspace blockchain-wallet-v4-frontend build:prod",
"ci:compile": "yarn workspace blockchain-wallet-v4-frontend ci:compile",
"analyze": "cross-env-shell ANALYZE=true NODE_ENV=production webpack-cli --config webpack.config.ci.js",
"build:dev": "cross-env-shell NODE_ENV=development webpack-cli --config webpack.config.dev.js --progress --colors",
"build:prod": "cross-env-shell NODE_ENV=production webpack-cli --config webpack.config.dev.js --progress --colors",
"build:staging": "cross-env-shell NODE_ENV=staging webpack-cli --config webpack.config.dev.js --progress --colors",
"build:testnet": "cross-env-shell NODE_ENV=testnet webpack-cli --config webpack.config.dev.js --progress --colors",
"ci:compile": "cross-env-shell NODE_ENV=production webpack-cli --config webpack.config.ci.js --display-error-details",
"ci:coverage:components": "yarn workspace blockchain-info-components ci:coverage:components",
"ci:coverage:core": "yarn workspace blockchain-wallet-v4 ci:coverage:core",
"ci:coverage:frontend": "yarn workspace blockchain-wallet-v4-frontend ci:coverage:frontend",
"ci:coverage:main-process": "yarn workspace main-process ci:coverage:frontend",
"ci:coverage:security-process": "yarn workspace security-process ci:coverage:frontend",
"ci:coverage:report": "istanbul report --root ./coverage --dir ./coverage/ lcov && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
"ci:lint": "prettier './packages/*/src/**/*.js' --loglevel error --write && eslint './packages/*/src/**/*.js' --fix && stylelint './packages/*/src/**/*.js'",
"ci:test:build": "yarn wsrun test:build --serial",
"ci:test:core:components": "yarn wsrun ci:test --serial --exclude-missing",
"ci:test:frontend": "yarn workspace blockchain-wallet-v4-frontend ci:test:frontend",
"ci:test:main-process": "yarn workspace main-process ci:test:frontend",
"ci:test:security-process": "yarn workspace security-process ci:test:frontend",
"clean": "cross-env yarn wsrun clean && rimraf build && rimraf coverage && rimraf dist && rimraf *.log && rimraf node_modules",
"coverage": "cross-env rimraf coverage && yarn wsrun coverage --fast-exit && istanbul report --root ./coverage --dir ./coverage/ text-summary html",
"coverage:components": "yarn workspace blockchain-info-components coverage",
"coverage:core": "yarn workspace blockchain-wallet-v4 coverage",
"coverage:frontend": "yarn workspace blockchain-wallet-v4-frontend coverage",
"debug:prod": "yarn workspace blockchain-wallet-v4-frontend debug:prod",
"coverage:main-process": "yarn workspace main-process coverage",
"coverage:security-process": "yarn workspace security-process coverage",
"debug:prod": "cross-env-shell NODE_ENV=production webpack-dev-server --config webpack.debug.js --progress --colors",
"fix": "cross-env yarn prettier && yarn lint:fix && yarn test:components:update && yarn test:frontend:update",
"link:resolved:paths": "yarn wsrun link:resolved:paths --exclude-missing",
"lint": "eslint --cache './packages/*/src/**/*.js'",
"lint:components": "eslint './packages/blockchain-info-components/src/**/*.js'",
"lint:core": "eslint './packages/blockchain-wallet-v4/src/**/*.js'",
"lint:css": "stylelint './packages/*/src/**/*.js'",
"lint:fix": "eslint './packages/*/src/**/*.js' --fix",
"lint:frontend": "eslint './packages/blockchain-wallet-v4-frontend/src/**/*.js'",
"manage:translations": "yarn workspace blockchain-wallet-v4-frontend manage:translations",
"lint:main-process": "eslint './packages/main-process/src/**/*.js'",
"lint:security-process": "eslint './packages/security-process/src/**/*.js'",
"manage:translations": "yarn build:prod && node ./translationRunner.js",
"prettier": "prettier './packages/*/src/**/*.js' --loglevel error --write",
"prettier:components": "prettier './packages/blockchain-info-components/src/**/*.js' --list-different --loglevel error --write",
"prettier:core": "prettier './packages/blockchain-wallet-v4/src/**/*.js' --list-different --loglevel error --write",
"prettier:frontend": "prettier './packages/blockchain-wallet-v4-frontend/src/**/*.js' --list-different --loglevel error --write",
"start": "yarn workspace blockchain-wallet-v4-frontend start:dev",
"start:dev": "yarn workspace blockchain-wallet-v4-frontend start:dev",
"start:prod": "yarn workspace blockchain-wallet-v4-frontend start:prod",
"start:staging": "yarn workspace blockchain-wallet-v4-frontend start:staging",
"start:testnet": "yarn workspace blockchain-wallet-v4-frontend start:testnet",
"prettier:main-process": "prettier './packages/main-process/src/**/*.js' --list-different --loglevel error --write",
"prettier:security-process": "prettier './packages/security-process/src/**/*.js' --list-different --loglevel error --write",
"start": "yarn start:dev",
"start:dev": "cross-env-shell NODE_ENV=development webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map",
"start:prod": "cross-env-shell DISABLE_SSL=true NODE_ENV=production webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map",
"start:staging": "cross-env-shell NODE_ENV=staging webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map",
"start:testnet": "cross-env-shell NODE_ENV=testnet webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map",
"storybook:build": "yarn workspace blockchain-info-components storybook:build",
"storybook:serve": "yarn workspace blockchain-info-components storybook:serve",
"storybook:deploy": "yarn workspace blockchain-info-components storybook:build && yarn workspace blockchain-info-components storybook:deploy",
Expand All @@ -104,10 +111,14 @@
"test:core": "yarn workspace blockchain-wallet-v4 test",
"test:core:debug": "yarn workspace blockchain-wallet-v4 test:debug",
"test:core:watch": "yarn workspace blockchain-wallet-v4 test:watch",
"test:frontend": "yarn workspace blockchain-wallet-v4-frontend test",
"test:frontend:debug": "yarn workspace blockchain-wallet-v4-frontend test:debug",
"test:frontend:update": "yarn workspace blockchain-wallet-v4-frontend test:update",
"test:frontend:watch": "yarn workspace blockchain-wallet-v4-frontend test:watch",
"test:main-process": "yarn workspace main-process test",
"test:main-process:debug": "yarn workspace main-process test:debug",
"test:main-process:update": "yarn workspace main-process test:update",
"test:main-process:watch": "yarn workspace main-process test:watch",
"test:security-process": "yarn workspace security-process test",
"test:security-process:debug": "yarn workspace security-process test:debug",
"test:security-process:update": "yarn workspace security-process test:update",
"test:security-process:watch": "yarn workspace security-process test:watch",
"release": "release-it"
},
"dependencies": {
Expand Down Expand Up @@ -166,7 +177,7 @@
"express": "4.16.4",
"file-loader": "3.0.1",
"generate-changelog": "1.7.1",
"html-webpack-plugin": "3.2.0",
"html-webpack-plugin": "4.0.0-beta.8",
"husky": "2.3.0",
"identity-obj-proxy": "3.0.0",
"istanbul": "github:Xesenix/istanbul",
Expand Down
114 changes: 114 additions & 0 deletions packages/blockchain-wallet-v4/src/SecurityModule/core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
export default ({ BIP39, Bitcoin, crypto, ed25519, EthHd, taskToPromise }) => {
const computeSecondPasswordHash = ({ iterations, sharedKey }, password) =>
crypto.hashNTimes(iterations, sharedKey + password).toString(`hex`)

const credentialsEntropy = ({ guid, password, sharedKey }) =>
crypto.sha256(Buffer.from(guid + sharedKey + password))

const verifySecondPassword = (
{ iterations, sharedKey, storedHash },
password
) => {
const computedHash = computeSecondPasswordHash(
{ iterations, sharedKey },
password
)

return computedHash === storedHash
}

const decryptWithSecondPassword = async (
{ iterations, secondPassword, sharedKey, storedHash },
cipherText
) => {
if (
verifySecondPassword(
{ iterations, sharedKey, storedHash },
secondPassword
)
) {
return taskToPromise(
crypto.decryptSecPass(sharedKey, iterations, secondPassword, cipherText)
)
} else {
throw new Error('INVALID_SECOND_PASSWORD')
}
}

const getSeedEntropy = ({
iterations,
secondPassword,
secondPasswordHash,
seedHex,
sharedKey
}) =>
secondPassword
? decryptWithSecondPassword(
{
iterations,
secondPassword,
sharedKey,
storedHash: secondPasswordHash
},
seedHex
)
: seedHex

const entropyToSeed = entropy =>
BIP39.mnemonicToSeed(BIP39.entropyToMnemonic(entropy))

const getSeed = async credentials =>
entropyToSeed(await getSeedEntropy(credentials))

const deriveBIP32KeyFromSeedHex = async (
{
iterations,
network,
secondPassword,
secondPasswordHash,
seedHex,
sharedKey
},
path
) => {
const seed = await getSeed({
iterations,
secondPassword,
secondPasswordHash,
seedHex,
sharedKey
})

return Bitcoin.HDNode.fromSeedBuffer(seed, network)
.derivePath(path)
.toBase58()
}

// Derivation error using seedHex directly instead of seed derived from
// mnemonic derived from seedHex
const deriveLegacyEthereumKey = async credentials => {
const entropy = await getSeedEntropy(credentials)

return EthHd.fromMasterSeed(entropy)
.derivePath(`m/44'/60'/0'/0/0`)
.getWallet()
.getPrivateKey()
}

const deriveSLIP10ed25519Key = async (credentials, path) => {
const seed = await getSeed(credentials)
return ed25519.derivePath(path, seed.toString(`hex`))
}

return {
computeSecondPasswordHash,
credentialsEntropy,
decryptWithSecondPassword,
deriveBIP32KeyFromSeedHex,
deriveLegacyEthereumKey,
deriveSLIP10ed25519Key,
entropyToSeed,
getSeedEntropy,
verifySecondPassword
}
}

0 comments on commit def8476

Please sign in to comment.