[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 <andrea.maria.piana@gmail.com>
This commit is contained in:
Andrea Maria Piana 2019-10-02 15:01:19 +02:00
parent b3d04bb68c
commit ba34af0dd4
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
4 changed files with 60 additions and 36 deletions

View File

@ -237,12 +237,19 @@
(def ^:const status-create-address "status_createaddress") (def ^:const status-create-address "status_createaddress")
(def ^:const path-root "m/44'/60'/0'/0") ; BIP44 Wallet Root Key, the extended key from which any wallet can be derived
(def ^:const path-default-wallet "m/44'/60'/0'/0/0") (def ^:const path-wallet-root "m/44'/60'/0'/0")
(def ^:const path-whisper "m/43'/60'/1581'/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-default-wallet-keyword (keyword path-default-wallet))
(def ^:const path-whisper-keyword (keyword path-whisper)) (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)") ;; (ethereum/sha3 "Transfer(address,address,uint256)")
(def ^:const event-transfer-hash "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") (def ^:const event-transfer-hash "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")

View File

@ -52,7 +52,7 @@
(let [{:keys [selected-id address key-code]} (:intro-wizard db) (let [{:keys [selected-id address key-code]} (:intro-wizard db)
{:keys [address]} (get-selected-multiaccount cofx) {:keys [address]} (get-selected-multiaccount cofx)
hashed-password (ethereum/sha3 (security/safe-unmask-data key-code)) 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]})) {::store-multiaccount [selected-id address hashed-password callback]}))
(fx/defn intro-wizard (fx/defn intro-wizard
@ -184,11 +184,16 @@
name (gfycat/generate-gfy publicKey) name (gfycat/generate-gfy publicKey)
photo-path (identicon/identicon publicKey) photo-path (identicon/identicon publicKey)
multiaccount-data {:name name :address address :photo-path photo-path} 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 :name name
:photo-path photo-path :photo-path photo-path
; public key of the chat account
:public-key publicKey :public-key publicKey
:latest-derived-path 0 :latest-derived-path 0
:accounts [wallet-account] :accounts [wallet-account]
:signing-phrase signing-phrase :signing-phrase signing-phrase
@ -296,26 +301,26 @@
{:events [::store-multiaccount-success] {:events [::store-multiaccount-success]
:interceptors [(re-frame/inject-cofx :random-guid-generator) :interceptors [(re-frame/inject-cofx :random-guid-generator)
(re-frame/inject-cofx ::get-signing-phrase)]} (re-frame/inject-cofx ::get-signing-phrase)]}
[cofx password] [cofx password derived]
(on-multiaccount-created cofx (get-selected-multiaccount cofx) password {:seed-backed-up? false})) (on-multiaccount-created cofx
(assoc
(get-selected-multiaccount cofx)
:derived
(types/json->clj derived))
password
{:seed-backed-up? false}))
(re-frame/reg-fx (re-frame/reg-fx
::store-multiaccount ::store-multiaccount
(fn [[id address hashed-password callback]] (fn [[id address hashed-password callback]]
(status/multiaccount-store-account (status/multiaccount-store-derived
id id
[constants/path-wallet-root
constants/path-eip1581
constants/path-whisper
constants/path-default-wallet]
hashed-password hashed-password
(fn [] callback)))
(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))))))))
(re-frame/reg-fx (re-frame/reg-fx
::save-account-and-login ::save-account-and-login

View File

@ -127,7 +127,10 @@
(let [{:keys [id] :as root-data} (types/json->clj result)] (let [{:keys [id] :as root-data} (types/json->clj result)]
(status-im.native-module.core/multiaccount-derive-addresses (status-im.native-module.core/multiaccount-derive-addresses
id id
[constants/path-default-wallet constants/path-whisper] [constants/path-wallet-root
constants/path-eip1581
constants/path-whisper
constants/path-default-wallet]
(fn [result] (fn [result]
(let [derived-data (types/json->clj result)] (let [derived-data (types/json->clj result)]
(re-frame/dispatch [::import-multiaccount-success (re-frame/dispatch [::import-multiaccount-success

View File

@ -21,15 +21,15 @@
(re-frame/reg-fx (re-frame/reg-fx
::generate-account ::generate-account
(fn [{:keys [address hashed-password path-num]}] (fn [{:keys [derivation-info hashed-password path-num]}]
(status/multiaccount-load-account (let [{:keys [address path]} derivation-info]
address (status/multiaccount-load-account
hashed-password address
(fn [value] hashed-password
(let [{:keys [id error]} (types/json->clj value)] (fn [value]
(if error (let [{:keys [id error]} (types/json->clj value)]
(re-frame/dispatch [::generate-new-account-error]) (if error
(let [path (str constants/path-root "/" path-num)] (re-frame/dispatch [::generate-new-account-error])
(status/multiaccount-derive-addresses (status/multiaccount-derive-addresses
id id
[path] [path]
@ -45,7 +45,7 @@
{:name (str "Account " path-num) {:name (str "Account " path-num)
:address address :address address
:public-key public-key :public-key public-key
:path path :path (str constants/path-wallet-root "/" path-num)
:color (rand-nth colors/account-colors)}]))))))))))))) :color (rand-nth colors/account-colors)}])))))))))))))
(fx/defn set-symbol-request (fx/defn set-symbol-request
@ -56,11 +56,20 @@
(fx/defn generate-new-account (fx/defn generate-new-account
{:events [:wallet.accounts/generate-new-account]} {:events [:wallet.accounts/generate-new-account]}
[{:keys [db]} password] [{:keys [db]} password]
(when-not (get-in db [:generate-account :step]) (let [wallet-root-address (get-in db [:multiaccount :wallet-root-address])
{:db (assoc-in db [:generate-account :step] :generating) path-num (inc (get-in db [:multiaccount :latest-derived-path]))]
::generate-account {:address (get-in db [:multiaccount :address]) (when-not (get-in db [:generate-account :step])
:path-num (inc (get-in db [:multiaccount :latest-derived-path])) {:db (assoc-in db [:generate-account :step] :generating)
:hashed-password (ethereum/sha3 password)}})) ::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 (fx/defn generate-new-account-error
{:events [::generate-new-account-error]} {:events [::generate-new-account-error]}