cfxstore/
secret_store.rs

1// Copyright 2015-2019 Parity Technologies (UK) Ltd.
2// This file is part of Parity Ethereum.
3
4// Parity Ethereum is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity Ethereum is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity Ethereum.  If not, see <http://www.gnu.org/licenses/>.
16
17use crate::{
18    json::{OpaqueKeyFile, Uuid},
19    Error, OpaqueSecret,
20};
21use cfx_types::H256;
22use cfxkey::{Address, Message, Password, Public, Secret, Signature};
23use std::{
24    cmp::Ordering,
25    hash::{Hash, Hasher},
26    path::PathBuf,
27};
28
29/// Key directory reference
30#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
31pub enum SecretVaultRef {
32    /// Reference to key in root directory
33    Root,
34    /// Referenc to key in specific vault
35    Vault(String),
36}
37
38/// Stored account reference
39#[derive(Debug, Clone)]
40pub struct StoreAccountRef {
41    /// Account address
42    pub address: Address,
43    /// Vault reference
44    pub vault: SecretVaultRef,
45}
46
47impl PartialOrd for StoreAccountRef {
48    fn partial_cmp(&self, other: &StoreAccountRef) -> Option<Ordering> {
49        Some(self.cmp(other))
50    }
51}
52
53impl PartialEq for StoreAccountRef {
54    fn eq(&self, other: &Self) -> bool { self.address == other.address }
55}
56impl Eq for StoreAccountRef {}
57
58impl Ord for StoreAccountRef {
59    fn cmp(&self, other: &Self) -> Ordering {
60        self.address
61            .cmp(&other.address)
62            .then_with(|| self.vault.cmp(&other.vault))
63    }
64}
65
66impl Hash for StoreAccountRef {
67    fn hash<H: Hasher>(&self, state: &mut H) { self.address.hash(state); }
68}
69
70impl ::std::borrow::Borrow<Address> for StoreAccountRef {
71    fn borrow(&self) -> &Address { &self.address }
72}
73
74/// Simple Secret Store API
75pub trait SimpleSecretStore: Send + Sync {
76    /// Inserts new accounts to the store (or vault) with given password.
77    fn insert_account(
78        &self, vault: SecretVaultRef, secret: Secret, password: &Password,
79    ) -> Result<StoreAccountRef, Error>;
80    /// Inserts new derived account to the store (or vault) with given password.
81    fn insert_derived(
82        &self, vault: SecretVaultRef, account_ref: &StoreAccountRef,
83        password: &Password, derivation: Derivation,
84    ) -> Result<StoreAccountRef, Error>;
85    /// Changes accounts password.
86    fn change_password(
87        &self, account: &StoreAccountRef, old_password: &Password,
88        new_password: &Password,
89    ) -> Result<(), Error>;
90    /// Exports key details for account.
91    fn export_account(
92        &self, account: &StoreAccountRef, password: &Password,
93    ) -> Result<OpaqueKeyFile, Error>;
94    /// Entirely removes account from the store and underlying storage.
95    fn remove_account(
96        &self, account: &StoreAccountRef, password: &Password,
97    ) -> Result<(), Error>;
98    /// Generates new derived account.
99    fn generate_derived(
100        &self, account_ref: &StoreAccountRef, password: &Password,
101        derivation: Derivation,
102    ) -> Result<Address, Error>;
103    /// Sign a message with given account.
104    fn sign(
105        &self, account: &StoreAccountRef, password: &Password,
106        message: &Message,
107    ) -> Result<Signature, Error>;
108    /// Sign a message with derived account.
109    fn sign_derived(
110        &self, account_ref: &StoreAccountRef, password: &Password,
111        derivation: Derivation, message: &Message,
112    ) -> Result<Signature, Error>;
113    /// Decrypt a messages with given account.
114    fn decrypt(
115        &self, account: &StoreAccountRef, password: &Password,
116        shared_mac: &[u8], message: &[u8],
117    ) -> Result<Vec<u8>, Error>;
118    /// Agree on shared key.
119    fn agree(
120        &self, account: &StoreAccountRef, password: &Password, other: &Public,
121    ) -> Result<Secret, Error>;
122
123    /// Returns all accounts in this secret store.
124    fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error>;
125    /// Get reference to some account with given address.
126    /// This method could be removed if we will guarantee that there is max(1)
127    /// account for given address.
128    fn account_ref(&self, address: &Address) -> Result<StoreAccountRef, Error>;
129
130    /// Create new vault with given password
131    fn create_vault(
132        &self, name: &str, password: &Password,
133    ) -> Result<(), Error>;
134    /// Open vault with given password
135    fn open_vault(&self, name: &str, password: &Password) -> Result<(), Error>;
136    /// Close vault
137    fn close_vault(&self, name: &str) -> Result<(), Error>;
138    /// List all vaults
139    fn list_vaults(&self) -> Result<Vec<String>, Error>;
140    /// List all currently opened vaults
141    fn list_opened_vaults(&self) -> Result<Vec<String>, Error>;
142    /// Change vault password
143    fn change_vault_password(
144        &self, name: &str, new_password: &Password,
145    ) -> Result<(), Error>;
146    /// Cnage account' vault
147    fn change_account_vault(
148        &self, vault: SecretVaultRef, account: StoreAccountRef,
149    ) -> Result<StoreAccountRef, Error>;
150    /// Get vault metadata string.
151    fn get_vault_meta(&self, name: &str) -> Result<String, Error>;
152    /// Set vault metadata string.
153    fn set_vault_meta(&self, name: &str, meta: &str) -> Result<(), Error>;
154}
155
156/// Secret Store API
157pub trait SecretStore: SimpleSecretStore {
158    /// Returns a raw opaque Secret that can be later used to sign a message.
159    fn raw_secret(
160        &self, account: &StoreAccountRef, password: &Password,
161    ) -> Result<OpaqueSecret, Error>;
162
163    /// Signs a message with raw secret.
164    fn sign_with_secret(
165        &self, secret: &OpaqueSecret, message: &Message,
166    ) -> Result<Signature, Error> {
167        Ok(::cfxkey::sign(&secret.0, message)?)
168    }
169
170    /// Imports existing JSON wallet
171    fn import_wallet(
172        &self, vault: SecretVaultRef, json: &[u8], password: &Password,
173        gen_id: bool,
174    ) -> Result<StoreAccountRef, Error>;
175    /// Copies account between stores and vaults.
176    fn copy_account(
177        &self, new_store: &dyn SimpleSecretStore, new_vault: SecretVaultRef,
178        account: &StoreAccountRef, password: &Password,
179        new_password: &Password,
180    ) -> Result<(), Error>;
181    /// Checks if password matches given account.
182    fn test_password(
183        &self, account: &StoreAccountRef, password: &Password,
184    ) -> Result<bool, Error>;
185
186    /// Returns a public key for given account.
187    fn public(
188        &self, account: &StoreAccountRef, password: &Password,
189    ) -> Result<Public, Error>;
190
191    /// Returns uuid of an account.
192    fn uuid(&self, account: &StoreAccountRef) -> Result<Uuid, Error>;
193    /// Returns account's name.
194    fn name(&self, account: &StoreAccountRef) -> Result<String, Error>;
195    /// Returns account's metadata.
196    fn meta(&self, account: &StoreAccountRef) -> Result<String, Error>;
197
198    /// Modifies account metadata.
199    fn set_name(
200        &self, account: &StoreAccountRef, name: String,
201    ) -> Result<(), Error>;
202    /// Modifies account name.
203    fn set_meta(
204        &self, account: &StoreAccountRef, meta: String,
205    ) -> Result<(), Error>;
206
207    /// Returns local path of the store.
208    fn local_path(&self) -> PathBuf;
209    /// Lists all found geth accounts.
210    fn list_geth_accounts(&self, testnet: bool) -> Vec<Address>;
211    /// Imports geth accounts to the store/vault.
212    fn import_geth_accounts(
213        &self, vault: SecretVaultRef, desired: Vec<Address>, testnet: bool,
214    ) -> Result<Vec<StoreAccountRef>, Error>;
215}
216
217impl StoreAccountRef {
218    /// Create reference to root account with given address
219    pub fn root(address: Address) -> Self {
220        StoreAccountRef::new(SecretVaultRef::Root, address)
221    }
222
223    /// Create reference to vault account with given address
224    pub fn vault(vault_name: &str, address: Address) -> Self {
225        StoreAccountRef::new(
226            SecretVaultRef::Vault(vault_name.to_owned()),
227            address,
228        )
229    }
230
231    /// Create new account reference
232    pub fn new(vault_ref: SecretVaultRef, address: Address) -> Self {
233        StoreAccountRef {
234            vault: vault_ref,
235            address,
236        }
237    }
238}
239
240/// Node in hierarchical derivation.
241pub struct IndexDerivation {
242    /// Node is soft (allows proof of parent from parent node).
243    pub soft: bool,
244    /// Index sequence of the node.
245    pub index: u32,
246}
247
248/// Derivation scheme for keys
249pub enum Derivation {
250    /// Hierarchical derivation
251    Hierarchical(Vec<IndexDerivation>),
252    /// Hash derivation, soft.
253    SoftHash(H256),
254    /// Hash derivation, hard.
255    HardHash(H256),
256}