// Copyright 2015-2020 Parity Technologies (UK) Ltd. // This file is part of OpenEthereum. // OpenEthereum is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // OpenEthereum is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with OpenEthereum. If not, see . use ethereum_types::H256; use ethkey::{Address, Message, Password, Public, Secret, Signature}; use json::{OpaqueKeyFile, Uuid}; use std::{ cmp::Ordering, hash::{Hash, Hasher}, path::PathBuf, }; use Error; use OpaqueSecret; /// Key directory reference #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum SecretVaultRef { /// Reference to key in root directory Root, /// Referenc to key in specific vault Vault(String), } /// Stored account reference #[derive(Debug, Clone, PartialEq, Eq, Ord)] pub struct StoreAccountRef { /// Account address pub address: Address, /// Vault reference pub vault: SecretVaultRef, } impl PartialOrd for StoreAccountRef { fn partial_cmp(&self, other: &StoreAccountRef) -> Option { Some( self.address .cmp(&other.address) .then_with(|| self.vault.cmp(&other.vault)), ) } } impl ::std::borrow::Borrow
for StoreAccountRef { fn borrow(&self) -> &Address { &self.address } } /// Simple Secret Store API pub trait SimpleSecretStore: Send + Sync { /// Inserts new accounts to the store (or vault) with given password. fn insert_account( &self, vault: SecretVaultRef, secret: Secret, password: &Password, ) -> Result; /// Inserts new derived account to the store (or vault) with given password. fn insert_derived( &self, vault: SecretVaultRef, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation, ) -> Result; /// Changes accounts password. fn change_password( &self, account: &StoreAccountRef, old_password: &Password, new_password: &Password, ) -> Result<(), Error>; /// Exports key details for account. fn export_account( &self, account: &StoreAccountRef, password: &Password, ) -> Result; /// Entirely removes account from the store and underlying storage. fn remove_account(&self, account: &StoreAccountRef, password: &Password) -> Result<(), Error>; /// Generates new derived account. fn generate_derived( &self, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation, ) -> Result; /// Sign a message with given account. fn sign( &self, account: &StoreAccountRef, password: &Password, message: &Message, ) -> Result; /// Sign a message with derived account. fn sign_derived( &self, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation, message: &Message, ) -> Result; /// Decrypt a messages with given account. fn decrypt( &self, account: &StoreAccountRef, password: &Password, shared_mac: &[u8], message: &[u8], ) -> Result, Error>; /// Agree on shared key. fn agree( &self, account: &StoreAccountRef, password: &Password, other: &Public, ) -> Result; /// Returns all accounts in this secret store. fn accounts(&self) -> Result, Error>; /// Get reference to some account with given address. /// This method could be removed if we will guarantee that there is max(1) account for given address. fn account_ref(&self, address: &Address) -> Result; /// Create new vault with given password fn create_vault(&self, name: &str, password: &Password) -> Result<(), Error>; /// Open vault with given password fn open_vault(&self, name: &str, password: &Password) -> Result<(), Error>; /// Close vault fn close_vault(&self, name: &str) -> Result<(), Error>; /// List all vaults fn list_vaults(&self) -> Result, Error>; /// List all currently opened vaults fn list_opened_vaults(&self) -> Result, Error>; /// Change vault password fn change_vault_password(&self, name: &str, new_password: &Password) -> Result<(), Error>; /// Cnage account' vault fn change_account_vault( &self, vault: SecretVaultRef, account: StoreAccountRef, ) -> Result; /// Get vault metadata string. fn get_vault_meta(&self, name: &str) -> Result; /// Set vault metadata string. fn set_vault_meta(&self, name: &str, meta: &str) -> Result<(), Error>; } /// Secret Store API pub trait SecretStore: SimpleSecretStore { /// Returns a raw opaque Secret that can be later used to sign a message. fn raw_secret( &self, account: &StoreAccountRef, password: &Password, ) -> Result; /// Signs a message with raw secret. fn sign_with_secret( &self, secret: &OpaqueSecret, message: &Message, ) -> Result { Ok(::ethkey::sign(&secret.0, message)?) } /// Imports presale wallet fn import_presale( &self, vault: SecretVaultRef, json: &[u8], password: &Password, ) -> Result; /// Imports existing JSON wallet fn import_wallet( &self, vault: SecretVaultRef, json: &[u8], password: &Password, gen_id: bool, ) -> Result; /// Copies account between stores and vaults. fn copy_account( &self, new_store: &dyn SimpleSecretStore, new_vault: SecretVaultRef, account: &StoreAccountRef, password: &Password, new_password: &Password, ) -> Result<(), Error>; /// Checks if password matches given account. fn test_password(&self, account: &StoreAccountRef, password: &Password) -> Result; /// Returns a public key for given account. fn public(&self, account: &StoreAccountRef, password: &Password) -> Result; /// Returns uuid of an account. fn uuid(&self, account: &StoreAccountRef) -> Result; /// Returns account's name. fn name(&self, account: &StoreAccountRef) -> Result; /// Returns account's metadata. fn meta(&self, account: &StoreAccountRef) -> Result; /// Modifies account metadata. fn set_name(&self, account: &StoreAccountRef, name: String) -> Result<(), Error>; /// Modifies account name. fn set_meta(&self, account: &StoreAccountRef, meta: String) -> Result<(), Error>; /// Returns local path of the store. fn local_path(&self) -> PathBuf; } impl StoreAccountRef { /// Create reference to root account with given address pub fn root(address: Address) -> Self { StoreAccountRef::new(SecretVaultRef::Root, address) } /// Create reference to vault account with given address pub fn vault(vault_name: &str, address: Address) -> Self { StoreAccountRef::new(SecretVaultRef::Vault(vault_name.to_owned()), address) } /// Create new account reference pub fn new(vault_ref: SecretVaultRef, address: Address) -> Self { StoreAccountRef { vault: vault_ref, address: address, } } } impl Hash for StoreAccountRef { fn hash(&self, state: &mut H) { self.address.hash(state); } } /// Node in hierarchical derivation. pub struct IndexDerivation { /// Node is soft (allows proof of parent from parent node). pub soft: bool, /// Index sequence of the node. pub index: u32, } /// Derivation scheme for keys pub enum Derivation { /// Hierarchical derivation Hierarchical(Vec), /// Hash derivation, soft. SoftHash(H256), /// Hash derivation, hard. HardHash(H256), }