From ba34af0dd45fa256cef59ba640a7eff524dcfef4 Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Wed, 2 Oct 2019 15:01:19 +0200 Subject: [PATCH] [Fixes #9088] Store eip1581 path and wallet root path, don't store master key When creating the account we store as well the path specified in eip1581 https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1581.md , `m / 43' / 60' / 1581'`. The reason for doing so is that eventually we might want to derive an encryption key from it, which would require the user to re-enter their seed phrase if we would not store this. This commit changes the behavior not to store the master key, and instead store `m /44'/60' /0'/0`, from which wallets are now derived. Signed-off-by: Andrea Maria Piana --- src/status_im/constants.cljs | 13 +++++-- src/status_im/multiaccounts/create/core.cljs | 39 +++++++++++-------- src/status_im/multiaccounts/recover/core.cljs | 5 ++- src/status_im/wallet/accounts/core.cljs | 39 ++++++++++++------- 4 files changed, 60 insertions(+), 36 deletions(-) diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index 57366f34b7..c7c90b580e 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -237,12 +237,19 @@ (def ^:const status-create-address "status_createaddress") -(def ^:const path-root "m/44'/60'/0'/0") -(def ^:const path-default-wallet "m/44'/60'/0'/0/0") -(def ^:const path-whisper "m/43'/60'/1581'/0'/0") +; BIP44 Wallet Root Key, the extended key from which any wallet can be derived +(def ^:const path-wallet-root "m/44'/60'/0'/0") +; EIP1581 Root Key, the extended key from which any whisper key/encryption key can be derived +(def ^:const path-eip1581 "m/43'/60'/1581'") +; BIP44-0 Wallet key, the default wallet key +(def ^:const path-default-wallet (str path-wallet-root "/0")) +; EIP1581 Chat Key 0, the default whisper key +(def ^:const path-whisper (str path-eip1581 "/0'/0")) (def ^:const path-default-wallet-keyword (keyword path-default-wallet)) (def ^:const path-whisper-keyword (keyword path-whisper)) +(def ^:const path-wallet-root-keyword (keyword path-wallet-root)) +(def ^:const path-eip1581-keyword (keyword path-eip1581)) ;; (ethereum/sha3 "Transfer(address,address,uint256)") (def ^:const event-transfer-hash "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") diff --git a/src/status_im/multiaccounts/create/core.cljs b/src/status_im/multiaccounts/create/core.cljs index 104774ca15..afa8c63e95 100644 --- a/src/status_im/multiaccounts/create/core.cljs +++ b/src/status_im/multiaccounts/create/core.cljs @@ -52,7 +52,7 @@ (let [{:keys [selected-id address key-code]} (:intro-wizard db) {:keys [address]} (get-selected-multiaccount cofx) hashed-password (ethereum/sha3 (security/safe-unmask-data key-code)) - callback #(re-frame/dispatch [::store-multiaccount-success key-code])] + callback #(re-frame/dispatch [::store-multiaccount-success key-code %])] {::store-multiaccount [selected-id address hashed-password callback]})) (fx/defn intro-wizard @@ -184,11 +184,16 @@ name (gfycat/generate-gfy publicKey) photo-path (identicon/identicon publicKey) multiaccount-data {:name name :address address :photo-path photo-path} - new-multiaccount (cond-> {:address address + new-multiaccount (cond-> {; address of the master key + :address address + ;; The address from which we derive any wallet + :wallet-root-address (get-in multiaccount [:derived constants/path-wallet-root-keyword :address]) + ;; The address from which we derive any chat account/encryption keys + :eip1581-address (get-in multiaccount [:derived constants/path-eip1581-keyword :address]) :name name :photo-path photo-path + ; public key of the chat account :public-key publicKey - :latest-derived-path 0 :accounts [wallet-account] :signing-phrase signing-phrase @@ -296,26 +301,26 @@ {:events [::store-multiaccount-success] :interceptors [(re-frame/inject-cofx :random-guid-generator) (re-frame/inject-cofx ::get-signing-phrase)]} - [cofx password] - (on-multiaccount-created cofx (get-selected-multiaccount cofx) password {:seed-backed-up? false})) + [cofx password derived] + (on-multiaccount-created cofx + (assoc + (get-selected-multiaccount cofx) + :derived + (types/json->clj derived)) + password + {:seed-backed-up? false})) (re-frame/reg-fx ::store-multiaccount (fn [[id address hashed-password callback]] - (status/multiaccount-store-account + (status/multiaccount-store-derived id + [constants/path-wallet-root + constants/path-eip1581 + constants/path-whisper + constants/path-default-wallet] hashed-password - (fn [] - (status/multiaccount-load-account - address - hashed-password - (fn [value] - (let [{:keys [id]} (types/json->clj value)] - (status/multiaccount-store-derived - id - [constants/path-whisper constants/path-default-wallet] - hashed-password - callback)))))))) + callback))) (re-frame/reg-fx ::save-account-and-login diff --git a/src/status_im/multiaccounts/recover/core.cljs b/src/status_im/multiaccounts/recover/core.cljs index 04520f8c99..7ce0a24cba 100644 --- a/src/status_im/multiaccounts/recover/core.cljs +++ b/src/status_im/multiaccounts/recover/core.cljs @@ -127,7 +127,10 @@ (let [{:keys [id] :as root-data} (types/json->clj result)] (status-im.native-module.core/multiaccount-derive-addresses id - [constants/path-default-wallet constants/path-whisper] + [constants/path-wallet-root + constants/path-eip1581 + constants/path-whisper + constants/path-default-wallet] (fn [result] (let [derived-data (types/json->clj result)] (re-frame/dispatch [::import-multiaccount-success diff --git a/src/status_im/wallet/accounts/core.cljs b/src/status_im/wallet/accounts/core.cljs index fcb1bf56e9..ea7914c64f 100644 --- a/src/status_im/wallet/accounts/core.cljs +++ b/src/status_im/wallet/accounts/core.cljs @@ -21,15 +21,15 @@ (re-frame/reg-fx ::generate-account - (fn [{:keys [address hashed-password path-num]}] - (status/multiaccount-load-account - address - hashed-password - (fn [value] - (let [{:keys [id error]} (types/json->clj value)] - (if error - (re-frame/dispatch [::generate-new-account-error]) - (let [path (str constants/path-root "/" path-num)] + (fn [{:keys [derivation-info hashed-password path-num]}] + (let [{:keys [address path]} derivation-info] + (status/multiaccount-load-account + address + hashed-password + (fn [value] + (let [{:keys [id error]} (types/json->clj value)] + (if error + (re-frame/dispatch [::generate-new-account-error]) (status/multiaccount-derive-addresses id [path] @@ -45,7 +45,7 @@ {:name (str "Account " path-num) :address address :public-key public-key - :path path + :path (str constants/path-wallet-root "/" path-num) :color (rand-nth colors/account-colors)}]))))))))))))) (fx/defn set-symbol-request @@ -56,11 +56,20 @@ (fx/defn generate-new-account {:events [:wallet.accounts/generate-new-account]} [{:keys [db]} password] - (when-not (get-in db [:generate-account :step]) - {:db (assoc-in db [:generate-account :step] :generating) - ::generate-account {:address (get-in db [:multiaccount :address]) - :path-num (inc (get-in db [:multiaccount :latest-derived-path])) - :hashed-password (ethereum/sha3 password)}})) + (let [wallet-root-address (get-in db [:multiaccount :wallet-root-address]) + path-num (inc (get-in db [:multiaccount :latest-derived-path]))] + (when-not (get-in db [:generate-account :step]) + {:db (assoc-in db [:generate-account :step] :generating) + ::generate-account {:derivation-info (if wallet-root-address + ;; Use the walllet-root-address for stored on disk keys + ;; This needs to be the RELATIVE path to the key used to derive + {:path (str "m/" path-num) + :address wallet-root-address} + ;; Fallback on the master account for keycards, use the absolute path + {:path (str constants/path-wallet-root "/" path-num) + :address (get-in db [:multiaccount :address])}) + :path-num path-num + :hashed-password (ethereum/sha3 password)}}))) (fx/defn generate-new-account-error {:events [::generate-new-account-error]}