Add type for passwords. (#8920)
* Add type for passwords. * Fix test. * Simplify `Drop` impls of `Password` and `Memzero`. * Spaces to tabs. * Custom `Drop` impl for `Password`.
This commit is contained in:
parent
c473ab97c7
commit
41348dead4
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -958,6 +958,8 @@ dependencies = [
|
|||||||
"quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -56,9 +56,9 @@ impl<T> Keccak256<[u8; 32]> for T where T: AsRef<[u8]> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn derive_key_iterations(password: &str, salt: &[u8; 32], c: u32) -> (Vec<u8>, Vec<u8>) {
|
pub fn derive_key_iterations(password: &[u8], salt: &[u8; 32], c: u32) -> (Vec<u8>, Vec<u8>) {
|
||||||
let mut derived_key = [0u8; KEY_LENGTH];
|
let mut derived_key = [0u8; KEY_LENGTH];
|
||||||
pbkdf2::sha256(c, pbkdf2::Salt(salt), pbkdf2::Secret(password.as_bytes()), &mut derived_key);
|
pbkdf2::sha256(c, pbkdf2::Salt(salt), pbkdf2::Secret(password), &mut derived_key);
|
||||||
let derived_right_bits = &derived_key[0..KEY_LENGTH_AES];
|
let derived_right_bits = &derived_key[0..KEY_LENGTH_AES];
|
||||||
let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH];
|
let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH];
|
||||||
(derived_right_bits.to_vec(), derived_left_bits.to_vec())
|
(derived_right_bits.to_vec(), derived_left_bits.to_vec())
|
||||||
|
@ -18,7 +18,7 @@ use error::ScryptError;
|
|||||||
use rcrypto::scrypt::{scrypt, ScryptParams};
|
use rcrypto::scrypt::{scrypt, ScryptParams};
|
||||||
use super::{KEY_LENGTH_AES, KEY_LENGTH};
|
use super::{KEY_LENGTH_AES, KEY_LENGTH};
|
||||||
|
|
||||||
pub fn derive_key(pass: &str, salt: &[u8; 32], n: u32, p: u32, r: u32) -> Result<(Vec<u8>, Vec<u8>), ScryptError> {
|
pub fn derive_key(pass: &[u8], salt: &[u8; 32], n: u32, p: u32, r: u32) -> Result<(Vec<u8>, Vec<u8>), ScryptError> {
|
||||||
// sanity checks
|
// sanity checks
|
||||||
let log_n = (32 - n.leading_zeros() - 1) as u8;
|
let log_n = (32 - n.leading_zeros() - 1) as u8;
|
||||||
if log_n as u32 >= r * 16 {
|
if log_n as u32 >= r * 16 {
|
||||||
@ -31,7 +31,7 @@ pub fn derive_key(pass: &str, salt: &[u8; 32], n: u32, p: u32, r: u32) -> Result
|
|||||||
|
|
||||||
let mut derived_key = vec![0u8; KEY_LENGTH];
|
let mut derived_key = vec![0u8; KEY_LENGTH];
|
||||||
let scrypt_params = ScryptParams::new(log_n, r, p);
|
let scrypt_params = ScryptParams::new(log_n, r, p);
|
||||||
scrypt(pass.as_bytes(), salt, &scrypt_params, &mut derived_key);
|
scrypt(pass, salt, &scrypt_params, &mut derived_key);
|
||||||
let derived_right_bits = &derived_key[0..KEY_LENGTH_AES];
|
let derived_right_bits = &derived_key[0..KEY_LENGTH_AES];
|
||||||
let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH];
|
let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH];
|
||||||
Ok((derived_right_bits.to_vec(), derived_left_bits.to_vec()))
|
Ok((derived_right_bits.to_vec(), derived_left_bits.to_vec()))
|
||||||
|
@ -26,7 +26,7 @@ use parking_lot::Mutex;
|
|||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethereum_types::{H128, H256, Address};
|
use ethereum_types::{H128, H256, Address};
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use ethkey::{Signature, Public};
|
use ethkey::{Signature, Password, Public};
|
||||||
use crypto;
|
use crypto;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use fetch::{Fetch, Client as FetchClient, Method, BodyReader, Request};
|
use fetch::{Fetch, Client as FetchClient, Method, BodyReader, Request};
|
||||||
@ -71,7 +71,7 @@ pub struct EncryptorConfig {
|
|||||||
/// Account used for signing requests to key server
|
/// Account used for signing requests to key server
|
||||||
pub key_server_account: Option<Address>,
|
pub key_server_account: Option<Address>,
|
||||||
/// Passwords used to unlock accounts
|
/// Passwords used to unlock accounts
|
||||||
pub passwords: Vec<String>,
|
pub passwords: Vec<Password>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EncryptionSession {
|
struct EncryptionSession {
|
||||||
|
@ -85,6 +85,7 @@ use ethcore::account_provider::AccountProvider;
|
|||||||
use ethcore::miner::{self, Miner, MinerService};
|
use ethcore::miner::{self, Miner, MinerService};
|
||||||
use ethcore::trace::{Tracer, VMTracer};
|
use ethcore::trace::{Tracer, VMTracer};
|
||||||
use rustc_hex::FromHex;
|
use rustc_hex::FromHex;
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
// Source avaiable at https://github.com/parity-contracts/private-tx/blob/master/contracts/PrivateContract.sol
|
// Source avaiable at https://github.com/parity-contracts/private-tx/blob/master/contracts/PrivateContract.sol
|
||||||
const DEFAULT_STUB_CONTRACT: &'static str = include_str!("../res/private.evm");
|
const DEFAULT_STUB_CONTRACT: &'static str = include_str!("../res/private.evm");
|
||||||
@ -102,7 +103,7 @@ pub struct ProviderConfig {
|
|||||||
/// Account used for signing public transactions created from private transactions
|
/// Account used for signing public transactions created from private transactions
|
||||||
pub signer_account: Option<Address>,
|
pub signer_account: Option<Address>,
|
||||||
/// Passwords used to unlock accounts
|
/// Passwords used to unlock accounts
|
||||||
pub passwords: Vec<String>,
|
pub passwords: Vec<Password>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -121,7 +122,7 @@ pub struct Provider {
|
|||||||
encryptor: Box<Encryptor>,
|
encryptor: Box<Encryptor>,
|
||||||
validator_accounts: HashSet<Address>,
|
validator_accounts: HashSet<Address>,
|
||||||
signer_account: Option<Address>,
|
signer_account: Option<Address>,
|
||||||
passwords: Vec<String>,
|
passwords: Vec<Password>,
|
||||||
notify: RwLock<Vec<Weak<ChainNotify>>>,
|
notify: RwLock<Vec<Weak<ChainNotify>>>,
|
||||||
transactions_for_signing: Mutex<SigningStore>,
|
transactions_for_signing: Mutex<SigningStore>,
|
||||||
// TODO [ToDr] Move the Mutex/RwLock inside `VerificationStore` after refactored to `drain`.
|
// TODO [ToDr] Move the Mutex/RwLock inside `VerificationStore` after refactored to `drain`.
|
||||||
@ -670,7 +671,7 @@ impl Importer for Arc<Provider> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Try to unlock account using stored password, return found password if any
|
/// Try to unlock account using stored password, return found password if any
|
||||||
fn find_account_password(passwords: &Vec<String>, account_provider: &AccountProvider, account: &Address) -> Option<String> {
|
fn find_account_password(passwords: &Vec<Password>, account_provider: &AccountProvider, account: &Address) -> Option<Password> {
|
||||||
for password in passwords {
|
for password in passwords {
|
||||||
if let Ok(true) = account_provider.test_password(account, password) {
|
if let Ok(true) = account_provider.test_password(account, password) {
|
||||||
return Some(password.clone());
|
return Some(password.clone());
|
||||||
|
@ -55,9 +55,9 @@ fn private_contract() {
|
|||||||
let key3 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000013")).unwrap();
|
let key3 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000013")).unwrap();
|
||||||
let key4 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000014")).unwrap();
|
let key4 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000014")).unwrap();
|
||||||
let ap = Arc::new(AccountProvider::transient_provider());
|
let ap = Arc::new(AccountProvider::transient_provider());
|
||||||
ap.insert_account(key1.secret().clone(), "").unwrap();
|
ap.insert_account(key1.secret().clone(), &"".into()).unwrap();
|
||||||
ap.insert_account(key3.secret().clone(), "").unwrap();
|
ap.insert_account(key3.secret().clone(), &"".into()).unwrap();
|
||||||
ap.insert_account(key4.secret().clone(), "").unwrap();
|
ap.insert_account(key4.secret().clone(), &"".into()).unwrap();
|
||||||
|
|
||||||
let config = ProviderConfig{
|
let config = ProviderConfig{
|
||||||
validator_accounts: vec![key3.address(), key4.address()],
|
validator_accounts: vec![key3.address(), key4.address()],
|
||||||
|
@ -29,7 +29,7 @@ use ethstore::{
|
|||||||
random_string, SecretVaultRef, StoreAccountRef, OpaqueSecret,
|
random_string, SecretVaultRef, StoreAccountRef, OpaqueSecret,
|
||||||
};
|
};
|
||||||
use ethstore::accounts_dir::MemoryDirectory;
|
use ethstore::accounts_dir::MemoryDirectory;
|
||||||
use ethstore::ethkey::{Address, Message, Public, Secret, Random, Generator};
|
use ethstore::ethkey::{Address, Message, Public, Secret, Password, Random, Generator};
|
||||||
use ethjson::misc::AccountMeta;
|
use ethjson::misc::AccountMeta;
|
||||||
use hardware_wallet::{Error as HardwareError, HardwareWalletManager, KeyPath, TransactionInfo};
|
use hardware_wallet::{Error as HardwareError, HardwareWalletManager, KeyPath, TransactionInfo};
|
||||||
use super::transaction::{Action, Transaction};
|
use super::transaction::{Action, Transaction};
|
||||||
@ -52,7 +52,7 @@ enum Unlock {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct AccountData {
|
struct AccountData {
|
||||||
unlock: Unlock,
|
unlock: Unlock,
|
||||||
password: String,
|
password: Password,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signing error
|
/// Signing error
|
||||||
@ -112,7 +112,7 @@ fn transient_sstore() -> EthMultiStore {
|
|||||||
EthMultiStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed")
|
EthMultiStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed")
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccountToken = String;
|
type AccountToken = Password;
|
||||||
|
|
||||||
/// Account management.
|
/// Account management.
|
||||||
/// Responsible for unlocking accounts.
|
/// Responsible for unlocking accounts.
|
||||||
@ -217,12 +217,12 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates new random account.
|
/// Creates new random account.
|
||||||
pub fn new_account(&self, password: &str) -> Result<Address, Error> {
|
pub fn new_account(&self, password: &Password) -> Result<Address, Error> {
|
||||||
self.new_account_and_public(password).map(|d| d.0)
|
self.new_account_and_public(password).map(|d| d.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates new random account and returns address and public key
|
/// Creates new random account and returns address and public key
|
||||||
pub fn new_account_and_public(&self, password: &str) -> Result<(Address, Public), Error> {
|
pub fn new_account_and_public(&self, password: &Password) -> Result<(Address, Public), Error> {
|
||||||
let acc = Random.generate().expect("secp context has generation capabilities; qed");
|
let acc = Random.generate().expect("secp context has generation capabilities; qed");
|
||||||
let public = acc.public().clone();
|
let public = acc.public().clone();
|
||||||
let secret = acc.secret().clone();
|
let secret = acc.secret().clone();
|
||||||
@ -232,7 +232,7 @@ impl AccountProvider {
|
|||||||
|
|
||||||
/// Inserts new account into underlying store.
|
/// Inserts new account into underlying store.
|
||||||
/// Does not unlock account!
|
/// Does not unlock account!
|
||||||
pub fn insert_account(&self, secret: Secret, password: &str) -> Result<Address, Error> {
|
pub fn insert_account(&self, secret: Secret, password: &Password) -> Result<Address, Error> {
|
||||||
let account = self.sstore.insert_account(SecretVaultRef::Root, secret, password)?;
|
let account = self.sstore.insert_account(SecretVaultRef::Root, secret, password)?;
|
||||||
if self.blacklisted_accounts.contains(&account.address) {
|
if self.blacklisted_accounts.contains(&account.address) {
|
||||||
self.sstore.remove_account(&account, password)?;
|
self.sstore.remove_account(&account, password)?;
|
||||||
@ -244,7 +244,7 @@ impl AccountProvider {
|
|||||||
/// Generates new derived account based on the existing one
|
/// Generates new derived account based on the existing one
|
||||||
/// If password is not provided, account must be unlocked
|
/// If password is not provided, account must be unlocked
|
||||||
/// New account will be created with the same password (if save: true)
|
/// New account will be created with the same password (if save: true)
|
||||||
pub fn derive_account(&self, address: &Address, password: Option<String>, derivation: Derivation, save: bool)
|
pub fn derive_account(&self, address: &Address, password: Option<Password>, derivation: Derivation, save: bool)
|
||||||
-> Result<Address, SignError>
|
-> Result<Address, SignError>
|
||||||
{
|
{
|
||||||
let account = self.sstore.account_ref(&address)?;
|
let account = self.sstore.account_ref(&address)?;
|
||||||
@ -256,13 +256,13 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Import a new presale wallet.
|
/// Import a new presale wallet.
|
||||||
pub fn import_presale(&self, presale_json: &[u8], password: &str) -> Result<Address, Error> {
|
pub fn import_presale(&self, presale_json: &[u8], password: &Password) -> Result<Address, Error> {
|
||||||
let account = self.sstore.import_presale(SecretVaultRef::Root, presale_json, password)?;
|
let account = self.sstore.import_presale(SecretVaultRef::Root, presale_json, password)?;
|
||||||
Ok(Address::from(account.address).into())
|
Ok(Address::from(account.address).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Import a new wallet.
|
/// Import a new wallet.
|
||||||
pub fn import_wallet(&self, json: &[u8], password: &str, gen_id: bool) -> Result<Address, Error> {
|
pub fn import_wallet(&self, json: &[u8], password: &Password, gen_id: bool) -> Result<Address, Error> {
|
||||||
let account = self.sstore.import_wallet(SecretVaultRef::Root, json, password, gen_id)?;
|
let account = self.sstore.import_wallet(SecretVaultRef::Root, json, password, gen_id)?;
|
||||||
if self.blacklisted_accounts.contains(&account.address) {
|
if self.blacklisted_accounts.contains(&account.address) {
|
||||||
self.sstore.remove_account(&account, password)?;
|
self.sstore.remove_account(&account, password)?;
|
||||||
@ -543,7 +543,7 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns account public key.
|
/// Returns account public key.
|
||||||
pub fn account_public(&self, address: Address, password: &str) -> Result<Public, Error> {
|
pub fn account_public(&self, address: Address, password: &Password) -> Result<Public, Error> {
|
||||||
self.sstore.public(&self.sstore.account_ref(&address)?, password)
|
self.sstore.public(&self.sstore.account_ref(&address)?, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,29 +560,29 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the password for `account` is `password`. `false` if not.
|
/// Returns `true` if the password for `account` is `password`. `false` if not.
|
||||||
pub fn test_password(&self, address: &Address, password: &str) -> Result<bool, Error> {
|
pub fn test_password(&self, address: &Address, password: &Password) -> Result<bool, Error> {
|
||||||
self.sstore.test_password(&self.sstore.account_ref(&address)?, password)
|
self.sstore.test_password(&self.sstore.account_ref(&address)?, password)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Permanently removes an account.
|
/// Permanently removes an account.
|
||||||
pub fn kill_account(&self, address: &Address, password: &str) -> Result<(), Error> {
|
pub fn kill_account(&self, address: &Address, password: &Password) -> Result<(), Error> {
|
||||||
self.sstore.remove_account(&self.sstore.account_ref(&address)?, &password)?;
|
self.sstore.remove_account(&self.sstore.account_ref(&address)?, &password)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Changes the password of `account` from `password` to `new_password`. Fails if incorrect `password` given.
|
/// Changes the password of `account` from `password` to `new_password`. Fails if incorrect `password` given.
|
||||||
pub fn change_password(&self, address: &Address, password: String, new_password: String) -> Result<(), Error> {
|
pub fn change_password(&self, address: &Address, password: Password, new_password: Password) -> Result<(), Error> {
|
||||||
self.sstore.change_password(&self.sstore.account_ref(address)?, &password, &new_password)
|
self.sstore.change_password(&self.sstore.account_ref(address)?, &password, &new_password)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exports an account for given address.
|
/// Exports an account for given address.
|
||||||
pub fn export_account(&self, address: &Address, password: String) -> Result<KeyFile, Error> {
|
pub fn export_account(&self, address: &Address, password: Password) -> Result<KeyFile, Error> {
|
||||||
self.sstore.export_account(&self.sstore.account_ref(address)?, &password)
|
self.sstore.export_account(&self.sstore.account_ref(address)?, &password)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper method used for unlocking accounts.
|
/// Helper method used for unlocking accounts.
|
||||||
fn unlock_account(&self, address: Address, password: String, unlock: Unlock) -> Result<(), Error> {
|
fn unlock_account(&self, address: Address, password: Password, unlock: Unlock) -> Result<(), Error> {
|
||||||
let account = self.sstore.account_ref(&address)?;
|
let account = self.sstore.account_ref(&address)?;
|
||||||
|
|
||||||
// check if account is already unlocked permanently, if it is, do nothing
|
// check if account is already unlocked permanently, if it is, do nothing
|
||||||
@ -612,7 +612,7 @@ impl AccountProvider {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn password(&self, account: &StoreAccountRef) -> Result<String, SignError> {
|
fn password(&self, account: &StoreAccountRef) -> Result<Password, SignError> {
|
||||||
let mut unlocked = self.unlocked.write();
|
let mut unlocked = self.unlocked.write();
|
||||||
let data = unlocked.get(account).ok_or(SignError::NotUnlocked)?.clone();
|
let data = unlocked.get(account).ok_or(SignError::NotUnlocked)?.clone();
|
||||||
if let Unlock::OneTime = data.unlock {
|
if let Unlock::OneTime = data.unlock {
|
||||||
@ -624,21 +624,21 @@ impl AccountProvider {
|
|||||||
return Err(SignError::NotUnlocked);
|
return Err(SignError::NotUnlocked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(data.password.clone())
|
Ok(data.password)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unlocks account permanently.
|
/// Unlocks account permanently.
|
||||||
pub fn unlock_account_permanently(&self, account: Address, password: String) -> Result<(), Error> {
|
pub fn unlock_account_permanently(&self, account: Address, password: Password) -> Result<(), Error> {
|
||||||
self.unlock_account(account, password, Unlock::Perm)
|
self.unlock_account(account, password, Unlock::Perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unlocks account temporarily (for one signing).
|
/// Unlocks account temporarily (for one signing).
|
||||||
pub fn unlock_account_temporarily(&self, account: Address, password: String) -> Result<(), Error> {
|
pub fn unlock_account_temporarily(&self, account: Address, password: Password) -> Result<(), Error> {
|
||||||
self.unlock_account(account, password, Unlock::OneTime)
|
self.unlock_account(account, password, Unlock::OneTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unlocks account temporarily with a timeout.
|
/// Unlocks account temporarily with a timeout.
|
||||||
pub fn unlock_account_timed(&self, account: Address, password: String, duration: Duration) -> Result<(), Error> {
|
pub fn unlock_account_timed(&self, account: Address, password: Password, duration: Duration) -> Result<(), Error> {
|
||||||
self.unlock_account(account, password, Unlock::Timed(Instant::now() + duration))
|
self.unlock_account(account, password, Unlock::Timed(Instant::now() + duration))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,7 +660,7 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Signs the message. If password is not provided the account must be unlocked.
|
/// Signs the message. If password is not provided the account must be unlocked.
|
||||||
pub fn sign(&self, address: Address, password: Option<String>, message: Message) -> Result<Signature, SignError> {
|
pub fn sign(&self, address: Address, password: Option<Password>, message: Message) -> Result<Signature, SignError> {
|
||||||
let account = self.sstore.account_ref(&address)?;
|
let account = self.sstore.account_ref(&address)?;
|
||||||
match self.unlocked_secrets.read().get(&account) {
|
match self.unlocked_secrets.read().get(&account) {
|
||||||
Some(secret) => {
|
Some(secret) => {
|
||||||
@ -674,7 +674,7 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Signs message using the derived secret. If password is not provided the account must be unlocked.
|
/// Signs message using the derived secret. If password is not provided the account must be unlocked.
|
||||||
pub fn sign_derived(&self, address: &Address, password: Option<String>, derivation: Derivation, message: Message)
|
pub fn sign_derived(&self, address: &Address, password: Option<Password>, derivation: Derivation, message: Message)
|
||||||
-> Result<Signature, SignError>
|
-> Result<Signature, SignError>
|
||||||
{
|
{
|
||||||
let account = self.sstore.account_ref(address)?;
|
let account = self.sstore.account_ref(address)?;
|
||||||
@ -687,7 +687,7 @@ impl AccountProvider {
|
|||||||
let account = self.sstore.account_ref(&address)?;
|
let account = self.sstore.account_ref(&address)?;
|
||||||
let is_std_password = self.sstore.test_password(&account, &token)?;
|
let is_std_password = self.sstore.test_password(&account, &token)?;
|
||||||
|
|
||||||
let new_token = random_string(16);
|
let new_token = Password::from(random_string(16));
|
||||||
let signature = if is_std_password {
|
let signature = if is_std_password {
|
||||||
// Insert to transient store
|
// Insert to transient store
|
||||||
self.sstore.copy_account(&self.transient_sstore, SecretVaultRef::Root, &account, &token, &new_token)?;
|
self.sstore.copy_account(&self.transient_sstore, SecretVaultRef::Root, &account, &token, &new_token)?;
|
||||||
@ -710,7 +710,7 @@ impl AccountProvider {
|
|||||||
let account = self.sstore.account_ref(&address)?;
|
let account = self.sstore.account_ref(&address)?;
|
||||||
let is_std_password = self.sstore.test_password(&account, &token)?;
|
let is_std_password = self.sstore.test_password(&account, &token)?;
|
||||||
|
|
||||||
let new_token = random_string(16);
|
let new_token = Password::from(random_string(16));
|
||||||
let message = if is_std_password {
|
let message = if is_std_password {
|
||||||
// Insert to transient store
|
// Insert to transient store
|
||||||
self.sstore.copy_account(&self.transient_sstore, SecretVaultRef::Root, &account, &token, &new_token)?;
|
self.sstore.copy_account(&self.transient_sstore, SecretVaultRef::Root, &account, &token, &new_token)?;
|
||||||
@ -727,14 +727,14 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypts a message. If password is not provided the account must be unlocked.
|
/// Decrypts a message. If password is not provided the account must be unlocked.
|
||||||
pub fn decrypt(&self, address: Address, password: Option<String>, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, SignError> {
|
pub fn decrypt(&self, address: Address, password: Option<Password>, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, SignError> {
|
||||||
let account = self.sstore.account_ref(&address)?;
|
let account = self.sstore.account_ref(&address)?;
|
||||||
let password = password.map(Ok).unwrap_or_else(|| self.password(&account))?;
|
let password = password.map(Ok).unwrap_or_else(|| self.password(&account))?;
|
||||||
Ok(self.sstore.decrypt(&account, &password, shared_mac, message)?)
|
Ok(self.sstore.decrypt(&account, &password, shared_mac, message)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Agree on shared key.
|
/// Agree on shared key.
|
||||||
pub fn agree(&self, address: Address, password: Option<String>, other_public: &Public) -> Result<Secret, SignError> {
|
pub fn agree(&self, address: Address, password: Option<Password>, other_public: &Public) -> Result<Secret, SignError> {
|
||||||
let account = self.sstore.account_ref(&address)?;
|
let account = self.sstore.account_ref(&address)?;
|
||||||
let password = password.map(Ok).unwrap_or_else(|| self.password(&account))?;
|
let password = password.map(Ok).unwrap_or_else(|| self.password(&account))?;
|
||||||
Ok(self.sstore.agree(&account, &password, other_public)?)
|
Ok(self.sstore.agree(&account, &password, other_public)?)
|
||||||
@ -753,13 +753,13 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create new vault.
|
/// Create new vault.
|
||||||
pub fn create_vault(&self, name: &str, password: &str) -> Result<(), Error> {
|
pub fn create_vault(&self, name: &str, password: &Password) -> Result<(), Error> {
|
||||||
self.sstore.create_vault(name, password)
|
self.sstore.create_vault(name, password)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Open existing vault.
|
/// Open existing vault.
|
||||||
pub fn open_vault(&self, name: &str, password: &str) -> Result<(), Error> {
|
pub fn open_vault(&self, name: &str, password: &Password) -> Result<(), Error> {
|
||||||
self.sstore.open_vault(name, password)
|
self.sstore.open_vault(name, password)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
@ -783,7 +783,7 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Change vault password.
|
/// Change vault password.
|
||||||
pub fn change_vault_password(&self, name: &str, new_password: &str) -> Result<(), Error> {
|
pub fn change_vault_password(&self, name: &str, new_password: &Password) -> Result<(), Error> {
|
||||||
self.sstore.change_vault_password(name, new_password)
|
self.sstore.change_vault_password(name, new_password)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
@ -852,7 +852,7 @@ mod tests {
|
|||||||
fn unlock_account_temp() {
|
fn unlock_account_temp() {
|
||||||
let kp = Random.generate().unwrap();
|
let kp = Random.generate().unwrap();
|
||||||
let ap = AccountProvider::transient_provider();
|
let ap = AccountProvider::transient_provider();
|
||||||
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
|
assert!(ap.insert_account(kp.secret().clone(), &"test".into()).is_ok());
|
||||||
assert!(ap.unlock_account_temporarily(kp.address(), "test1".into()).is_err());
|
assert!(ap.unlock_account_temporarily(kp.address(), "test1".into()).is_err());
|
||||||
assert!(ap.unlock_account_temporarily(kp.address(), "test".into()).is_ok());
|
assert!(ap.unlock_account_temporarily(kp.address(), "test".into()).is_ok());
|
||||||
assert!(ap.sign(kp.address(), None, Default::default()).is_ok());
|
assert!(ap.sign(kp.address(), None, Default::default()).is_ok());
|
||||||
@ -863,7 +863,7 @@ mod tests {
|
|||||||
fn derived_account_nosave() {
|
fn derived_account_nosave() {
|
||||||
let kp = Random.generate().unwrap();
|
let kp = Random.generate().unwrap();
|
||||||
let ap = AccountProvider::transient_provider();
|
let ap = AccountProvider::transient_provider();
|
||||||
assert!(ap.insert_account(kp.secret().clone(), "base").is_ok());
|
assert!(ap.insert_account(kp.secret().clone(), &"base".into()).is_ok());
|
||||||
assert!(ap.unlock_account_permanently(kp.address(), "base".into()).is_ok());
|
assert!(ap.unlock_account_permanently(kp.address(), "base".into()).is_ok());
|
||||||
|
|
||||||
let derived_addr = ap.derive_account(
|
let derived_addr = ap.derive_account(
|
||||||
@ -881,7 +881,7 @@ mod tests {
|
|||||||
fn derived_account_save() {
|
fn derived_account_save() {
|
||||||
let kp = Random.generate().unwrap();
|
let kp = Random.generate().unwrap();
|
||||||
let ap = AccountProvider::transient_provider();
|
let ap = AccountProvider::transient_provider();
|
||||||
assert!(ap.insert_account(kp.secret().clone(), "base").is_ok());
|
assert!(ap.insert_account(kp.secret().clone(), &"base".into()).is_ok());
|
||||||
assert!(ap.unlock_account_permanently(kp.address(), "base".into()).is_ok());
|
assert!(ap.unlock_account_permanently(kp.address(), "base".into()).is_ok());
|
||||||
|
|
||||||
let derived_addr = ap.derive_account(
|
let derived_addr = ap.derive_account(
|
||||||
@ -902,7 +902,7 @@ mod tests {
|
|||||||
fn derived_account_sign() {
|
fn derived_account_sign() {
|
||||||
let kp = Random.generate().unwrap();
|
let kp = Random.generate().unwrap();
|
||||||
let ap = AccountProvider::transient_provider();
|
let ap = AccountProvider::transient_provider();
|
||||||
assert!(ap.insert_account(kp.secret().clone(), "base").is_ok());
|
assert!(ap.insert_account(kp.secret().clone(), &"base".into()).is_ok());
|
||||||
assert!(ap.unlock_account_permanently(kp.address(), "base".into()).is_ok());
|
assert!(ap.unlock_account_permanently(kp.address(), "base".into()).is_ok());
|
||||||
|
|
||||||
let derived_addr = ap.derive_account(
|
let derived_addr = ap.derive_account(
|
||||||
@ -932,7 +932,7 @@ mod tests {
|
|||||||
fn unlock_account_perm() {
|
fn unlock_account_perm() {
|
||||||
let kp = Random.generate().unwrap();
|
let kp = Random.generate().unwrap();
|
||||||
let ap = AccountProvider::transient_provider();
|
let ap = AccountProvider::transient_provider();
|
||||||
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
|
assert!(ap.insert_account(kp.secret().clone(), &"test".into()).is_ok());
|
||||||
assert!(ap.unlock_account_permanently(kp.address(), "test1".into()).is_err());
|
assert!(ap.unlock_account_permanently(kp.address(), "test1".into()).is_err());
|
||||||
assert!(ap.unlock_account_permanently(kp.address(), "test".into()).is_ok());
|
assert!(ap.unlock_account_permanently(kp.address(), "test".into()).is_ok());
|
||||||
assert!(ap.sign(kp.address(), None, Default::default()).is_ok());
|
assert!(ap.sign(kp.address(), None, Default::default()).is_ok());
|
||||||
@ -946,7 +946,7 @@ mod tests {
|
|||||||
fn unlock_account_timer() {
|
fn unlock_account_timer() {
|
||||||
let kp = Random.generate().unwrap();
|
let kp = Random.generate().unwrap();
|
||||||
let ap = AccountProvider::transient_provider();
|
let ap = AccountProvider::transient_provider();
|
||||||
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
|
assert!(ap.insert_account(kp.secret().clone(), &"test".into()).is_ok());
|
||||||
assert!(ap.unlock_account_timed(kp.address(), "test1".into(), Duration::from_secs(60)).is_err());
|
assert!(ap.unlock_account_timed(kp.address(), "test1".into(), Duration::from_secs(60)).is_err());
|
||||||
assert!(ap.unlock_account_timed(kp.address(), "test".into(), Duration::from_secs(60)).is_ok());
|
assert!(ap.unlock_account_timed(kp.address(), "test".into(), Duration::from_secs(60)).is_ok());
|
||||||
assert!(ap.sign(kp.address(), None, Default::default()).is_ok());
|
assert!(ap.sign(kp.address(), None, Default::default()).is_ok());
|
||||||
@ -959,7 +959,7 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let kp = Random.generate().unwrap();
|
let kp = Random.generate().unwrap();
|
||||||
let ap = AccountProvider::transient_provider();
|
let ap = AccountProvider::transient_provider();
|
||||||
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
|
assert!(ap.insert_account(kp.secret().clone(), &"test".into()).is_ok());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let (_signature, token) = ap.sign_with_token(kp.address(), "test".into(), Default::default()).unwrap();
|
let (_signature, token) = ap.sign_with_token(kp.address(), "test".into(), Default::default()).unwrap();
|
||||||
@ -1027,7 +1027,7 @@ mod tests {
|
|||||||
// default_account should be always available
|
// default_account should be always available
|
||||||
assert_eq!(ap.new_dapps_default_address().unwrap(), 0.into());
|
assert_eq!(ap.new_dapps_default_address().unwrap(), 0.into());
|
||||||
|
|
||||||
let address = ap.new_account("test").unwrap();
|
let address = ap.new_account(&"test".into()).unwrap();
|
||||||
ap.set_address_name(1.into(), "1".into());
|
ap.set_address_name(1.into(), "1".into());
|
||||||
|
|
||||||
// Default account set to first account by default
|
// Default account set to first account by default
|
||||||
@ -1064,7 +1064,7 @@ mod tests {
|
|||||||
fn should_not_return_blacklisted_account() {
|
fn should_not_return_blacklisted_account() {
|
||||||
// given
|
// given
|
||||||
let mut ap = AccountProvider::transient_provider();
|
let mut ap = AccountProvider::transient_provider();
|
||||||
let acc = ap.new_account("test").unwrap();
|
let acc = ap.new_account(&"test".into()).unwrap();
|
||||||
ap.blacklisted_accounts = vec![acc];
|
ap.blacklisted_accounts = vec![acc];
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
@ -40,7 +40,7 @@ use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
|
|||||||
|
|
||||||
use self::finality::RollingFinality;
|
use self::finality::RollingFinality;
|
||||||
|
|
||||||
use ethkey::{self, Signature};
|
use ethkey::{self, Password, Signature};
|
||||||
use io::{IoContext, IoHandler, TimerToken, IoService};
|
use io::{IoContext, IoHandler, TimerToken, IoService};
|
||||||
use itertools::{self, Itertools};
|
use itertools::{self, Itertools};
|
||||||
use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, Rlp};
|
use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, Rlp};
|
||||||
@ -1345,7 +1345,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
self.validators.register_client(client);
|
self.validators.register_client(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: Password) {
|
||||||
self.signer.write().set(ap, address, password);
|
self.signer.write().set(ap, address, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1414,8 +1414,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn generates_seal_and_does_not_double_propose() {
|
fn generates_seal_and_does_not_double_propose() {
|
||||||
let tap = Arc::new(AccountProvider::transient_provider());
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
let addr1 = tap.insert_account(keccak("1").into(), "1").unwrap();
|
let addr1 = tap.insert_account(keccak("1").into(), &"1".into()).unwrap();
|
||||||
let addr2 = tap.insert_account(keccak("2").into(), "2").unwrap();
|
let addr2 = tap.insert_account(keccak("2").into(), &"2".into()).unwrap();
|
||||||
|
|
||||||
let spec = Spec::new_test_round();
|
let spec = Spec::new_test_round();
|
||||||
let engine = &*spec.engine;
|
let engine = &*spec.engine;
|
||||||
@ -1446,8 +1446,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn checks_difficulty_in_generate_seal() {
|
fn checks_difficulty_in_generate_seal() {
|
||||||
let tap = Arc::new(AccountProvider::transient_provider());
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
let addr1 = tap.insert_account(keccak("1").into(), "1").unwrap();
|
let addr1 = tap.insert_account(keccak("1").into(), &"1".into()).unwrap();
|
||||||
let addr2 = tap.insert_account(keccak("0").into(), "0").unwrap();
|
let addr2 = tap.insert_account(keccak("0").into(), &"0".into()).unwrap();
|
||||||
|
|
||||||
let spec = Spec::new_test_round();
|
let spec = Spec::new_test_round();
|
||||||
let engine = &*spec.engine;
|
let engine = &*spec.engine;
|
||||||
@ -1480,7 +1480,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn proposer_switching() {
|
fn proposer_switching() {
|
||||||
let tap = AccountProvider::transient_provider();
|
let tap = AccountProvider::transient_provider();
|
||||||
let addr = tap.insert_account(keccak("0").into(), "0").unwrap();
|
let addr = tap.insert_account(keccak("0").into(), &"0".into()).unwrap();
|
||||||
let mut parent_header: Header = Header::default();
|
let mut parent_header: Header = Header::default();
|
||||||
parent_header.set_seal(vec![encode(&0usize).into_vec()]);
|
parent_header.set_seal(vec![encode(&0usize).into_vec()]);
|
||||||
parent_header.set_gas_limit("222222".parse::<U256>().unwrap());
|
parent_header.set_gas_limit("222222".parse::<U256>().unwrap());
|
||||||
@ -1505,7 +1505,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rejects_future_block() {
|
fn rejects_future_block() {
|
||||||
let tap = AccountProvider::transient_provider();
|
let tap = AccountProvider::transient_provider();
|
||||||
let addr = tap.insert_account(keccak("0").into(), "0").unwrap();
|
let addr = tap.insert_account(keccak("0").into(), &"0".into()).unwrap();
|
||||||
|
|
||||||
let mut parent_header: Header = Header::default();
|
let mut parent_header: Header = Header::default();
|
||||||
parent_header.set_seal(vec![encode(&0usize).into_vec()]);
|
parent_header.set_seal(vec![encode(&0usize).into_vec()]);
|
||||||
@ -1530,7 +1530,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rejects_step_backwards() {
|
fn rejects_step_backwards() {
|
||||||
let tap = AccountProvider::transient_provider();
|
let tap = AccountProvider::transient_provider();
|
||||||
let addr = tap.insert_account(keccak("0").into(), "0").unwrap();
|
let addr = tap.insert_account(keccak("0").into(), &"0".into()).unwrap();
|
||||||
|
|
||||||
let mut parent_header: Header = Header::default();
|
let mut parent_header: Header = Header::default();
|
||||||
parent_header.set_seal(vec![encode(&4usize).into_vec()]);
|
parent_header.set_seal(vec![encode(&4usize).into_vec()]);
|
||||||
@ -1589,7 +1589,7 @@ mod tests {
|
|||||||
assert!(aura.verify_block_family(&header, &parent_header).is_ok());
|
assert!(aura.verify_block_family(&header, &parent_header).is_ok());
|
||||||
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 0);
|
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 0);
|
||||||
|
|
||||||
aura.set_signer(Arc::new(AccountProvider::transient_provider()), Default::default(), Default::default());
|
aura.set_signer(Arc::new(AccountProvider::transient_provider()), Default::default(), "".into());
|
||||||
|
|
||||||
assert!(aura.verify_block_family(&header, &parent_header).is_ok());
|
assert!(aura.verify_block_family(&header, &parent_header).is_ok());
|
||||||
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 1);
|
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 1);
|
||||||
@ -1680,8 +1680,8 @@ mod tests {
|
|||||||
let spec = Spec::new_test_round_empty_steps();
|
let spec = Spec::new_test_round_empty_steps();
|
||||||
let tap = Arc::new(AccountProvider::transient_provider());
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
|
|
||||||
let addr1 = tap.insert_account(keccak("1").into(), "1").unwrap();
|
let addr1 = tap.insert_account(keccak("1").into(), &"1".into()).unwrap();
|
||||||
let addr2 = tap.insert_account(keccak("0").into(), "0").unwrap();
|
let addr2 = tap.insert_account(keccak("0").into(), &"0".into()).unwrap();
|
||||||
|
|
||||||
let accounts = vec![addr1, addr2];
|
let accounts = vec![addr1, addr2];
|
||||||
|
|
||||||
@ -1951,7 +1951,7 @@ mod tests {
|
|||||||
let spec = Spec::new_test_round_block_reward_contract();
|
let spec = Spec::new_test_round_block_reward_contract();
|
||||||
let tap = Arc::new(AccountProvider::transient_provider());
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
|
|
||||||
let addr1 = tap.insert_account(keccak("1").into(), "1").unwrap();
|
let addr1 = tap.insert_account(keccak("1").into(), &"1".into()).unwrap();
|
||||||
|
|
||||||
let engine = &*spec.engine;
|
let engine = &*spec.engine;
|
||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
use std::sync::{Weak, Arc};
|
use std::sync::{Weak, Arc};
|
||||||
use ethereum_types::{H256, H520, Address};
|
use ethereum_types::{H256, H520, Address};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use ethkey::{self, Signature};
|
use ethkey::{self, Password, Signature};
|
||||||
use account_provider::AccountProvider;
|
use account_provider::AccountProvider;
|
||||||
use block::*;
|
use block::*;
|
||||||
use engines::{Engine, Seal, ConstructedVerifier, EngineError};
|
use engines::{Engine, Seal, ConstructedVerifier, EngineError};
|
||||||
@ -180,7 +180,7 @@ impl Engine<EthereumMachine> for BasicAuthority {
|
|||||||
self.validators.register_client(client);
|
self.validators.register_client(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: Password) {
|
||||||
self.signer.write().set(ap, address, password);
|
self.signer.write().set(ap, address, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +243,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn can_generate_seal() {
|
fn can_generate_seal() {
|
||||||
let tap = AccountProvider::transient_provider();
|
let tap = AccountProvider::transient_provider();
|
||||||
let addr = tap.insert_account(keccak("").into(), "").unwrap();
|
let addr = tap.insert_account(keccak("").into(), &"".into()).unwrap();
|
||||||
|
|
||||||
let spec = new_test_authority();
|
let spec = new_test_authority();
|
||||||
let engine = &*spec.engine;
|
let engine = &*spec.engine;
|
||||||
@ -261,7 +261,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn seals_internally() {
|
fn seals_internally() {
|
||||||
let tap = AccountProvider::transient_provider();
|
let tap = AccountProvider::transient_provider();
|
||||||
let authority = tap.insert_account(keccak("").into(), "").unwrap();
|
let authority = tap.insert_account(keccak("").into(), &"".into()).unwrap();
|
||||||
|
|
||||||
let engine = new_test_authority().engine;
|
let engine = new_test_authority().engine;
|
||||||
assert!(!engine.seals_internally().unwrap());
|
assert!(!engine.seals_internally().unwrap());
|
||||||
|
@ -51,7 +51,7 @@ use snapshot::SnapshotComponents;
|
|||||||
use spec::CommonParams;
|
use spec::CommonParams;
|
||||||
use transaction::{self, UnverifiedTransaction, SignedTransaction};
|
use transaction::{self, UnverifiedTransaction, SignedTransaction};
|
||||||
|
|
||||||
use ethkey::Signature;
|
use ethkey::{Password, Signature};
|
||||||
use parity_machine::{Machine, LocalizedMachine as Localized, TotalScoredHeader};
|
use parity_machine::{Machine, LocalizedMachine as Localized, TotalScoredHeader};
|
||||||
use ethereum_types::{H256, U256, Address};
|
use ethereum_types::{H256, U256, Address};
|
||||||
use unexpected::{Mismatch, OutOfBounds};
|
use unexpected::{Mismatch, OutOfBounds};
|
||||||
@ -322,7 +322,7 @@ pub trait Engine<M: Machine>: Sync + Send {
|
|||||||
fn is_proposal(&self, _verified_header: &M::Header) -> bool { false }
|
fn is_proposal(&self, _verified_header: &M::Header) -> bool { false }
|
||||||
|
|
||||||
/// Register an account which signs consensus messages.
|
/// Register an account which signs consensus messages.
|
||||||
fn set_signer(&self, _account_provider: Arc<AccountProvider>, _address: Address, _password: String) {}
|
fn set_signer(&self, _account_provider: Arc<AccountProvider>, _address: Address, _password: Password) {}
|
||||||
|
|
||||||
/// Sign using the EngineSigner, to be used for consensus tx signing.
|
/// Sign using the EngineSigner, to be used for consensus tx signing.
|
||||||
fn sign(&self, _hash: H256) -> Result<Signature, M::Error> { unimplemented!() }
|
fn sign(&self, _hash: H256) -> Result<Signature, M::Error> { unimplemented!() }
|
||||||
|
@ -18,14 +18,14 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ethereum_types::{H256, Address};
|
use ethereum_types::{H256, Address};
|
||||||
use ethkey::Signature;
|
use ethkey::{Password, Signature};
|
||||||
use account_provider::{self, AccountProvider};
|
use account_provider::{self, AccountProvider};
|
||||||
|
|
||||||
/// Everything that an Engine needs to sign messages.
|
/// Everything that an Engine needs to sign messages.
|
||||||
pub struct EngineSigner {
|
pub struct EngineSigner {
|
||||||
account_provider: Arc<AccountProvider>,
|
account_provider: Arc<AccountProvider>,
|
||||||
address: Option<Address>,
|
address: Option<Address>,
|
||||||
password: Option<String>,
|
password: Option<Password>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EngineSigner {
|
impl Default for EngineSigner {
|
||||||
@ -40,7 +40,7 @@ impl Default for EngineSigner {
|
|||||||
|
|
||||||
impl EngineSigner {
|
impl EngineSigner {
|
||||||
/// Set up the signer to sign with given address and password.
|
/// Set up the signer to sign with given address and password.
|
||||||
pub fn set(&mut self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
pub fn set(&mut self, ap: Arc<AccountProvider>, address: Address, password: Password) {
|
||||||
self.account_provider = ap;
|
self.account_provider = ap;
|
||||||
self.address = Some(address);
|
self.address = Some(address);
|
||||||
self.password = Some(password);
|
self.password = Some(password);
|
||||||
|
@ -252,7 +252,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn generate_and_verify() {
|
fn generate_and_verify() {
|
||||||
let tap = Arc::new(AccountProvider::transient_provider());
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
let addr = tap.insert_account(keccak("0").into(), "0").unwrap();
|
let addr = tap.insert_account(keccak("0").into(), &"0".into()).unwrap();
|
||||||
tap.unlock_account_permanently(addr, "0".into()).unwrap();
|
tap.unlock_account_permanently(addr, "0".into()).unwrap();
|
||||||
|
|
||||||
let mi = message_info_rlp(&VoteStep::new(123, 2, Step::Precommit), Some(H256::default()));
|
let mi = message_info_rlp(&VoteStep::new(123, 2, Step::Precommit), Some(H256::default()));
|
||||||
|
@ -37,7 +37,7 @@ use bytes::Bytes;
|
|||||||
use error::{Error, BlockError};
|
use error::{Error, BlockError};
|
||||||
use header::{Header, BlockNumber, ExtendedHeader};
|
use header::{Header, BlockNumber, ExtendedHeader};
|
||||||
use rlp::Rlp;
|
use rlp::Rlp;
|
||||||
use ethkey::{self, Message, Signature};
|
use ethkey::{self, Password, Message, Signature};
|
||||||
use account_provider::AccountProvider;
|
use account_provider::AccountProvider;
|
||||||
use block::*;
|
use block::*;
|
||||||
use engines::{Engine, Seal, EngineError, ConstructedVerifier};
|
use engines::{Engine, Seal, EngineError, ConstructedVerifier};
|
||||||
@ -677,7 +677,7 @@ impl Engine<EthereumMachine> for Tendermint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: Password) {
|
||||||
{
|
{
|
||||||
self.signer.write().set(ap, address, password);
|
self.signer.write().set(ap, address, password);
|
||||||
}
|
}
|
||||||
@ -831,7 +831,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn insert_and_unlock(tap: &Arc<AccountProvider>, acc: &str) -> Address {
|
fn insert_and_unlock(tap: &Arc<AccountProvider>, acc: &str) -> Address {
|
||||||
let addr = tap.insert_account(keccak(acc).into(), acc).unwrap();
|
let addr = tap.insert_account(keccak(acc).into(), &acc.into()).unwrap();
|
||||||
tap.unlock_account_permanently(addr, acc.into()).unwrap();
|
tap.unlock_account_permanently(addr, acc.into()).unwrap();
|
||||||
addr
|
addr
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn reports_validators() {
|
fn reports_validators() {
|
||||||
let tap = Arc::new(AccountProvider::transient_provider());
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
let v1 = tap.insert_account(keccak("1").into(), "").unwrap();
|
let v1 = tap.insert_account(keccak("1").into(), &"".into()).unwrap();
|
||||||
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap.clone()));
|
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap.clone()));
|
||||||
client.engine().register_client(Arc::downgrade(&client) as _);
|
client.engine().register_client(Arc::downgrade(&client) as _);
|
||||||
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
|
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
|
||||||
|
@ -165,8 +165,8 @@ mod tests {
|
|||||||
fn uses_current_set() {
|
fn uses_current_set() {
|
||||||
let tap = Arc::new(AccountProvider::transient_provider());
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
let s0: Secret = keccak("0").into();
|
let s0: Secret = keccak("0").into();
|
||||||
let v0 = tap.insert_account(s0.clone(), "").unwrap();
|
let v0 = tap.insert_account(s0.clone(), &"".into()).unwrap();
|
||||||
let v1 = tap.insert_account(keccak("1").into(), "").unwrap();
|
let v1 = tap.insert_account(keccak("1").into(), &"".into()).unwrap();
|
||||||
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_multi, Some(tap));
|
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_multi, Some(tap));
|
||||||
client.engine().register_client(Arc::downgrade(&client) as _);
|
client.engine().register_client(Arc::downgrade(&client) as _);
|
||||||
|
|
||||||
|
@ -477,8 +477,8 @@ mod tests {
|
|||||||
fn knows_validators() {
|
fn knows_validators() {
|
||||||
let tap = Arc::new(AccountProvider::transient_provider());
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
let s0: Secret = keccak("1").into();
|
let s0: Secret = keccak("1").into();
|
||||||
let v0 = tap.insert_account(s0.clone(), "").unwrap();
|
let v0 = tap.insert_account(s0.clone(), &"".into()).unwrap();
|
||||||
let v1 = tap.insert_account(keccak("0").into(), "").unwrap();
|
let v1 = tap.insert_account(keccak("0").into(), &"".into()).unwrap();
|
||||||
let chain_id = Spec::new_validator_safe_contract().chain_id();
|
let chain_id = Spec::new_validator_safe_contract().chain_id();
|
||||||
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap));
|
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap));
|
||||||
client.engine().register_client(Arc::downgrade(&client) as _);
|
client.engine().register_client(Arc::downgrade(&client) as _);
|
||||||
|
@ -50,6 +50,7 @@ use miner::pool_client::{PoolClient, CachedNonceClient};
|
|||||||
use receipt::{Receipt, RichReceipt};
|
use receipt::{Receipt, RichReceipt};
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use state::State;
|
use state::State;
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
/// Different possible definitions for pending transaction set.
|
/// Different possible definitions for pending transaction set.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@ -736,12 +737,12 @@ impl miner::MinerService for Miner {
|
|||||||
self.params.write().extra_data = extra_data;
|
self.params.write().extra_data = extra_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_author(&self, address: Address, password: Option<String>) -> Result<(), AccountError> {
|
fn set_author(&self, address: Address, password: Option<Password>) -> Result<(), AccountError> {
|
||||||
self.params.write().author = address;
|
self.params.write().author = address;
|
||||||
|
|
||||||
if self.engine.seals_internally().is_some() && password.is_some() {
|
if self.engine.seals_internally().is_some() && password.is_some() {
|
||||||
if let Some(ref ap) = self.accounts {
|
if let Some(ref ap) = self.accounts {
|
||||||
let password = password.unwrap_or_default();
|
let password = password.unwrap_or_else(|| Password::from(String::new()));
|
||||||
// Sign test message
|
// Sign test message
|
||||||
ap.sign(address.clone(), Some(password.clone()), Default::default())?;
|
ap.sign(address.clone(), Some(password.clone()), Default::default())?;
|
||||||
// Enable sealing
|
// Enable sealing
|
||||||
@ -1285,7 +1286,7 @@ mod tests {
|
|||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
let client = TestBlockChainClient::default();
|
let client = TestBlockChainClient::default();
|
||||||
let account_provider = AccountProvider::transient_provider();
|
let account_provider = AccountProvider::transient_provider();
|
||||||
account_provider.insert_account(keypair.secret().clone(), "").expect("can add accounts to the provider we just created");
|
account_provider.insert_account(keypair.secret().clone(), &"".into()).expect("can add accounts to the provider we just created");
|
||||||
|
|
||||||
let miner = Miner::new(
|
let miner = Miner::new(
|
||||||
MinerOptions {
|
MinerOptions {
|
||||||
@ -1366,7 +1367,7 @@ mod tests {
|
|||||||
fn should_fail_setting_engine_signer_without_account_provider() {
|
fn should_fail_setting_engine_signer_without_account_provider() {
|
||||||
let spec = Spec::new_instant;
|
let spec = Spec::new_instant;
|
||||||
let tap = Arc::new(AccountProvider::transient_provider());
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
let addr = tap.insert_account(keccak("1").into(), "").unwrap();
|
let addr = tap.insert_account(keccak("1").into(), &"".into()).unwrap();
|
||||||
let client = generate_dummy_client_with_spec_and_accounts(spec, None);
|
let client = generate_dummy_client_with_spec_and_accounts(spec, None);
|
||||||
assert!(match client.miner().set_author(addr, Some("".into())) { Err(AccountError::NotFound) => true, _ => false });
|
assert!(match client.miner().set_author(addr, Some("".into())) { Err(AccountError::NotFound) => true, _ => false });
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ use header::{BlockNumber, Header};
|
|||||||
use receipt::{RichReceipt, Receipt};
|
use receipt::{RichReceipt, Receipt};
|
||||||
use transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction};
|
use transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction};
|
||||||
use state::StateInfo;
|
use state::StateInfo;
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
/// Provides methods to verify incoming external transactions
|
/// Provides methods to verify incoming external transactions
|
||||||
pub trait TransactionVerifierClient: Send + Sync
|
pub trait TransactionVerifierClient: Send + Sync
|
||||||
@ -124,7 +125,7 @@ pub trait MinerService : Send + Sync {
|
|||||||
/// Set info necessary to sign consensus messages and block authoring.
|
/// Set info necessary to sign consensus messages and block authoring.
|
||||||
///
|
///
|
||||||
/// On PoW password is optional.
|
/// On PoW password is optional.
|
||||||
fn set_author(&self, address: Address, password: Option<String>) -> Result<(), ::account_provider::SignError>;
|
fn set_author(&self, address: Address, password: Option<Password>) -> Result<(), ::account_provider::SignError>;
|
||||||
|
|
||||||
// Transaction Pool
|
// Transaction Pool
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ fn make_accounts(secrets: &[Secret]) -> (Arc<AccountProvider>, Vec<Address>) {
|
|||||||
|
|
||||||
let addrs = secrets.iter()
|
let addrs = secrets.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|s| provider.insert_account(s, PASS).unwrap())
|
.map(|s| provider.insert_account(s, &PASS.into()).unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
(Arc::new(provider), addrs)
|
(Arc::new(provider), addrs)
|
||||||
|
@ -44,8 +44,8 @@ fn authority_round() {
|
|||||||
let s0 = KeyPair::from_secret_slice(&keccak("1")).unwrap();
|
let s0 = KeyPair::from_secret_slice(&keccak("1")).unwrap();
|
||||||
let s1 = KeyPair::from_secret_slice(&keccak("0")).unwrap();
|
let s1 = KeyPair::from_secret_slice(&keccak("0")).unwrap();
|
||||||
let ap = Arc::new(AccountProvider::transient_provider());
|
let ap = Arc::new(AccountProvider::transient_provider());
|
||||||
ap.insert_account(s0.secret().clone(), "").unwrap();
|
ap.insert_account(s0.secret().clone(), &"".into()).unwrap();
|
||||||
ap.insert_account(s1.secret().clone(), "").unwrap();
|
ap.insert_account(s1.secret().clone(), &"".into()).unwrap();
|
||||||
|
|
||||||
let chain_id = Spec::new_test_round().chain_id();
|
let chain_id = Spec::new_test_round().chain_id();
|
||||||
let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_round, Some(ap));
|
let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_round, Some(ap));
|
||||||
@ -53,7 +53,7 @@ fn authority_round() {
|
|||||||
let io_handler1: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
|
let io_handler1: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
|
||||||
// Push transaction to both clients. Only one of them gets lucky to produce a block.
|
// Push transaction to both clients. Only one of them gets lucky to produce a block.
|
||||||
net.peer(0).miner.set_author(s0.address(), Some("".into())).unwrap();
|
net.peer(0).miner.set_author(s0.address(), Some("".into())).unwrap();
|
||||||
net.peer(1).miner.set_author(s1.address(), Some("".to_owned())).unwrap();
|
net.peer(1).miner.set_author(s1.address(), Some("".into())).unwrap();
|
||||||
net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _);
|
net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _);
|
||||||
net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _);
|
net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _);
|
||||||
net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler1)));
|
net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler1)));
|
||||||
@ -131,8 +131,8 @@ fn tendermint() {
|
|||||||
let s0 = KeyPair::from_secret_slice(&keccak("1")).unwrap();
|
let s0 = KeyPair::from_secret_slice(&keccak("1")).unwrap();
|
||||||
let s1 = KeyPair::from_secret_slice(&keccak("0")).unwrap();
|
let s1 = KeyPair::from_secret_slice(&keccak("0")).unwrap();
|
||||||
let ap = Arc::new(AccountProvider::transient_provider());
|
let ap = Arc::new(AccountProvider::transient_provider());
|
||||||
ap.insert_account(s0.secret().clone(), "").unwrap();
|
ap.insert_account(s0.secret().clone(), &"".into()).unwrap();
|
||||||
ap.insert_account(s1.secret().clone(), "").unwrap();
|
ap.insert_account(s1.secret().clone(), &"".into()).unwrap();
|
||||||
|
|
||||||
let chain_id = Spec::new_test_tendermint().chain_id();
|
let chain_id = Spec::new_test_tendermint().chain_id();
|
||||||
let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_tendermint, Some(ap));
|
let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_tendermint, Some(ap));
|
||||||
|
@ -42,8 +42,8 @@ fn send_private_transaction() {
|
|||||||
let s0 = KeyPair::from_secret_slice(&keccak("1")).unwrap();
|
let s0 = KeyPair::from_secret_slice(&keccak("1")).unwrap();
|
||||||
let s1 = KeyPair::from_secret_slice(&keccak("0")).unwrap();
|
let s1 = KeyPair::from_secret_slice(&keccak("0")).unwrap();
|
||||||
let ap = Arc::new(AccountProvider::transient_provider());
|
let ap = Arc::new(AccountProvider::transient_provider());
|
||||||
ap.insert_account(s0.secret().clone(), "").unwrap();
|
ap.insert_account(s0.secret().clone(), &"".into()).unwrap();
|
||||||
ap.insert_account(s1.secret().clone(), "").unwrap();
|
ap.insert_account(s1.secret().clone(), &"".into()).unwrap();
|
||||||
|
|
||||||
let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), seal_spec, Some(ap.clone()));
|
let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), seal_spec, Some(ap.clone()));
|
||||||
let client0 = net.peer(0).chain.clone();
|
let client0 = net.peer(0).chain.clone();
|
||||||
@ -52,7 +52,7 @@ fn send_private_transaction() {
|
|||||||
let io_handler1: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
|
let io_handler1: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
|
||||||
|
|
||||||
net.peer(0).miner.set_author(s0.address(), Some("".into())).unwrap();
|
net.peer(0).miner.set_author(s0.address(), Some("".into())).unwrap();
|
||||||
net.peer(1).miner.set_author(s1.address(), Some("".to_owned())).unwrap();
|
net.peer(1).miner.set_author(s1.address(), Some("".into())).unwrap();
|
||||||
net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _);
|
net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _);
|
||||||
net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _);
|
net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _);
|
||||||
net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler0)));
|
net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler0)));
|
||||||
|
@ -16,4 +16,6 @@ parity-wordlist = "1.2"
|
|||||||
quick-error = "1.2"
|
quick-error = "1.2"
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
rustc-hex = "1.0"
|
rustc-hex = "1.0"
|
||||||
|
serde = "1.0"
|
||||||
|
serde_derive = "1.0"
|
||||||
tiny-keccak = "1.4"
|
tiny-keccak = "1.4"
|
||||||
|
@ -27,18 +27,22 @@ extern crate quick_error;
|
|||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate rustc_hex;
|
extern crate rustc_hex;
|
||||||
extern crate secp256k1;
|
extern crate secp256k1;
|
||||||
|
extern crate serde;
|
||||||
extern crate tiny_keccak;
|
extern crate tiny_keccak;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
mod brain;
|
mod brain;
|
||||||
mod brain_prefix;
|
mod brain_prefix;
|
||||||
mod error;
|
mod error;
|
||||||
mod keypair;
|
mod keypair;
|
||||||
mod keccak;
|
mod keccak;
|
||||||
|
mod password;
|
||||||
mod prefix;
|
mod prefix;
|
||||||
mod random;
|
mod random;
|
||||||
mod signature;
|
mod signature;
|
||||||
@ -55,6 +59,7 @@ pub use self::brain_prefix::BrainPrefix;
|
|||||||
pub use self::error::Error;
|
pub use self::error::Error;
|
||||||
pub use self::keypair::{KeyPair, public_to_address};
|
pub use self::keypair::{KeyPair, public_to_address};
|
||||||
pub use self::math::public_is_valid;
|
pub use self::math::public_is_valid;
|
||||||
|
pub use self::password::Password;
|
||||||
pub use self::prefix::Prefix;
|
pub use self::prefix::Prefix;
|
||||||
pub use self::random::Random;
|
pub use self::random::Random;
|
||||||
pub use self::signature::{sign, verify_public, verify_address, recover, Signature};
|
pub use self::signature::{sign, verify_public, verify_address, recover, Signature};
|
||||||
|
60
ethkey/src/password.rs
Normal file
60
ethkey/src/password.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// Copyright 2018 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity 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.
|
||||||
|
|
||||||
|
// Parity 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 Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::{fmt, ptr};
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct Password(String);
|
||||||
|
|
||||||
|
impl fmt::Debug for Password {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "Password(******)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Password {
|
||||||
|
pub fn as_bytes(&self) -> &[u8] {
|
||||||
|
self.0.as_bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
self.0.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom drop impl to zero out memory.
|
||||||
|
impl Drop for Password {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
for byte_ref in self.0.as_mut_vec() {
|
||||||
|
ptr::write_volatile(byte_ref, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for Password {
|
||||||
|
fn from(s: String) -> Password {
|
||||||
|
Password(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a str> for Password {
|
||||||
|
fn from(s: &'a str) -> Password {
|
||||||
|
Password::from(String::from(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,10 +19,10 @@ use std::sync::Arc;
|
|||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
use ethstore::{PresaleWallet, Error};
|
use ethstore::{ethkey::Password, PresaleWallet, Error};
|
||||||
use num_cpus;
|
use num_cpus;
|
||||||
|
|
||||||
pub fn run(passwords: VecDeque<String>, wallet_path: &str) -> Result<(), Error> {
|
pub fn run(passwords: VecDeque<Password>, wallet_path: &str) -> Result<(), Error> {
|
||||||
let passwords = Arc::new(Mutex::new(passwords));
|
let passwords = Arc::new(Mutex::new(passwords));
|
||||||
|
|
||||||
let mut handles = Vec::new();
|
let mut handles = Vec::new();
|
||||||
@ -42,7 +42,7 @@ pub fn run(passwords: VecDeque<String>, wallet_path: &str) -> Result<(), Error>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn look_for_password(passwords: Arc<Mutex<VecDeque<String>>>, wallet: PresaleWallet) {
|
fn look_for_password(passwords: Arc<Mutex<VecDeque<Password>>>, wallet: PresaleWallet) {
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
while !passwords.lock().is_empty() {
|
while !passwords.lock().is_empty() {
|
||||||
let package = {
|
let package = {
|
||||||
@ -54,7 +54,7 @@ fn look_for_password(passwords: Arc<Mutex<VecDeque<String>>>, wallet: PresaleWal
|
|||||||
counter += 1;
|
counter += 1;
|
||||||
match wallet.decrypt(&pass) {
|
match wallet.decrypt(&pass) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
println!("Found password: {}", &pass);
|
println!("Found password: {}", pass.as_str());
|
||||||
passwords.lock().clear();
|
passwords.lock().clear();
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
@ -32,7 +32,7 @@ use std::{env, process, fs, fmt};
|
|||||||
|
|
||||||
use docopt::Docopt;
|
use docopt::Docopt;
|
||||||
use ethstore::accounts_dir::{KeyDirectory, RootDiskDirectory};
|
use ethstore::accounts_dir::{KeyDirectory, RootDiskDirectory};
|
||||||
use ethstore::ethkey::Address;
|
use ethstore::ethkey::{Address, Password};
|
||||||
use ethstore::{EthStore, SimpleSecretStore, SecretStore, import_accounts, PresaleWallet, SecretVaultRef, StoreAccountRef};
|
use ethstore::{EthStore, SimpleSecretStore, SecretStore, import_accounts, PresaleWallet, SecretVaultRef, StoreAccountRef};
|
||||||
|
|
||||||
mod crack;
|
mod crack;
|
||||||
@ -201,13 +201,13 @@ fn format_vaults(vaults: &[String]) -> String {
|
|||||||
vaults.join("\n")
|
vaults.join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_password(path: &str) -> Result<String, Error> {
|
fn load_password(path: &str) -> Result<Password, Error> {
|
||||||
let mut file = fs::File::open(path).map_err(|e| ethstore::Error::Custom(format!("Error opening password file {}: {}", path, e)))?;
|
let mut file = fs::File::open(path).map_err(|e| ethstore::Error::Custom(format!("Error opening password file {}: {}", path, e)))?;
|
||||||
let mut password = String::new();
|
let mut password = String::new();
|
||||||
file.read_to_string(&mut password).map_err(|e| ethstore::Error::Custom(format!("Error reading password file {}: {}", path, e)))?;
|
file.read_to_string(&mut password).map_err(|e| ethstore::Error::Custom(format!("Error reading password file {}: {}", path, e)))?;
|
||||||
// drop EOF
|
// drop EOF
|
||||||
let _ = password.pop();
|
let _ = password.pop();
|
||||||
Ok(password)
|
Ok(password.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item=S>, S: AsRef<str> {
|
fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item=S>, S: AsRef<str> {
|
||||||
@ -252,7 +252,7 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
|
|||||||
Ok(format!("0x{:x}", account_ref.address))
|
Ok(format!("0x{:x}", account_ref.address))
|
||||||
} else if args.cmd_find_wallet_pass {
|
} else if args.cmd_find_wallet_pass {
|
||||||
let passwords = load_password(&args.arg_password)?;
|
let passwords = load_password(&args.arg_password)?;
|
||||||
let passwords = passwords.lines().map(str::to_owned).collect::<VecDeque<_>>();
|
let passwords = passwords.as_str().lines().map(|line| str::to_owned(line).into()).collect::<VecDeque<_>>();
|
||||||
crack::run(passwords, &args.arg_path)?;
|
crack::run(passwords, &args.arg_path)?;
|
||||||
Ok(format!("Password not found."))
|
Ok(format!("Password not found."))
|
||||||
} else if args.cmd_remove {
|
} else if args.cmd_remove {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::str;
|
use std::str;
|
||||||
use ethkey::Secret;
|
use ethkey::{Password, Secret};
|
||||||
use {json, Error, crypto};
|
use {json, Error, crypto};
|
||||||
use crypto::Keccak256;
|
use crypto::Keccak256;
|
||||||
use random::Random;
|
use random::Random;
|
||||||
@ -73,18 +73,18 @@ impl From<Crypto> for String {
|
|||||||
|
|
||||||
impl Crypto {
|
impl Crypto {
|
||||||
/// Encrypt account secret
|
/// Encrypt account secret
|
||||||
pub fn with_secret(secret: &Secret, password: &str, iterations: u32) -> Result<Self, crypto::Error> {
|
pub fn with_secret(secret: &Secret, password: &Password, iterations: u32) -> Result<Self, crypto::Error> {
|
||||||
Crypto::with_plain(&*secret, password, iterations)
|
Crypto::with_plain(&*secret, password, iterations)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encrypt custom plain data
|
/// Encrypt custom plain data
|
||||||
pub fn with_plain(plain: &[u8], password: &str, iterations: u32) -> Result<Self, crypto::Error> {
|
pub fn with_plain(plain: &[u8], password: &Password, iterations: u32) -> Result<Self, crypto::Error> {
|
||||||
let salt: [u8; 32] = Random::random();
|
let salt: [u8; 32] = Random::random();
|
||||||
let iv: [u8; 16] = Random::random();
|
let iv: [u8; 16] = Random::random();
|
||||||
|
|
||||||
// two parts of derived key
|
// two parts of derived key
|
||||||
// DK = [ DK[0..15] DK[16..31] ] = [derived_left_bits, derived_right_bits]
|
// DK = [ DK[0..15] DK[16..31] ] = [derived_left_bits, derived_right_bits]
|
||||||
let (derived_left_bits, derived_right_bits) = crypto::derive_key_iterations(password, &salt, iterations);
|
let (derived_left_bits, derived_right_bits) = crypto::derive_key_iterations(password.as_bytes(), &salt, iterations);
|
||||||
|
|
||||||
// preallocated (on-stack in case of `Secret`) buffer to hold cipher
|
// preallocated (on-stack in case of `Secret`) buffer to hold cipher
|
||||||
// length = length(plain) as we are using CTR-approach
|
// length = length(plain) as we are using CTR-approach
|
||||||
@ -113,7 +113,7 @@ impl Crypto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Try to decrypt and convert result to account secret
|
/// Try to decrypt and convert result to account secret
|
||||||
pub fn secret(&self, password: &str) -> Result<Secret, Error> {
|
pub fn secret(&self, password: &Password) -> Result<Secret, Error> {
|
||||||
if self.ciphertext.len() > 32 {
|
if self.ciphertext.len() > 32 {
|
||||||
return Err(Error::InvalidSecret);
|
return Err(Error::InvalidSecret);
|
||||||
}
|
}
|
||||||
@ -123,15 +123,15 @@ impl Crypto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Try to decrypt and return result as is
|
/// Try to decrypt and return result as is
|
||||||
pub fn decrypt(&self, password: &str) -> Result<Vec<u8>, Error> {
|
pub fn decrypt(&self, password: &Password) -> Result<Vec<u8>, Error> {
|
||||||
let expected_len = self.ciphertext.len();
|
let expected_len = self.ciphertext.len();
|
||||||
self.do_decrypt(password, expected_len)
|
self.do_decrypt(password, expected_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_decrypt(&self, password: &str, expected_len: usize) -> Result<Vec<u8>, Error> {
|
fn do_decrypt(&self, password: &Password, expected_len: usize) -> Result<Vec<u8>, Error> {
|
||||||
let (derived_left_bits, derived_right_bits) = match self.kdf {
|
let (derived_left_bits, derived_right_bits) = match self.kdf {
|
||||||
Kdf::Pbkdf2(ref params) => crypto::derive_key_iterations(password, ¶ms.salt, params.c),
|
Kdf::Pbkdf2(ref params) => crypto::derive_key_iterations(password.as_bytes(), ¶ms.salt, params.c),
|
||||||
Kdf::Scrypt(ref params) => crypto::scrypt::derive_key(password, ¶ms.salt, params.n, params.p, params.r)?,
|
Kdf::Scrypt(ref params) => crypto::scrypt::derive_key(password.as_bytes(), ¶ms.salt, params.n, params.p, params.r)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mac = crypto::derive_mac(&derived_right_bits, &self.ciphertext).keccak256();
|
let mac = crypto::derive_mac(&derived_right_bits, &self.ciphertext).keccak256();
|
||||||
@ -163,39 +163,43 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn crypto_with_secret_create() {
|
fn crypto_with_secret_create() {
|
||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
let crypto = Crypto::with_secret(keypair.secret(), "this is sparta", 10240).unwrap();
|
let passwd = "this is sparta".into();
|
||||||
let secret = crypto.secret("this is sparta").unwrap();
|
let crypto = Crypto::with_secret(keypair.secret(), &passwd, 10240).unwrap();
|
||||||
|
let secret = crypto.secret(&passwd).unwrap();
|
||||||
assert_eq!(keypair.secret(), &secret);
|
assert_eq!(keypair.secret(), &secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn crypto_with_secret_invalid_password() {
|
fn crypto_with_secret_invalid_password() {
|
||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
let crypto = Crypto::with_secret(keypair.secret(), "this is sparta", 10240).unwrap();
|
let crypto = Crypto::with_secret(keypair.secret(), &"this is sparta".into(), 10240).unwrap();
|
||||||
assert_matches!(crypto.secret("this is sparta!"), Err(Error::InvalidPassword))
|
assert_matches!(crypto.secret(&"this is sparta!".into()), Err(Error::InvalidPassword))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn crypto_with_null_plain_data() {
|
fn crypto_with_null_plain_data() {
|
||||||
let original_data = b"";
|
let original_data = b"";
|
||||||
let crypto = Crypto::with_plain(&original_data[..], "this is sparta", 10240).unwrap();
|
let passwd = "this is sparta".into();
|
||||||
let decrypted_data = crypto.decrypt("this is sparta").unwrap();
|
let crypto = Crypto::with_plain(&original_data[..], &passwd, 10240).unwrap();
|
||||||
|
let decrypted_data = crypto.decrypt(&passwd).unwrap();
|
||||||
assert_eq!(original_data[..], *decrypted_data);
|
assert_eq!(original_data[..], *decrypted_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn crypto_with_tiny_plain_data() {
|
fn crypto_with_tiny_plain_data() {
|
||||||
let original_data = b"{}";
|
let original_data = b"{}";
|
||||||
let crypto = Crypto::with_plain(&original_data[..], "this is sparta", 10240).unwrap();
|
let passwd = "this is sparta".into();
|
||||||
let decrypted_data = crypto.decrypt("this is sparta").unwrap();
|
let crypto = Crypto::with_plain(&original_data[..], &passwd, 10240).unwrap();
|
||||||
|
let decrypted_data = crypto.decrypt(&passwd).unwrap();
|
||||||
assert_eq!(original_data[..], *decrypted_data);
|
assert_eq!(original_data[..], *decrypted_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn crypto_with_huge_plain_data() {
|
fn crypto_with_huge_plain_data() {
|
||||||
let original_data: Vec<_> = (1..65536).map(|i| (i % 256) as u8).collect();
|
let original_data: Vec<_> = (1..65536).map(|i| (i % 256) as u8).collect();
|
||||||
let crypto = Crypto::with_plain(&original_data, "this is sparta", 10240).unwrap();
|
let passwd = "this is sparta".into();
|
||||||
let decrypted_data = crypto.decrypt("this is sparta").unwrap();
|
let crypto = Crypto::with_plain(&original_data, &passwd, 10240).unwrap();
|
||||||
|
let decrypted_data = crypto.decrypt(&passwd).unwrap();
|
||||||
assert_eq!(&original_data, &decrypted_data);
|
assert_eq!(&original_data, &decrypted_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use ethkey::{self, KeyPair, sign, Address, Signature, Message, Public, Secret};
|
use ethkey::{self, KeyPair, sign, Address, Password, Signature, Message, Public, Secret};
|
||||||
use ethkey::crypto::ecdh::agree;
|
use ethkey::crypto::ecdh::agree;
|
||||||
use {json, Error};
|
use {json, Error};
|
||||||
use account::Version;
|
use account::Version;
|
||||||
@ -58,7 +58,7 @@ impl SafeAccount {
|
|||||||
pub fn create(
|
pub fn create(
|
||||||
keypair: &KeyPair,
|
keypair: &KeyPair,
|
||||||
id: [u8; 16],
|
id: [u8; 16],
|
||||||
password: &str,
|
password: &Password,
|
||||||
iterations: u32,
|
iterations: u32,
|
||||||
name: String,
|
name: String,
|
||||||
meta: String
|
meta: String
|
||||||
@ -92,7 +92,7 @@ impl SafeAccount {
|
|||||||
/// Create a new `SafeAccount` from the given vault `json`; if it was read from a
|
/// Create a new `SafeAccount` from the given vault `json`; if it was read from a
|
||||||
/// file, the `filename` should be `Some` name. If it is as yet anonymous, then it
|
/// file, the `filename` should be `Some` name. If it is as yet anonymous, then it
|
||||||
/// can be left `None`.
|
/// can be left `None`.
|
||||||
pub fn from_vault_file(password: &str, json: json::VaultKeyFile, filename: Option<String>) -> Result<Self, Error> {
|
pub fn from_vault_file(password: &Password, json: json::VaultKeyFile, filename: Option<String>) -> Result<Self, Error> {
|
||||||
let meta_crypto: Crypto = json.metacrypto.into();
|
let meta_crypto: Crypto = json.metacrypto.into();
|
||||||
let meta_plain = meta_crypto.decrypt(password)?;
|
let meta_plain = meta_crypto.decrypt(password)?;
|
||||||
let meta_plain = json::VaultKeyMeta::load(&meta_plain).map_err(|e| Error::Custom(format!("{:?}", e)))?;
|
let meta_plain = json::VaultKeyMeta::load(&meta_plain).map_err(|e| Error::Custom(format!("{:?}", e)))?;
|
||||||
@ -108,7 +108,7 @@ impl SafeAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new `VaultKeyFile` from the given `self`
|
/// Create a new `VaultKeyFile` from the given `self`
|
||||||
pub fn into_vault_file(self, iterations: u32, password: &str) -> Result<json::VaultKeyFile, Error> {
|
pub fn into_vault_file(self, iterations: u32, password: &Password) -> Result<json::VaultKeyFile, Error> {
|
||||||
let meta_plain = json::VaultKeyMeta {
|
let meta_plain = json::VaultKeyMeta {
|
||||||
address: self.address.into(),
|
address: self.address.into(),
|
||||||
name: Some(self.name),
|
name: Some(self.name),
|
||||||
@ -126,31 +126,31 @@ impl SafeAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sign a message.
|
/// Sign a message.
|
||||||
pub fn sign(&self, password: &str, message: &Message) -> Result<Signature, Error> {
|
pub fn sign(&self, password: &Password, message: &Message) -> Result<Signature, Error> {
|
||||||
let secret = self.crypto.secret(password)?;
|
let secret = self.crypto.secret(password)?;
|
||||||
sign(&secret, message).map_err(From::from)
|
sign(&secret, message).map_err(From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypt a message.
|
/// Decrypt a message.
|
||||||
pub fn decrypt(&self, password: &str, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
|
pub fn decrypt(&self, password: &Password, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
|
||||||
let secret = self.crypto.secret(password)?;
|
let secret = self.crypto.secret(password)?;
|
||||||
ethkey::crypto::ecies::decrypt(&secret, shared_mac, message).map_err(From::from)
|
ethkey::crypto::ecies::decrypt(&secret, shared_mac, message).map_err(From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Agree on shared key.
|
/// Agree on shared key.
|
||||||
pub fn agree(&self, password: &str, other: &Public) -> Result<Secret, Error> {
|
pub fn agree(&self, password: &Password, other: &Public) -> Result<Secret, Error> {
|
||||||
let secret = self.crypto.secret(password)?;
|
let secret = self.crypto.secret(password)?;
|
||||||
agree(&secret, other).map_err(From::from)
|
agree(&secret, other).map_err(From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Derive public key.
|
/// Derive public key.
|
||||||
pub fn public(&self, password: &str) -> Result<Public, Error> {
|
pub fn public(&self, password: &Password) -> Result<Public, Error> {
|
||||||
let secret = self.crypto.secret(password)?;
|
let secret = self.crypto.secret(password)?;
|
||||||
Ok(KeyPair::from_secret(secret)?.public().clone())
|
Ok(KeyPair::from_secret(secret)?.public().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change account's password.
|
/// Change account's password.
|
||||||
pub fn change_password(&self, old_password: &str, new_password: &str, iterations: u32) -> Result<Self, Error> {
|
pub fn change_password(&self, old_password: &Password, new_password: &Password, iterations: u32) -> Result<Self, Error> {
|
||||||
let secret = self.crypto.secret(old_password)?;
|
let secret = self.crypto.secret(old_password)?;
|
||||||
let result = SafeAccount {
|
let result = SafeAccount {
|
||||||
id: self.id.clone(),
|
id: self.id.clone(),
|
||||||
@ -165,7 +165,7 @@ impl SafeAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check if password matches the account.
|
/// Check if password matches the account.
|
||||||
pub fn check_password(&self, password: &str) -> bool {
|
pub fn check_password(&self, password: &Password) -> bool {
|
||||||
self.crypto.secret(password).is_ok()
|
self.crypto.secret(password).is_ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,25 +178,25 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn sign_and_verify_public() {
|
fn sign_and_verify_public() {
|
||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
let password = "hello world";
|
let password = "hello world".into();
|
||||||
let message = Message::default();
|
let message = Message::default();
|
||||||
let account = SafeAccount::create(&keypair, [0u8; 16], password, 10240, "Test".to_owned(), "{}".to_owned());
|
let account = SafeAccount::create(&keypair, [0u8; 16], &password, 10240, "Test".to_owned(), "{}".to_owned());
|
||||||
let signature = account.unwrap().sign(password, &message).unwrap();
|
let signature = account.unwrap().sign(&password, &message).unwrap();
|
||||||
assert!(verify_public(keypair.public(), &signature, &message).unwrap());
|
assert!(verify_public(keypair.public(), &signature, &message).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn change_password() {
|
fn change_password() {
|
||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
let first_password = "hello world";
|
let first_password = "hello world".into();
|
||||||
let sec_password = "this is sparta";
|
let sec_password = "this is sparta".into();
|
||||||
let i = 10240;
|
let i = 10240;
|
||||||
let message = Message::default();
|
let message = Message::default();
|
||||||
let account = SafeAccount::create(&keypair, [0u8; 16], first_password, i, "Test".to_owned(), "{}".to_owned()).unwrap();
|
let account = SafeAccount::create(&keypair, [0u8; 16], &first_password, i, "Test".to_owned(), "{}".to_owned()).unwrap();
|
||||||
let new_account = account.change_password(first_password, sec_password, i).unwrap();
|
let new_account = account.change_password(&first_password, &sec_password, i).unwrap();
|
||||||
assert!(account.sign(first_password, &message).is_ok());
|
assert!(account.sign(&first_password, &message).is_ok());
|
||||||
assert!(account.sign(sec_password, &message).is_err());
|
assert!(account.sign(&sec_password, &message).is_err());
|
||||||
assert!(new_account.sign(first_password, &message).is_err());
|
assert!(new_account.sign(&first_password, &message).is_err());
|
||||||
assert!(new_account.sign(sec_password, &message).is_ok());
|
assert!(new_account.sign(&sec_password, &message).is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,11 +357,11 @@ mod test {
|
|||||||
let mut dir = env::temp_dir();
|
let mut dir = env::temp_dir();
|
||||||
dir.push("ethstore_should_create_new_account");
|
dir.push("ethstore_should_create_new_account");
|
||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
let password = "hello world";
|
let password = "hello world".into();
|
||||||
let directory = RootDiskDirectory::create(dir.clone()).unwrap();
|
let directory = RootDiskDirectory::create(dir.clone()).unwrap();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let account = SafeAccount::create(&keypair, [0u8; 16], password, 1024, "Test".to_owned(), "{}".to_owned());
|
let account = SafeAccount::create(&keypair, [0u8; 16], &password, 1024, "Test".to_owned(), "{}".to_owned());
|
||||||
let res = directory.insert(account.unwrap());
|
let res = directory.insert(account.unwrap());
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@ -378,11 +378,11 @@ mod test {
|
|||||||
let mut dir = env::temp_dir();
|
let mut dir = env::temp_dir();
|
||||||
dir.push("ethstore_should_handle_duplicate_filenames");
|
dir.push("ethstore_should_handle_duplicate_filenames");
|
||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
let password = "hello world";
|
let password = "hello world".into();
|
||||||
let directory = RootDiskDirectory::create(dir.clone()).unwrap();
|
let directory = RootDiskDirectory::create(dir.clone()).unwrap();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let account = SafeAccount::create(&keypair, [0u8; 16], password, 1024, "Test".to_owned(), "{}".to_owned()).unwrap();
|
let account = SafeAccount::create(&keypair, [0u8; 16], &password, 1024, "Test".to_owned(), "{}".to_owned()).unwrap();
|
||||||
let filename = "test".to_string();
|
let filename = "test".to_string();
|
||||||
let dedup = true;
|
let dedup = true;
|
||||||
|
|
||||||
@ -411,14 +411,14 @@ mod test {
|
|||||||
dir.push("should_create_new_vault");
|
dir.push("should_create_new_vault");
|
||||||
let directory = RootDiskDirectory::create(dir.clone()).unwrap();
|
let directory = RootDiskDirectory::create(dir.clone()).unwrap();
|
||||||
let vault_name = "vault";
|
let vault_name = "vault";
|
||||||
let password = "password";
|
let password = "password".into();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert!(directory.as_vault_provider().is_some());
|
assert!(directory.as_vault_provider().is_some());
|
||||||
|
|
||||||
// and when
|
// and when
|
||||||
let before_root_items_count = fs::read_dir(&dir).unwrap().count();
|
let before_root_items_count = fs::read_dir(&dir).unwrap().count();
|
||||||
let vault = directory.as_vault_provider().unwrap().create(vault_name, VaultKey::new(password, 1024));
|
let vault = directory.as_vault_provider().unwrap().create(vault_name, VaultKey::new(&password, 1024));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert!(vault.is_ok());
|
assert!(vault.is_ok());
|
||||||
@ -426,7 +426,7 @@ mod test {
|
|||||||
assert!(after_root_items_count > before_root_items_count);
|
assert!(after_root_items_count > before_root_items_count);
|
||||||
|
|
||||||
// and when
|
// and when
|
||||||
let vault = directory.as_vault_provider().unwrap().open(vault_name, VaultKey::new(password, 1024));
|
let vault = directory.as_vault_provider().unwrap().open(vault_name, VaultKey::new(&password, 1024));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert!(vault.is_ok());
|
assert!(vault.is_ok());
|
||||||
@ -443,8 +443,8 @@ mod test {
|
|||||||
let temp_path = TempDir::new("").unwrap();
|
let temp_path = TempDir::new("").unwrap();
|
||||||
let directory = RootDiskDirectory::create(&temp_path).unwrap();
|
let directory = RootDiskDirectory::create(&temp_path).unwrap();
|
||||||
let vault_provider = directory.as_vault_provider().unwrap();
|
let vault_provider = directory.as_vault_provider().unwrap();
|
||||||
vault_provider.create("vault1", VaultKey::new("password1", 1)).unwrap();
|
vault_provider.create("vault1", VaultKey::new(&"password1".into(), 1)).unwrap();
|
||||||
vault_provider.create("vault2", VaultKey::new("password2", 1)).unwrap();
|
vault_provider.create("vault2", VaultKey::new(&"password2".into(), 1)).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let vaults = vault_provider.list_vaults().unwrap();
|
let vaults = vault_provider.list_vaults().unwrap();
|
||||||
@ -465,8 +465,8 @@ mod test {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
let password = "test pass";
|
let password = "test pass".into();
|
||||||
let account = SafeAccount::create(&keypair, [0u8; 16], password, 1024, "Test".to_owned(), "{}".to_owned());
|
let account = SafeAccount::create(&keypair, [0u8; 16], &password, 1024, "Test".to_owned(), "{}".to_owned());
|
||||||
directory.insert(account.unwrap()).expect("Account should be inserted ok");
|
directory.insert(account.unwrap()).expect("Account should be inserted ok");
|
||||||
|
|
||||||
let new_hash = directory.files_hash().expect("New files hash should be calculated ok");
|
let new_hash = directory.files_hash().expect("New files hash should be calculated ok");
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
//! Accounts Directory
|
//! Accounts Directory
|
||||||
|
|
||||||
|
use ethkey::Password;
|
||||||
use std::path::{PathBuf};
|
use std::path::{PathBuf};
|
||||||
use {SafeAccount, Error};
|
use {SafeAccount, Error};
|
||||||
|
|
||||||
@ -35,10 +36,10 @@ pub enum SetKeyError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Vault key
|
/// Vault key
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Clone, PartialEq, Eq)]
|
||||||
pub struct VaultKey {
|
pub struct VaultKey {
|
||||||
/// Vault password
|
/// Vault password
|
||||||
pub password: String,
|
pub password: Password,
|
||||||
/// Number of iterations to produce a derived key from password
|
/// Number of iterations to produce a derived key from password
|
||||||
pub iterations: u32,
|
pub iterations: u32,
|
||||||
}
|
}
|
||||||
@ -95,9 +96,9 @@ pub use self::vault::VaultDiskDirectory;
|
|||||||
|
|
||||||
impl VaultKey {
|
impl VaultKey {
|
||||||
/// Create new vault key
|
/// Create new vault key
|
||||||
pub fn new(password: &str, iterations: u32) -> Self {
|
pub fn new(password: &Password, iterations: u32) -> Self {
|
||||||
VaultKey {
|
VaultKey {
|
||||||
password: password.to_owned(),
|
password: password.clone(),
|
||||||
iterations: iterations,
|
iterations: iterations,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ fn check_vault_name(name: &str) -> bool {
|
|||||||
|
|
||||||
/// Vault can be empty, but still must be pluggable => we store vault password in separate file
|
/// Vault can be empty, but still must be pluggable => we store vault password in separate file
|
||||||
fn create_vault_file<P>(vault_dir_path: P, key: &VaultKey, meta: &str) -> Result<(), Error> where P: AsRef<Path> {
|
fn create_vault_file<P>(vault_dir_path: P, key: &VaultKey, meta: &str) -> Result<(), Error> where P: AsRef<Path> {
|
||||||
let password_hash = key.password.keccak256();
|
let password_hash = key.password.as_bytes().keccak256();
|
||||||
let crypto = Crypto::with_plain(&password_hash, &key.password, key.iterations)?;
|
let crypto = Crypto::with_plain(&password_hash, &key.password, key.iterations)?;
|
||||||
|
|
||||||
let vault_file_path = vault_dir_path.as_ref().join(VAULT_FILE_NAME);
|
let vault_file_path = vault_dir_path.as_ref().join(VAULT_FILE_NAME);
|
||||||
@ -267,7 +267,7 @@ fn read_vault_file<P>(vault_dir_path: P, key: Option<&VaultKey>) -> Result<Strin
|
|||||||
|
|
||||||
if let Some(key) = key {
|
if let Some(key) = key {
|
||||||
let password_bytes = vault_file_crypto.decrypt(&key.password)?;
|
let password_bytes = vault_file_crypto.decrypt(&key.password)?;
|
||||||
let password_hash = key.password.keccak256();
|
let password_hash = key.password.as_bytes().keccak256();
|
||||||
if password_hash != password_bytes.as_slice() {
|
if password_hash != password_bytes.as_slice() {
|
||||||
return Err(Error::InvalidPassword);
|
return Err(Error::InvalidPassword);
|
||||||
}
|
}
|
||||||
@ -323,7 +323,7 @@ mod test {
|
|||||||
fn create_vault_file_succeeds() {
|
fn create_vault_file_succeeds() {
|
||||||
// given
|
// given
|
||||||
let temp_path = TempDir::new("").unwrap();
|
let temp_path = TempDir::new("").unwrap();
|
||||||
let key = VaultKey::new("password", 1024);
|
let key = VaultKey::new(&"password".into(), 1024);
|
||||||
let mut vault_dir: PathBuf = temp_path.path().into();
|
let mut vault_dir: PathBuf = temp_path.path().into();
|
||||||
vault_dir.push("vault");
|
vault_dir.push("vault");
|
||||||
fs::create_dir_all(&vault_dir).unwrap();
|
fs::create_dir_all(&vault_dir).unwrap();
|
||||||
@ -342,7 +342,7 @@ mod test {
|
|||||||
fn read_vault_file_succeeds() {
|
fn read_vault_file_succeeds() {
|
||||||
// given
|
// given
|
||||||
let temp_path = TempDir::new("").unwrap();
|
let temp_path = TempDir::new("").unwrap();
|
||||||
let key = VaultKey::new("password", 1024);
|
let key = VaultKey::new(&"password".into(), 1024);
|
||||||
let vault_file_contents = r#"{"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"758696c8dc6378ab9b25bb42790da2f5"},"ciphertext":"54eb50683717d41caaeb12ea969f2c159daada5907383f26f327606a37dc7168","kdf":"pbkdf2","kdfparams":{"c":1024,"dklen":32,"prf":"hmac-sha256","salt":"3c320fa566a1a7963ac8df68a19548d27c8f40bf92ef87c84594dcd5bbc402b6"},"mac":"9e5c2314c2a0781962db85611417c614bd6756666b6b1e93840f5b6ed895f003"}}"#;
|
let vault_file_contents = r#"{"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"758696c8dc6378ab9b25bb42790da2f5"},"ciphertext":"54eb50683717d41caaeb12ea969f2c159daada5907383f26f327606a37dc7168","kdf":"pbkdf2","kdfparams":{"c":1024,"dklen":32,"prf":"hmac-sha256","salt":"3c320fa566a1a7963ac8df68a19548d27c8f40bf92ef87c84594dcd5bbc402b6"},"mac":"9e5c2314c2a0781962db85611417c614bd6756666b6b1e93840f5b6ed895f003"}}"#;
|
||||||
let dir: PathBuf = temp_path.path().into();
|
let dir: PathBuf = temp_path.path().into();
|
||||||
let mut vault_file_path: PathBuf = dir.clone();
|
let mut vault_file_path: PathBuf = dir.clone();
|
||||||
@ -363,7 +363,7 @@ mod test {
|
|||||||
fn read_vault_file_fails() {
|
fn read_vault_file_fails() {
|
||||||
// given
|
// given
|
||||||
let temp_path = TempDir::new("").unwrap();
|
let temp_path = TempDir::new("").unwrap();
|
||||||
let key = VaultKey::new("password1", 1024);
|
let key = VaultKey::new(&"password1".into(), 1024);
|
||||||
let dir: PathBuf = temp_path.path().into();
|
let dir: PathBuf = temp_path.path().into();
|
||||||
let mut vault_file_path: PathBuf = dir.clone();
|
let mut vault_file_path: PathBuf = dir.clone();
|
||||||
vault_file_path.push(VAULT_FILE_NAME);
|
vault_file_path.push(VAULT_FILE_NAME);
|
||||||
@ -392,7 +392,7 @@ mod test {
|
|||||||
fn vault_directory_can_be_created() {
|
fn vault_directory_can_be_created() {
|
||||||
// given
|
// given
|
||||||
let temp_path = TempDir::new("").unwrap();
|
let temp_path = TempDir::new("").unwrap();
|
||||||
let key = VaultKey::new("password", 1024);
|
let key = VaultKey::new(&"password".into(), 1024);
|
||||||
let dir: PathBuf = temp_path.path().into();
|
let dir: PathBuf = temp_path.path().into();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -412,7 +412,7 @@ mod test {
|
|||||||
fn vault_directory_cannot_be_created_if_already_exists() {
|
fn vault_directory_cannot_be_created_if_already_exists() {
|
||||||
// given
|
// given
|
||||||
let temp_path = TempDir::new("").unwrap();
|
let temp_path = TempDir::new("").unwrap();
|
||||||
let key = VaultKey::new("password", 1024);
|
let key = VaultKey::new(&"password".into(), 1024);
|
||||||
let dir: PathBuf = temp_path.path().into();
|
let dir: PathBuf = temp_path.path().into();
|
||||||
let mut vault_dir = dir.clone();
|
let mut vault_dir = dir.clone();
|
||||||
vault_dir.push("vault");
|
vault_dir.push("vault");
|
||||||
@ -429,7 +429,7 @@ mod test {
|
|||||||
fn vault_directory_cannot_be_opened_if_not_exists() {
|
fn vault_directory_cannot_be_opened_if_not_exists() {
|
||||||
// given
|
// given
|
||||||
let temp_path = TempDir::new("").unwrap();
|
let temp_path = TempDir::new("").unwrap();
|
||||||
let key = VaultKey::new("password", 1024);
|
let key = VaultKey::new(&"password".into(), 1024);
|
||||||
let dir: PathBuf = temp_path.path().into();
|
let dir: PathBuf = temp_path.path().into();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
|
@ -22,7 +22,7 @@ use std::time::{Instant, Duration};
|
|||||||
|
|
||||||
use crypto::KEY_ITERATIONS;
|
use crypto::KEY_ITERATIONS;
|
||||||
use random::Random;
|
use random::Random;
|
||||||
use ethkey::{self, Signature, Address, Message, Secret, Public, KeyPair, ExtendedKeyPair};
|
use ethkey::{self, Signature, Password, Address, Message, Secret, Public, KeyPair, ExtendedKeyPair};
|
||||||
use accounts_dir::{KeyDirectory, VaultKeyDirectory, VaultKey, SetKeyError};
|
use accounts_dir::{KeyDirectory, VaultKeyDirectory, VaultKey, SetKeyError};
|
||||||
use account::SafeAccount;
|
use account::SafeAccount;
|
||||||
use presale::PresaleWallet;
|
use presale::PresaleWallet;
|
||||||
@ -64,17 +64,17 @@ impl EthStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SimpleSecretStore for EthStore {
|
impl SimpleSecretStore for EthStore {
|
||||||
fn insert_account(&self, vault: SecretVaultRef, secret: Secret, password: &str) -> Result<StoreAccountRef, Error> {
|
fn insert_account(&self, vault: SecretVaultRef, secret: Secret, password: &Password) -> Result<StoreAccountRef, Error> {
|
||||||
self.store.insert_account(vault, secret, password)
|
self.store.insert_account(vault, secret, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_derived(&self, vault: SecretVaultRef, account_ref: &StoreAccountRef, password: &str, derivation: Derivation)
|
fn insert_derived(&self, vault: SecretVaultRef, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation)
|
||||||
-> Result<StoreAccountRef, Error>
|
-> Result<StoreAccountRef, Error>
|
||||||
{
|
{
|
||||||
self.store.insert_derived(vault, account_ref, password, derivation)
|
self.store.insert_derived(vault, account_ref, password, derivation)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_derived(&self, account_ref: &StoreAccountRef, password: &str, derivation: Derivation) -> Result<Address, Error> {
|
fn generate_derived(&self, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation) -> Result<Address, Error> {
|
||||||
self.store.generate_derived(account_ref, password, derivation)
|
self.store.generate_derived(account_ref, password, derivation)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,42 +86,42 @@ impl SimpleSecretStore for EthStore {
|
|||||||
self.store.accounts()
|
self.store.accounts()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_password(&self, account: &StoreAccountRef, old_password: &str, new_password: &str) -> Result<(), Error> {
|
fn change_password(&self, account: &StoreAccountRef, old_password: &Password, new_password: &Password) -> Result<(), Error> {
|
||||||
self.store.change_password(account, old_password, new_password)
|
self.store.change_password(account, old_password, new_password)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn export_account(&self, account: &StoreAccountRef, password: &str) -> Result<OpaqueKeyFile, Error> {
|
fn export_account(&self, account: &StoreAccountRef, password: &Password) -> Result<OpaqueKeyFile, Error> {
|
||||||
self.store.export_account(account, password)
|
self.store.export_account(account, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_account(&self, account: &StoreAccountRef, password: &str) -> Result<(), Error> {
|
fn remove_account(&self, account: &StoreAccountRef, password: &Password) -> Result<(), Error> {
|
||||||
self.store.remove_account(account, password)
|
self.store.remove_account(account, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign(&self, account: &StoreAccountRef, password: &str, message: &Message) -> Result<Signature, Error> {
|
fn sign(&self, account: &StoreAccountRef, password: &Password, message: &Message) -> Result<Signature, Error> {
|
||||||
self.get(account)?.sign(password, message)
|
self.get(account)?.sign(password, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_derived(&self, account_ref: &StoreAccountRef, password: &str, derivation: Derivation, message: &Message)
|
fn sign_derived(&self, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation, message: &Message)
|
||||||
-> Result<Signature, Error>
|
-> Result<Signature, Error>
|
||||||
{
|
{
|
||||||
self.store.sign_derived(account_ref, password, derivation, message)
|
self.store.sign_derived(account_ref, password, derivation, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result<Secret, Error> {
|
fn agree(&self, account: &StoreAccountRef, password: &Password, other: &Public) -> Result<Secret, Error> {
|
||||||
self.store.agree(account, password, other)
|
self.store.agree(account, password, other)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
|
fn decrypt(&self, account: &StoreAccountRef, password: &Password, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
|
||||||
let account = self.get(account)?;
|
let account = self.get(account)?;
|
||||||
account.decrypt(password, shared_mac, message)
|
account.decrypt(password, shared_mac, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_vault(&self, name: &str, password: &str) -> Result<(), Error> {
|
fn create_vault(&self, name: &str, password: &Password) -> Result<(), Error> {
|
||||||
self.store.create_vault(name, password)
|
self.store.create_vault(name, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_vault(&self, name: &str, password: &str) -> Result<(), Error> {
|
fn open_vault(&self, name: &str, password: &Password) -> Result<(), Error> {
|
||||||
self.store.open_vault(name, password)
|
self.store.open_vault(name, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ impl SimpleSecretStore for EthStore {
|
|||||||
self.store.list_opened_vaults()
|
self.store.list_opened_vaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_vault_password(&self, name: &str, new_password: &str) -> Result<(), Error> {
|
fn change_vault_password(&self, name: &str, new_password: &Password) -> Result<(), Error> {
|
||||||
self.store.change_vault_password(name, new_password)
|
self.store.change_vault_password(name, new_password)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,18 +155,18 @@ impl SimpleSecretStore for EthStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SecretStore for EthStore {
|
impl SecretStore for EthStore {
|
||||||
fn raw_secret(&self, account: &StoreAccountRef, password: &str) -> Result<OpaqueSecret, Error> {
|
fn raw_secret(&self, account: &StoreAccountRef, password: &Password) -> Result<OpaqueSecret, Error> {
|
||||||
Ok(OpaqueSecret(self.get(account)?.crypto.secret(password)?))
|
Ok(OpaqueSecret(self.get(account)?.crypto.secret(password)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_presale(&self, vault: SecretVaultRef, json: &[u8], password: &str) -> Result<StoreAccountRef, Error> {
|
fn import_presale(&self, vault: SecretVaultRef, json: &[u8], password: &Password) -> Result<StoreAccountRef, Error> {
|
||||||
let json_wallet = json::PresaleWallet::load(json).map_err(|_| Error::InvalidKeyFile("Invalid JSON format".to_owned()))?;
|
let json_wallet = json::PresaleWallet::load(json).map_err(|_| Error::InvalidKeyFile("Invalid JSON format".to_owned()))?;
|
||||||
let wallet = PresaleWallet::from(json_wallet);
|
let wallet = PresaleWallet::from(json_wallet);
|
||||||
let keypair = wallet.decrypt(password).map_err(|_| Error::InvalidPassword)?;
|
let keypair = wallet.decrypt(password).map_err(|_| Error::InvalidPassword)?;
|
||||||
self.insert_account(vault, keypair.secret().clone(), password)
|
self.insert_account(vault, keypair.secret().clone(), password)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str, gen_id: bool) -> Result<StoreAccountRef, Error> {
|
fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &Password, gen_id: bool) -> Result<StoreAccountRef, Error> {
|
||||||
let json_keyfile = json::KeyFile::load(json).map_err(|_| Error::InvalidKeyFile("Invalid JSON format".to_owned()))?;
|
let json_keyfile = json::KeyFile::load(json).map_err(|_| Error::InvalidKeyFile("Invalid JSON format".to_owned()))?;
|
||||||
let mut safe_account = SafeAccount::from_file(json_keyfile, None);
|
let mut safe_account = SafeAccount::from_file(json_keyfile, None);
|
||||||
|
|
||||||
@ -179,19 +179,19 @@ impl SecretStore for EthStore {
|
|||||||
self.store.import(vault, safe_account)
|
self.store.import(vault, safe_account)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_password(&self, account: &StoreAccountRef, password: &str) -> Result<bool, Error> {
|
fn test_password(&self, account: &StoreAccountRef, password: &Password) -> Result<bool, Error> {
|
||||||
let account = self.get(account)?;
|
let account = self.get(account)?;
|
||||||
Ok(account.check_password(password))
|
Ok(account.check_password(password))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_account(&self, new_store: &SimpleSecretStore, new_vault: SecretVaultRef, account: &StoreAccountRef, password: &str, new_password: &str) -> Result<(), Error> {
|
fn copy_account(&self, new_store: &SimpleSecretStore, new_vault: SecretVaultRef, account: &StoreAccountRef, password: &Password, new_password: &Password) -> Result<(), Error> {
|
||||||
let account = self.get(account)?;
|
let account = self.get(account)?;
|
||||||
let secret = account.crypto.secret(password)?;
|
let secret = account.crypto.secret(password)?;
|
||||||
new_store.insert_account(new_vault, secret, new_password)?;
|
new_store.insert_account(new_vault, secret, new_password)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn public(&self, account: &StoreAccountRef, password: &str) -> Result<Public, Error> {
|
fn public(&self, account: &StoreAccountRef, password: &Password) -> Result<Public, Error> {
|
||||||
let account = self.get(account)?;
|
let account = self.get(account)?;
|
||||||
account.public(password)
|
account.public(password)
|
||||||
}
|
}
|
||||||
@ -365,7 +365,7 @@ impl EthMultiStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_matching(&self, account: &StoreAccountRef, password: &str) -> Result<Vec<SafeAccount>, Error> {
|
fn get_matching(&self, account: &StoreAccountRef, password: &Password) -> Result<Vec<SafeAccount>, Error> {
|
||||||
let accounts = self.get_accounts(account)?;
|
let accounts = self.get_accounts(account)?;
|
||||||
|
|
||||||
Ok(accounts.into_iter()
|
Ok(accounts.into_iter()
|
||||||
@ -455,14 +455,14 @@ impl EthMultiStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SimpleSecretStore for EthMultiStore {
|
impl SimpleSecretStore for EthMultiStore {
|
||||||
fn insert_account(&self, vault: SecretVaultRef, secret: Secret, password: &str) -> Result<StoreAccountRef, Error> {
|
fn insert_account(&self, vault: SecretVaultRef, secret: Secret, password: &Password) -> Result<StoreAccountRef, Error> {
|
||||||
let keypair = KeyPair::from_secret(secret).map_err(|_| Error::CreationFailed)?;
|
let keypair = KeyPair::from_secret(secret).map_err(|_| Error::CreationFailed)?;
|
||||||
let id: [u8; 16] = Random::random();
|
let id: [u8; 16] = Random::random();
|
||||||
let account = SafeAccount::create(&keypair, id, password, self.iterations, "".to_owned(), "{}".to_owned())?;
|
let account = SafeAccount::create(&keypair, id, password, self.iterations, "".to_owned(), "{}".to_owned())?;
|
||||||
self.import(vault, account)
|
self.import(vault, account)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_derived(&self, vault: SecretVaultRef, account_ref: &StoreAccountRef, password: &str, derivation: Derivation)
|
fn insert_derived(&self, vault: SecretVaultRef, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation)
|
||||||
-> Result<StoreAccountRef, Error>
|
-> Result<StoreAccountRef, Error>
|
||||||
{
|
{
|
||||||
let accounts = self.get_matching(account_ref, password)?;
|
let accounts = self.get_matching(account_ref, password)?;
|
||||||
@ -473,7 +473,7 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
Err(Error::InvalidPassword)
|
Err(Error::InvalidPassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_derived(&self, account_ref: &StoreAccountRef, password: &str, derivation: Derivation)
|
fn generate_derived(&self, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation)
|
||||||
-> Result<Address, Error>
|
-> Result<Address, Error>
|
||||||
{
|
{
|
||||||
let accounts = self.get_matching(&account_ref, password)?;
|
let accounts = self.get_matching(&account_ref, password)?;
|
||||||
@ -484,7 +484,7 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
Err(Error::InvalidPassword)
|
Err(Error::InvalidPassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_derived(&self, account_ref: &StoreAccountRef, password: &str, derivation: Derivation, message: &Message)
|
fn sign_derived(&self, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation, message: &Message)
|
||||||
-> Result<Signature, Error>
|
-> Result<Signature, Error>
|
||||||
{
|
{
|
||||||
let accounts = self.get_matching(&account_ref, password)?;
|
let accounts = self.get_matching(&account_ref, password)?;
|
||||||
@ -518,7 +518,7 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
Ok(self.cache.read().keys().cloned().collect())
|
Ok(self.cache.read().keys().cloned().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_account(&self, account_ref: &StoreAccountRef, password: &str) -> Result<(), Error> {
|
fn remove_account(&self, account_ref: &StoreAccountRef, password: &Password) -> Result<(), Error> {
|
||||||
let accounts = self.get_matching(account_ref, password)?;
|
let accounts = self.get_matching(account_ref, password)?;
|
||||||
|
|
||||||
for account in accounts {
|
for account in accounts {
|
||||||
@ -528,7 +528,7 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
Err(Error::InvalidPassword)
|
Err(Error::InvalidPassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_password(&self, account_ref: &StoreAccountRef, old_password: &str, new_password: &str) -> Result<(), Error> {
|
fn change_password(&self, account_ref: &StoreAccountRef, old_password: &Password, new_password: &Password) -> Result<(), Error> {
|
||||||
let accounts = self.get_matching(account_ref, old_password)?;
|
let accounts = self.get_matching(account_ref, old_password)?;
|
||||||
|
|
||||||
if accounts.is_empty() {
|
if accounts.is_empty() {
|
||||||
@ -544,11 +544,11 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn export_account(&self, account_ref: &StoreAccountRef, password: &str) -> Result<OpaqueKeyFile, Error> {
|
fn export_account(&self, account_ref: &StoreAccountRef, password: &Password) -> Result<OpaqueKeyFile, Error> {
|
||||||
self.get_matching(account_ref, password)?.into_iter().nth(0).map(Into::into).ok_or(Error::InvalidPassword)
|
self.get_matching(account_ref, password)?.into_iter().nth(0).map(Into::into).ok_or(Error::InvalidPassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign(&self, account: &StoreAccountRef, password: &str, message: &Message) -> Result<Signature, Error> {
|
fn sign(&self, account: &StoreAccountRef, password: &Password, message: &Message) -> Result<Signature, Error> {
|
||||||
let accounts = self.get_matching(account, password)?;
|
let accounts = self.get_matching(account, password)?;
|
||||||
match accounts.first() {
|
match accounts.first() {
|
||||||
Some(ref account) => account.sign(password, message),
|
Some(ref account) => account.sign(password, message),
|
||||||
@ -556,7 +556,7 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
|
fn decrypt(&self, account: &StoreAccountRef, password: &Password, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
|
||||||
let accounts = self.get_matching(account, password)?;
|
let accounts = self.get_matching(account, password)?;
|
||||||
match accounts.first() {
|
match accounts.first() {
|
||||||
Some(ref account) => account.decrypt(password, shared_mac, message),
|
Some(ref account) => account.decrypt(password, shared_mac, message),
|
||||||
@ -564,7 +564,7 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result<Secret, Error> {
|
fn agree(&self, account: &StoreAccountRef, password: &Password, other: &Public) -> Result<Secret, Error> {
|
||||||
let accounts = self.get_matching(account, password)?;
|
let accounts = self.get_matching(account, password)?;
|
||||||
match accounts.first() {
|
match accounts.first() {
|
||||||
Some(ref account) => account.agree(password, other),
|
Some(ref account) => account.agree(password, other),
|
||||||
@ -572,7 +572,7 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_vault(&self, name: &str, password: &str) -> Result<(), Error> {
|
fn create_vault(&self, name: &str, password: &Password) -> Result<(), Error> {
|
||||||
let is_vault_created = { // lock border
|
let is_vault_created = { // lock border
|
||||||
let mut vaults = self.vaults.lock();
|
let mut vaults = self.vaults.lock();
|
||||||
if !vaults.contains_key(&name.to_owned()) {
|
if !vaults.contains_key(&name.to_owned()) {
|
||||||
@ -592,7 +592,7 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_vault(&self, name: &str, password: &str) -> Result<(), Error> {
|
fn open_vault(&self, name: &str, password: &Password) -> Result<(), Error> {
|
||||||
let is_vault_opened = { // lock border
|
let is_vault_opened = { // lock border
|
||||||
let mut vaults = self.vaults.lock();
|
let mut vaults = self.vaults.lock();
|
||||||
if !vaults.contains_key(&name.to_owned()) {
|
if !vaults.contains_key(&name.to_owned()) {
|
||||||
@ -629,7 +629,7 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
Ok(self.vaults.lock().keys().cloned().collect())
|
Ok(self.vaults.lock().keys().cloned().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_vault_password(&self, name: &str, new_password: &str) -> Result<(), Error> {
|
fn change_vault_password(&self, name: &str, new_password: &Password) -> Result<(), Error> {
|
||||||
let old_key = self.vaults.lock().get(name).map(|v| v.key()).ok_or(Error::VaultNotFound)?;
|
let old_key = self.vaults.lock().get(name).map(|v| v.key()).ok_or(Error::VaultNotFound)?;
|
||||||
let vault_provider = self.dir.as_vault_provider().ok_or(Error::VaultsAreNotSupported)?;
|
let vault_provider = self.dir.as_vault_provider().ok_or(Error::VaultsAreNotSupported)?;
|
||||||
let vault = vault_provider.open(name, old_key)?;
|
let vault = vault_provider.open(name, old_key)?;
|
||||||
@ -732,7 +732,8 @@ mod tests {
|
|||||||
let keypair = keypair();
|
let keypair = keypair();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), "test").unwrap();
|
let passwd = "test".into();
|
||||||
|
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), &passwd).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(address, StoreAccountRef::root(keypair.address()));
|
assert_eq!(address, StoreAccountRef::root(keypair.address()));
|
||||||
@ -745,7 +746,8 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let store = store();
|
let store = store();
|
||||||
let keypair = keypair();
|
let keypair = keypair();
|
||||||
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), "test").unwrap();
|
let passwd = "test".into();
|
||||||
|
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), &passwd).unwrap();
|
||||||
assert_eq!(&store.meta(&address).unwrap(), "{}");
|
assert_eq!(&store.meta(&address).unwrap(), "{}");
|
||||||
assert_eq!(&store.name(&address).unwrap(), "");
|
assert_eq!(&store.name(&address).unwrap(), "");
|
||||||
|
|
||||||
@ -763,11 +765,12 @@ mod tests {
|
|||||||
fn should_remove_account() {
|
fn should_remove_account() {
|
||||||
// given
|
// given
|
||||||
let store = store();
|
let store = store();
|
||||||
|
let passwd = "test".into();
|
||||||
let keypair = keypair();
|
let keypair = keypair();
|
||||||
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), "test").unwrap();
|
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), &passwd).unwrap();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.remove_account(&address, "test").unwrap();
|
store.remove_account(&address, &passwd).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(store.accounts().unwrap().len(), 0, "Should remove account.");
|
assert_eq!(store.accounts().unwrap().len(), 0, "Should remove account.");
|
||||||
@ -777,12 +780,13 @@ mod tests {
|
|||||||
fn should_return_true_if_password_is_correct() {
|
fn should_return_true_if_password_is_correct() {
|
||||||
// given
|
// given
|
||||||
let store = store();
|
let store = store();
|
||||||
|
let passwd = "test".into();
|
||||||
let keypair = keypair();
|
let keypair = keypair();
|
||||||
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), "test").unwrap();
|
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), &passwd).unwrap();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res1 = store.test_password(&address, "x").unwrap();
|
let res1 = store.test_password(&address, &"x".into()).unwrap();
|
||||||
let res2 = store.test_password(&address, "test").unwrap();
|
let res2 = store.test_password(&address, &passwd).unwrap();
|
||||||
|
|
||||||
assert!(!res1, "First password should be invalid.");
|
assert!(!res1, "First password should be invalid.");
|
||||||
assert!(res2, "Second password should be correct.");
|
assert!(res2, "Second password should be correct.");
|
||||||
@ -792,16 +796,18 @@ mod tests {
|
|||||||
fn multistore_should_be_able_to_have_the_same_account_twice() {
|
fn multistore_should_be_able_to_have_the_same_account_twice() {
|
||||||
// given
|
// given
|
||||||
let store = multi_store();
|
let store = multi_store();
|
||||||
|
let passwd1 = "test".into();
|
||||||
|
let passwd2 = "xyz".into();
|
||||||
let keypair = keypair();
|
let keypair = keypair();
|
||||||
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), "test").unwrap();
|
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), &passwd1).unwrap();
|
||||||
let address2 = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), "xyz").unwrap();
|
let address2 = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), &passwd2).unwrap();
|
||||||
assert_eq!(address, address2);
|
assert_eq!(address, address2);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
assert!(store.remove_account(&address, "test").is_ok(), "First password should work.");
|
assert!(store.remove_account(&address, &passwd1).is_ok(), "First password should work.");
|
||||||
assert_eq!(store.accounts().unwrap().len(), 1);
|
assert_eq!(store.accounts().unwrap().len(), 1);
|
||||||
|
|
||||||
assert!(store.remove_account(&address, "xyz").is_ok(), "Second password should work too.");
|
assert!(store.remove_account(&address, &passwd2).is_ok(), "Second password should work too.");
|
||||||
assert_eq!(store.accounts().unwrap().len(), 0);
|
assert_eq!(store.accounts().unwrap().len(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,17 +815,19 @@ mod tests {
|
|||||||
fn should_copy_account() {
|
fn should_copy_account() {
|
||||||
// given
|
// given
|
||||||
let store = store();
|
let store = store();
|
||||||
|
let passwd1 = "test".into();
|
||||||
|
let passwd2 = "xzy".into();
|
||||||
let multi_store = multi_store();
|
let multi_store = multi_store();
|
||||||
let keypair = keypair();
|
let keypair = keypair();
|
||||||
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), "test").unwrap();
|
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), &passwd1).unwrap();
|
||||||
assert_eq!(multi_store.accounts().unwrap().len(), 0);
|
assert_eq!(multi_store.accounts().unwrap().len(), 0);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.copy_account(&multi_store, SecretVaultRef::Root, &address, "test", "xyz").unwrap();
|
store.copy_account(&multi_store, SecretVaultRef::Root, &address, &passwd1, &passwd2).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert!(store.test_password(&address, "test").unwrap(), "First password should work for store.");
|
assert!(store.test_password(&address, &passwd1).unwrap(), "First password should work for store.");
|
||||||
assert!(multi_store.sign(&address, "xyz", &Default::default()).is_ok(), "Second password should work for second store.");
|
assert!(multi_store.sign(&address, &passwd2, &Default::default()).is_ok(), "Second password should work for second store.");
|
||||||
assert_eq!(multi_store.accounts().unwrap().len(), 1);
|
assert_eq!(multi_store.accounts().unwrap().len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -828,23 +836,23 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let mut dir = RootDiskDirectoryGuard::new();
|
let mut dir = RootDiskDirectoryGuard::new();
|
||||||
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
||||||
let name1 = "vault1"; let password1 = "password1";
|
let name1 = "vault1"; let password1 = "password1".into();
|
||||||
let name2 = "vault2"; let password2 = "password2";
|
let name2 = "vault2"; let password2 = "password2".into();
|
||||||
let keypair1 = keypair();
|
let keypair1 = keypair();
|
||||||
let keypair2 = keypair();
|
let keypair2 = keypair();
|
||||||
let keypair3 = keypair(); let password3 = "password3";
|
let keypair3 = keypair(); let password3 = "password3".into();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.create_vault(name1, password1).unwrap();
|
store.create_vault(name1, &password1).unwrap();
|
||||||
store.create_vault(name2, password2).unwrap();
|
store.create_vault(name2, &password2).unwrap();
|
||||||
|
|
||||||
// then [can create vaults] ^^^
|
// then [can create vaults] ^^^
|
||||||
|
|
||||||
// and when
|
// and when
|
||||||
store.insert_account(SecretVaultRef::Vault(name1.to_owned()), keypair1.secret().clone(), password1).unwrap();
|
store.insert_account(SecretVaultRef::Vault(name1.to_owned()), keypair1.secret().clone(), &password1).unwrap();
|
||||||
store.insert_account(SecretVaultRef::Vault(name2.to_owned()), keypair2.secret().clone(), password2).unwrap();
|
store.insert_account(SecretVaultRef::Vault(name2.to_owned()), keypair2.secret().clone(), &password2).unwrap();
|
||||||
store.insert_account(SecretVaultRef::Root, keypair3.secret().clone(), password3).unwrap();
|
store.insert_account(SecretVaultRef::Root, keypair3.secret().clone(), &password3).unwrap();
|
||||||
store.insert_account(SecretVaultRef::Vault("vault3".to_owned()), keypair1.secret().clone(), password3).unwrap_err();
|
store.insert_account(SecretVaultRef::Vault("vault3".to_owned()), keypair1.secret().clone(), &password3).unwrap_err();
|
||||||
let accounts = store.accounts().unwrap();
|
let accounts = store.accounts().unwrap();
|
||||||
|
|
||||||
// then [can create accounts in vaults]
|
// then [can create accounts in vaults]
|
||||||
@ -864,10 +872,10 @@ mod tests {
|
|||||||
assert!(accounts.iter().any(|a| a.vault == SecretVaultRef::Root));
|
assert!(accounts.iter().any(|a| a.vault == SecretVaultRef::Root));
|
||||||
|
|
||||||
// and when
|
// and when
|
||||||
store.open_vault(name1, password2).unwrap_err();
|
store.open_vault(name1, &password2).unwrap_err();
|
||||||
store.open_vault(name2, password1).unwrap_err();
|
store.open_vault(name2, &password1).unwrap_err();
|
||||||
store.open_vault(name1, password1).unwrap();
|
store.open_vault(name1, &password1).unwrap();
|
||||||
store.open_vault(name2, password2).unwrap();
|
store.open_vault(name2, &password2).unwrap();
|
||||||
let accounts = store.accounts().unwrap();
|
let accounts = store.accounts().unwrap();
|
||||||
|
|
||||||
// then [can check vaults on open + can reopen vaults + accounts from vaults appear]
|
// then [can check vaults on open + can reopen vaults + accounts from vaults appear]
|
||||||
@ -882,19 +890,19 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let mut dir = RootDiskDirectoryGuard::new();
|
let mut dir = RootDiskDirectoryGuard::new();
|
||||||
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
||||||
let name1 = "vault1"; let password1 = "password1";
|
let name1 = "vault1"; let password1 = "password1".into();
|
||||||
let name2 = "vault2"; let password2 = "password2";
|
let name2 = "vault2"; let password2 = "password2".into();
|
||||||
let password3 = "password3";
|
let password3 = "password3".into();
|
||||||
let keypair1 = keypair();
|
let keypair1 = keypair();
|
||||||
let keypair2 = keypair();
|
let keypair2 = keypair();
|
||||||
let keypair3 = keypair();
|
let keypair3 = keypair();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.create_vault(name1, password1).unwrap();
|
store.create_vault(name1, &password1).unwrap();
|
||||||
store.create_vault(name2, password2).unwrap();
|
store.create_vault(name2, &password2).unwrap();
|
||||||
let account1 = store.insert_account(SecretVaultRef::Vault(name1.to_owned()), keypair1.secret().clone(), password1).unwrap();
|
let account1 = store.insert_account(SecretVaultRef::Vault(name1.to_owned()), keypair1.secret().clone(), &password1).unwrap();
|
||||||
let account2 = store.insert_account(SecretVaultRef::Vault(name1.to_owned()), keypair2.secret().clone(), password1).unwrap();
|
let account2 = store.insert_account(SecretVaultRef::Vault(name1.to_owned()), keypair2.secret().clone(), &password1).unwrap();
|
||||||
let account3 = store.insert_account(SecretVaultRef::Root, keypair3.secret().clone(), password3).unwrap();
|
let account3 = store.insert_account(SecretVaultRef::Root, keypair3.secret().clone(), &password3).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let account1 = store.change_account_vault(SecretVaultRef::Root, account1.clone()).unwrap();
|
let account1 = store.change_account_vault(SecretVaultRef::Root, account1.clone()).unwrap();
|
||||||
@ -917,11 +925,11 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let mut dir = RootDiskDirectoryGuard::new();
|
let mut dir = RootDiskDirectoryGuard::new();
|
||||||
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
||||||
let password1 = "password1";
|
let password1 = "password1".into();
|
||||||
let keypair1 = keypair();
|
let keypair1 = keypair();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let account1 = store.insert_account(SecretVaultRef::Root, keypair1.secret().clone(), password1).unwrap();
|
let account1 = store.insert_account(SecretVaultRef::Root, keypair1.secret().clone(), &password1).unwrap();
|
||||||
store.change_account_vault(SecretVaultRef::Root, account1).unwrap();
|
store.change_account_vault(SecretVaultRef::Root, account1).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@ -934,16 +942,16 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let mut dir = RootDiskDirectoryGuard::new();
|
let mut dir = RootDiskDirectoryGuard::new();
|
||||||
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
||||||
let name1 = "vault1"; let password1 = "password1";
|
let name1 = "vault1"; let password1 = "password1".into();
|
||||||
let keypair1 = keypair();
|
let keypair1 = keypair();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.create_vault(name1, password1).unwrap();
|
store.create_vault(name1, &password1).unwrap();
|
||||||
let account1 = store.insert_account(SecretVaultRef::Vault(name1.to_owned()), keypair1.secret().clone(), password1).unwrap();
|
let account1 = store.insert_account(SecretVaultRef::Vault(name1.to_owned()), keypair1.secret().clone(), &password1).unwrap();
|
||||||
assert_eq!(store.accounts().unwrap().len(), 1);
|
assert_eq!(store.accounts().unwrap().len(), 1);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
store.remove_account(&account1, password1).unwrap();
|
store.remove_account(&account1, &password1).unwrap();
|
||||||
assert_eq!(store.accounts().unwrap().len(), 0);
|
assert_eq!(store.accounts().unwrap().len(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -952,17 +960,17 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let mut dir = RootDiskDirectoryGuard::new();
|
let mut dir = RootDiskDirectoryGuard::new();
|
||||||
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
||||||
let name1 = "vault1"; let password1 = "password1";
|
let name1 = "vault1"; let password1 = "password1".into();
|
||||||
let password2 = "password2";
|
let password2 = "password2".into();
|
||||||
let keypair1 = keypair();
|
let keypair1 = keypair();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.create_vault(name1, password1).unwrap();
|
store.create_vault(name1, &password1).unwrap();
|
||||||
let account1 = store.insert_account(SecretVaultRef::Vault(name1.to_owned()), keypair1.secret().clone(), password1).unwrap();
|
let account1 = store.insert_account(SecretVaultRef::Vault(name1.to_owned()), keypair1.secret().clone(), &password1).unwrap();
|
||||||
assert_eq!(store.accounts().unwrap().len(), 1);
|
assert_eq!(store.accounts().unwrap().len(), 1);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
store.remove_account(&account1, password2).unwrap_err();
|
store.remove_account(&account1, &password2).unwrap_err();
|
||||||
assert_eq!(store.accounts().unwrap().len(), 1);
|
assert_eq!(store.accounts().unwrap().len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -971,24 +979,24 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let mut dir = RootDiskDirectoryGuard::new();
|
let mut dir = RootDiskDirectoryGuard::new();
|
||||||
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
||||||
let name = "vault"; let password = "password";
|
let name = "vault"; let password = "password".into();
|
||||||
let keypair = keypair();
|
let keypair = keypair();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.create_vault(name, password).unwrap();
|
store.create_vault(name, &password).unwrap();
|
||||||
store.insert_account(SecretVaultRef::Vault(name.to_owned()), keypair.secret().clone(), password).unwrap();
|
store.insert_account(SecretVaultRef::Vault(name.to_owned()), keypair.secret().clone(), &password).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(store.accounts().unwrap().len(), 1);
|
assert_eq!(store.accounts().unwrap().len(), 1);
|
||||||
let new_password = "new_password";
|
let new_password = "new_password".into();
|
||||||
store.change_vault_password(name, new_password).unwrap();
|
store.change_vault_password(name, &new_password).unwrap();
|
||||||
assert_eq!(store.accounts().unwrap().len(), 1);
|
assert_eq!(store.accounts().unwrap().len(), 1);
|
||||||
|
|
||||||
// and when
|
// and when
|
||||||
store.close_vault(name).unwrap();
|
store.close_vault(name).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
store.open_vault(name, new_password).unwrap();
|
store.open_vault(name, &new_password).unwrap();
|
||||||
assert_eq!(store.accounts().unwrap().len(), 1);
|
assert_eq!(store.accounts().unwrap().len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,18 +1005,18 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let mut dir = RootDiskDirectoryGuard::new();
|
let mut dir = RootDiskDirectoryGuard::new();
|
||||||
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
||||||
let name = "vault"; let password = "password";
|
let name = "vault"; let password = "password".into();
|
||||||
let secret_password = "sec_password";
|
let secret_password = "sec_password".into();
|
||||||
let keypair = keypair();
|
let keypair = keypair();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.create_vault(name, password).unwrap();
|
store.create_vault(name, &password).unwrap();
|
||||||
let account_ref = store.insert_account(SecretVaultRef::Vault(name.to_owned()), keypair.secret().clone(), secret_password).unwrap();
|
let account_ref = store.insert_account(SecretVaultRef::Vault(name.to_owned()), keypair.secret().clone(), &secret_password).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(store.accounts().unwrap().len(), 1);
|
assert_eq!(store.accounts().unwrap().len(), 1);
|
||||||
let new_secret_password = "new_sec_password";
|
let new_secret_password = "new_sec_password".into();
|
||||||
store.change_password(&account_ref, secret_password, new_secret_password).unwrap();
|
store.change_password(&account_ref, &secret_password, &new_secret_password).unwrap();
|
||||||
assert_eq!(store.accounts().unwrap().len(), 1);
|
assert_eq!(store.accounts().unwrap().len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1017,14 +1025,14 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let mut dir = RootDiskDirectoryGuard::new();
|
let mut dir = RootDiskDirectoryGuard::new();
|
||||||
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
||||||
let name1 = "vault1"; let password1 = "password1";
|
let name1 = "vault1"; let password1 = "password1".into();
|
||||||
let name2 = "vault2"; let password2 = "password2";
|
let name2 = "vault2"; let password2 = "password2".into();
|
||||||
let name3 = "vault3"; let password3 = "password3";
|
let name3 = "vault3"; let password3 = "password3".into();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.create_vault(name1, password1).unwrap();
|
store.create_vault(name1, &password1).unwrap();
|
||||||
store.create_vault(name2, password2).unwrap();
|
store.create_vault(name2, &password2).unwrap();
|
||||||
store.create_vault(name3, password3).unwrap();
|
store.create_vault(name3, &password3).unwrap();
|
||||||
store.close_vault(name2).unwrap();
|
store.close_vault(name2).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@ -1039,10 +1047,10 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let mut dir = RootDiskDirectoryGuard::new();
|
let mut dir = RootDiskDirectoryGuard::new();
|
||||||
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
||||||
let name1 = "vault1"; let password1 = "password1";
|
let name1 = "vault1"; let password1 = "password1".into();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.create_vault(name1, password1).unwrap();
|
store.create_vault(name1, &password1).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(store.get_vault_meta(name1).unwrap(), "{}".to_owned());
|
assert_eq!(store.get_vault_meta(name1).unwrap(), "{}".to_owned());
|
||||||
@ -1051,7 +1059,7 @@ mod tests {
|
|||||||
|
|
||||||
// and when
|
// and when
|
||||||
store.close_vault(name1).unwrap();
|
store.close_vault(name1).unwrap();
|
||||||
store.open_vault(name1, password1).unwrap();
|
store.open_vault(name1, &password1).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(store.get_vault_meta(name1).unwrap(), "Hello, world!!!".to_owned());
|
assert_eq!(store.get_vault_meta(name1).unwrap(), "Hello, world!!!".to_owned());
|
||||||
@ -1069,13 +1077,13 @@ mod tests {
|
|||||||
// given we have one account in the store
|
// given we have one account in the store
|
||||||
let store = store();
|
let store = store();
|
||||||
let keypair = keypair();
|
let keypair = keypair();
|
||||||
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), "test").unwrap();
|
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), &"test".into()).unwrap();
|
||||||
|
|
||||||
// when we deriving from that account
|
// when we deriving from that account
|
||||||
let derived = store.insert_derived(
|
let derived = store.insert_derived(
|
||||||
SecretVaultRef::Root,
|
SecretVaultRef::Root,
|
||||||
&address,
|
&address,
|
||||||
"test",
|
&"test".into(),
|
||||||
Derivation::HardHash(H256::from(0)),
|
Derivation::HardHash(H256::from(0)),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
@ -1084,7 +1092,7 @@ mod tests {
|
|||||||
assert_eq!(accounts.len(), 2);
|
assert_eq!(accounts.len(), 2);
|
||||||
|
|
||||||
// and we can sign with the derived contract
|
// and we can sign with the derived contract
|
||||||
assert!(store.sign(&derived, "test", &Default::default()).is_ok(), "Second password should work for second store.");
|
assert!(store.sign(&derived, &"test".into(), &Default::default()).is_ok(), "Second password should work for second store.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1092,13 +1100,13 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let mut dir = RootDiskDirectoryGuard::new();
|
let mut dir = RootDiskDirectoryGuard::new();
|
||||||
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
let store = EthStore::open(dir.key_dir.take().unwrap()).unwrap();
|
||||||
let name = "vault"; let password = "password1";
|
let name = "vault"; let password = "password1".into();
|
||||||
let new_password = "password2";
|
let new_password = "password2".into();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.create_vault(name, password).unwrap();
|
store.create_vault(name, &password).unwrap();
|
||||||
store.set_vault_meta(name, "OldMeta").unwrap();
|
store.set_vault_meta(name, "OldMeta").unwrap();
|
||||||
store.change_vault_password(name, new_password).unwrap();
|
store.change_vault_password(name, &new_password).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(store.get_vault_meta(name).unwrap(), "OldMeta".to_owned());
|
assert_eq!(store.get_vault_meta(name).unwrap(), "OldMeta".to_owned());
|
||||||
@ -1109,10 +1117,10 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
let store = store();
|
let store = store();
|
||||||
let keypair = keypair();
|
let keypair = keypair();
|
||||||
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), "test").unwrap();
|
let address = store.insert_account(SecretVaultRef::Root, keypair.secret().clone(), &"test".into()).unwrap();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let exported = store.export_account(&address, "test");
|
let exported = store.export_account(&address, &"test".into());
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert!(exported.is_ok(), "Should export single account: {:?}", exported);
|
assert!(exported.is_ok(), "Should export single account: {:?}", exported);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use json;
|
use json;
|
||||||
use ethkey::{Address, Secret, KeyPair};
|
use ethkey::{Address, Secret, KeyPair, Password};
|
||||||
use crypto::{Keccak256, pbkdf2};
|
use crypto::{Keccak256, pbkdf2};
|
||||||
use {crypto, Error};
|
use {crypto, Error};
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ impl PresaleWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypt the wallet.
|
/// Decrypt the wallet.
|
||||||
pub fn decrypt(&self, password: &str) -> Result<KeyPair, Error> {
|
pub fn decrypt(&self, password: &Password) -> Result<KeyPair, Error> {
|
||||||
let mut derived_key = [0u8; 32];
|
let mut derived_key = [0u8; 32];
|
||||||
let salt = pbkdf2::Salt(password.as_bytes());
|
let salt = pbkdf2::Salt(password.as_bytes());
|
||||||
let sec = pbkdf2::Secret(password.as_bytes());
|
let sec = pbkdf2::Secret(password.as_bytes());
|
||||||
@ -93,7 +93,7 @@ mod tests {
|
|||||||
|
|
||||||
let wallet = json::PresaleWallet::load(json.as_bytes()).unwrap();
|
let wallet = json::PresaleWallet::load(json.as_bytes()).unwrap();
|
||||||
let wallet = PresaleWallet::from(wallet);
|
let wallet = PresaleWallet::from(wallet);
|
||||||
assert!(wallet.decrypt("123").is_ok());
|
assert!(wallet.decrypt(&"123".into()).is_ok());
|
||||||
assert!(wallet.decrypt("124").is_err());
|
assert!(wallet.decrypt(&"124".into()).is_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use ethkey::{Address, Message, Signature, Secret, Public};
|
use ethkey::{Address, Message, Signature, Secret, Password, Public};
|
||||||
use Error;
|
use Error;
|
||||||
use json::{Uuid, OpaqueKeyFile};
|
use json::{Uuid, OpaqueKeyFile};
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
@ -56,25 +56,25 @@ impl ::std::borrow::Borrow<Address> for StoreAccountRef {
|
|||||||
/// Simple Secret Store API
|
/// Simple Secret Store API
|
||||||
pub trait SimpleSecretStore: Send + Sync {
|
pub trait SimpleSecretStore: Send + Sync {
|
||||||
/// Inserts new accounts to the store (or vault) with given password.
|
/// Inserts new accounts to the store (or vault) with given password.
|
||||||
fn insert_account(&self, vault: SecretVaultRef, secret: Secret, password: &str) -> Result<StoreAccountRef, Error>;
|
fn insert_account(&self, vault: SecretVaultRef, secret: Secret, password: &Password) -> Result<StoreAccountRef, Error>;
|
||||||
/// Inserts new derived account to the store (or vault) with given password.
|
/// Inserts new derived account to the store (or vault) with given password.
|
||||||
fn insert_derived(&self, vault: SecretVaultRef, account_ref: &StoreAccountRef, password: &str, derivation: Derivation) -> Result<StoreAccountRef, Error>;
|
fn insert_derived(&self, vault: SecretVaultRef, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation) -> Result<StoreAccountRef, Error>;
|
||||||
/// Changes accounts password.
|
/// Changes accounts password.
|
||||||
fn change_password(&self, account: &StoreAccountRef, old_password: &str, new_password: &str) -> Result<(), Error>;
|
fn change_password(&self, account: &StoreAccountRef, old_password: &Password, new_password: &Password) -> Result<(), Error>;
|
||||||
/// Exports key details for account.
|
/// Exports key details for account.
|
||||||
fn export_account(&self, account: &StoreAccountRef, password: &str) -> Result<OpaqueKeyFile, Error>;
|
fn export_account(&self, account: &StoreAccountRef, password: &Password) -> Result<OpaqueKeyFile, Error>;
|
||||||
/// Entirely removes account from the store and underlying storage.
|
/// Entirely removes account from the store and underlying storage.
|
||||||
fn remove_account(&self, account: &StoreAccountRef, password: &str) -> Result<(), Error>;
|
fn remove_account(&self, account: &StoreAccountRef, password: &Password) -> Result<(), Error>;
|
||||||
/// Generates new derived account.
|
/// Generates new derived account.
|
||||||
fn generate_derived(&self, account_ref: &StoreAccountRef, password: &str, derivation: Derivation) -> Result<Address, Error>;
|
fn generate_derived(&self, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation) -> Result<Address, Error>;
|
||||||
/// Sign a message with given account.
|
/// Sign a message with given account.
|
||||||
fn sign(&self, account: &StoreAccountRef, password: &str, message: &Message) -> Result<Signature, Error>;
|
fn sign(&self, account: &StoreAccountRef, password: &Password, message: &Message) -> Result<Signature, Error>;
|
||||||
/// Sign a message with derived account.
|
/// Sign a message with derived account.
|
||||||
fn sign_derived(&self, account_ref: &StoreAccountRef, password: &str, derivation: Derivation, message: &Message) -> Result<Signature, Error>;
|
fn sign_derived(&self, account_ref: &StoreAccountRef, password: &Password, derivation: Derivation, message: &Message) -> Result<Signature, Error>;
|
||||||
/// Decrypt a messages with given account.
|
/// Decrypt a messages with given account.
|
||||||
fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error>;
|
fn decrypt(&self, account: &StoreAccountRef, password: &Password, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error>;
|
||||||
/// Agree on shared key.
|
/// Agree on shared key.
|
||||||
fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result<Secret, Error>;
|
fn agree(&self, account: &StoreAccountRef, password: &Password, other: &Public) -> Result<Secret, Error>;
|
||||||
|
|
||||||
/// Returns all accounts in this secret store.
|
/// Returns all accounts in this secret store.
|
||||||
fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error>;
|
fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error>;
|
||||||
@ -83,9 +83,9 @@ pub trait SimpleSecretStore: Send + Sync {
|
|||||||
fn account_ref(&self, address: &Address) -> Result<StoreAccountRef, Error>;
|
fn account_ref(&self, address: &Address) -> Result<StoreAccountRef, Error>;
|
||||||
|
|
||||||
/// Create new vault with given password
|
/// Create new vault with given password
|
||||||
fn create_vault(&self, name: &str, password: &str) -> Result<(), Error>;
|
fn create_vault(&self, name: &str, password: &Password) -> Result<(), Error>;
|
||||||
/// Open vault with given password
|
/// Open vault with given password
|
||||||
fn open_vault(&self, name: &str, password: &str) -> Result<(), Error>;
|
fn open_vault(&self, name: &str, password: &Password) -> Result<(), Error>;
|
||||||
/// Close vault
|
/// Close vault
|
||||||
fn close_vault(&self, name: &str) -> Result<(), Error>;
|
fn close_vault(&self, name: &str) -> Result<(), Error>;
|
||||||
/// List all vaults
|
/// List all vaults
|
||||||
@ -93,7 +93,7 @@ pub trait SimpleSecretStore: Send + Sync {
|
|||||||
/// List all currently opened vaults
|
/// List all currently opened vaults
|
||||||
fn list_opened_vaults(&self) -> Result<Vec<String>, Error>;
|
fn list_opened_vaults(&self) -> Result<Vec<String>, Error>;
|
||||||
/// Change vault password
|
/// Change vault password
|
||||||
fn change_vault_password(&self, name: &str, new_password: &str) -> Result<(), Error>;
|
fn change_vault_password(&self, name: &str, new_password: &Password) -> Result<(), Error>;
|
||||||
/// Cnage account' vault
|
/// Cnage account' vault
|
||||||
fn change_account_vault(&self, vault: SecretVaultRef, account: StoreAccountRef) -> Result<StoreAccountRef, Error>;
|
fn change_account_vault(&self, vault: SecretVaultRef, account: StoreAccountRef) -> Result<StoreAccountRef, Error>;
|
||||||
/// Get vault metadata string.
|
/// Get vault metadata string.
|
||||||
@ -106,7 +106,7 @@ pub trait SimpleSecretStore: Send + Sync {
|
|||||||
pub trait SecretStore: SimpleSecretStore {
|
pub trait SecretStore: SimpleSecretStore {
|
||||||
|
|
||||||
/// Returns a raw opaque Secret that can be later used to sign a message.
|
/// Returns a raw opaque Secret that can be later used to sign a message.
|
||||||
fn raw_secret(&self, account: &StoreAccountRef, password: &str) -> Result<OpaqueSecret, Error>;
|
fn raw_secret(&self, account: &StoreAccountRef, password: &Password) -> Result<OpaqueSecret, Error>;
|
||||||
|
|
||||||
/// Signs a message with raw secret.
|
/// Signs a message with raw secret.
|
||||||
fn sign_with_secret(&self, secret: &OpaqueSecret, message: &Message) -> Result<Signature, Error> {
|
fn sign_with_secret(&self, secret: &OpaqueSecret, message: &Message) -> Result<Signature, Error> {
|
||||||
@ -114,16 +114,16 @@ pub trait SecretStore: SimpleSecretStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Imports presale wallet
|
/// Imports presale wallet
|
||||||
fn import_presale(&self, vault: SecretVaultRef, json: &[u8], password: &str) -> Result<StoreAccountRef, Error>;
|
fn import_presale(&self, vault: SecretVaultRef, json: &[u8], password: &Password) -> Result<StoreAccountRef, Error>;
|
||||||
/// Imports existing JSON wallet
|
/// Imports existing JSON wallet
|
||||||
fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str, gen_id: bool) -> Result<StoreAccountRef, Error>;
|
fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &Password, gen_id: bool) -> Result<StoreAccountRef, Error>;
|
||||||
/// Copies account between stores and vaults.
|
/// Copies account between stores and vaults.
|
||||||
fn copy_account(&self, new_store: &SimpleSecretStore, new_vault: SecretVaultRef, account: &StoreAccountRef, password: &str, new_password: &str) -> Result<(), Error>;
|
fn copy_account(&self, new_store: &SimpleSecretStore, new_vault: SecretVaultRef, account: &StoreAccountRef, password: &Password, new_password: &Password) -> Result<(), Error>;
|
||||||
/// Checks if password matches given account.
|
/// Checks if password matches given account.
|
||||||
fn test_password(&self, account: &StoreAccountRef, password: &str) -> Result<bool, Error>;
|
fn test_password(&self, account: &StoreAccountRef, password: &Password) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Returns a public key for given account.
|
/// Returns a public key for given account.
|
||||||
fn public(&self, account: &StoreAccountRef, password: &str) -> Result<Public, Error>;
|
fn public(&self, account: &StoreAccountRef, password: &Password) -> Result<Public, Error>;
|
||||||
|
|
||||||
/// Returns uuid of an account.
|
/// Returns uuid of an account.
|
||||||
fn uuid(&self, account: &StoreAccountRef) -> Result<Uuid, Error>;
|
fn uuid(&self, account: &StoreAccountRef) -> Result<Uuid, Error>;
|
||||||
|
@ -46,9 +46,9 @@ fn secret_store_create_account() {
|
|||||||
let dir = TransientDir::create().unwrap();
|
let dir = TransientDir::create().unwrap();
|
||||||
let store = EthStore::open(Box::new(dir)).unwrap();
|
let store = EthStore::open(Box::new(dir)).unwrap();
|
||||||
assert_eq!(store.accounts().unwrap().len(), 0);
|
assert_eq!(store.accounts().unwrap().len(), 0);
|
||||||
assert!(store.insert_account(SecretVaultRef::Root, random_secret(), "").is_ok());
|
assert!(store.insert_account(SecretVaultRef::Root, random_secret(), &"".into()).is_ok());
|
||||||
assert_eq!(store.accounts().unwrap().len(), 1);
|
assert_eq!(store.accounts().unwrap().len(), 1);
|
||||||
assert!(store.insert_account(SecretVaultRef::Root, random_secret(), "").is_ok());
|
assert!(store.insert_account(SecretVaultRef::Root, random_secret(), &"".into()).is_ok());
|
||||||
assert_eq!(store.accounts().unwrap().len(), 2);
|
assert_eq!(store.accounts().unwrap().len(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,36 +56,36 @@ fn secret_store_create_account() {
|
|||||||
fn secret_store_sign() {
|
fn secret_store_sign() {
|
||||||
let dir = TransientDir::create().unwrap();
|
let dir = TransientDir::create().unwrap();
|
||||||
let store = EthStore::open(Box::new(dir)).unwrap();
|
let store = EthStore::open(Box::new(dir)).unwrap();
|
||||||
assert!(store.insert_account(SecretVaultRef::Root, random_secret(), "").is_ok());
|
assert!(store.insert_account(SecretVaultRef::Root, random_secret(), &"".into()).is_ok());
|
||||||
let accounts = store.accounts().unwrap();
|
let accounts = store.accounts().unwrap();
|
||||||
assert_eq!(accounts.len(), 1);
|
assert_eq!(accounts.len(), 1);
|
||||||
assert!(store.sign(&accounts[0], "", &Default::default()).is_ok());
|
assert!(store.sign(&accounts[0], &"".into(), &Default::default()).is_ok());
|
||||||
assert!(store.sign(&accounts[0], "1", &Default::default()).is_err());
|
assert!(store.sign(&accounts[0], &"1".into(), &Default::default()).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn secret_store_change_password() {
|
fn secret_store_change_password() {
|
||||||
let dir = TransientDir::create().unwrap();
|
let dir = TransientDir::create().unwrap();
|
||||||
let store = EthStore::open(Box::new(dir)).unwrap();
|
let store = EthStore::open(Box::new(dir)).unwrap();
|
||||||
assert!(store.insert_account(SecretVaultRef::Root, random_secret(), "").is_ok());
|
assert!(store.insert_account(SecretVaultRef::Root, random_secret(), &"".into()).is_ok());
|
||||||
let accounts = store.accounts().unwrap();
|
let accounts = store.accounts().unwrap();
|
||||||
assert_eq!(accounts.len(), 1);
|
assert_eq!(accounts.len(), 1);
|
||||||
assert!(store.sign(&accounts[0], "", &Default::default()).is_ok());
|
assert!(store.sign(&accounts[0], &"".into(), &Default::default()).is_ok());
|
||||||
assert!(store.change_password(&accounts[0], "", "1").is_ok());
|
assert!(store.change_password(&accounts[0], &"".into(), &"1".into()).is_ok());
|
||||||
assert!(store.sign(&accounts[0], "", &Default::default()).is_err());
|
assert!(store.sign(&accounts[0], &"".into(), &Default::default()).is_err());
|
||||||
assert!(store.sign(&accounts[0], "1", &Default::default()).is_ok());
|
assert!(store.sign(&accounts[0], &"1".into(), &Default::default()).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn secret_store_remove_account() {
|
fn secret_store_remove_account() {
|
||||||
let dir = TransientDir::create().unwrap();
|
let dir = TransientDir::create().unwrap();
|
||||||
let store = EthStore::open(Box::new(dir)).unwrap();
|
let store = EthStore::open(Box::new(dir)).unwrap();
|
||||||
assert!(store.insert_account(SecretVaultRef::Root, random_secret(), "").is_ok());
|
assert!(store.insert_account(SecretVaultRef::Root, random_secret(), &"".into()).is_ok());
|
||||||
let accounts = store.accounts().unwrap();
|
let accounts = store.accounts().unwrap();
|
||||||
assert_eq!(accounts.len(), 1);
|
assert_eq!(accounts.len(), 1);
|
||||||
assert!(store.remove_account(&accounts[0], "").is_ok());
|
assert!(store.remove_account(&accounts[0], &"".into()).is_ok());
|
||||||
assert_eq!(store.accounts().unwrap().len(), 0);
|
assert_eq!(store.accounts().unwrap().len(), 0);
|
||||||
assert!(store.remove_account(&accounts[0], "").is_err());
|
assert!(store.remove_account(&accounts[0], &"".into()).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_path() -> &'static str {
|
fn test_path() -> &'static str {
|
||||||
@ -146,8 +146,8 @@ fn test_decrypting_files_with_short_ciphertext() {
|
|||||||
|
|
||||||
let message = Default::default();
|
let message = Default::default();
|
||||||
|
|
||||||
let s1 = store.sign(&accounts[0], "foo", &message).unwrap();
|
let s1 = store.sign(&accounts[0], &"foo".into(), &message).unwrap();
|
||||||
let s2 = store.sign(&accounts[1], "foo", &message).unwrap();
|
let s2 = store.sign(&accounts[1], &"foo".into(), &message).unwrap();
|
||||||
assert!(verify_address(&accounts[0].address, &s1, &message).unwrap());
|
assert!(verify_address(&accounts[0].address, &s1, &message).unwrap());
|
||||||
assert!(verify_address(&kp1.address(), &s1, &message).unwrap());
|
assert!(verify_address(&kp1.address(), &s1, &message).unwrap());
|
||||||
assert!(verify_address(&kp2.address(), &s2, &message).unwrap());
|
assert!(verify_address(&kp2.address(), &s2, &message).unwrap());
|
||||||
|
@ -85,7 +85,7 @@ fn secret_store(dir: Box<RootDiskDirectory>, iterations: Option<u32>) -> Result<
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new(n: NewAccount) -> Result<String, String> {
|
fn new(n: NewAccount) -> Result<String, String> {
|
||||||
let password: String = match n.password_file {
|
let password = match n.password_file {
|
||||||
Some(file) => password_from_file(file)?,
|
Some(file) => password_from_file(file)?,
|
||||||
None => password_prompt()?,
|
None => password_prompt()?,
|
||||||
};
|
};
|
||||||
|
@ -30,6 +30,7 @@ use upgrade::{upgrade, upgrade_data_paths};
|
|||||||
use sync::{validate_node_url, self};
|
use sync::{validate_node_url, self};
|
||||||
use db::migrate;
|
use db::migrate;
|
||||||
use path;
|
use path;
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
pub fn to_duration(s: &str) -> Result<Duration, String> {
|
pub fn to_duration(s: &str) -> Result<Duration, String> {
|
||||||
to_seconds(s).map(Duration::from_secs)
|
to_seconds(s).map(Duration::from_secs)
|
||||||
@ -277,7 +278,7 @@ pub fn execute_upgrades(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Prompts user asking for password.
|
/// Prompts user asking for password.
|
||||||
pub fn password_prompt() -> Result<String, String> {
|
pub fn password_prompt() -> Result<Password, String> {
|
||||||
use rpassword::read_password;
|
use rpassword::read_password;
|
||||||
const STDIN_ERROR: &'static str = "Unable to ask for password on non-interactive terminal.";
|
const STDIN_ERROR: &'static str = "Unable to ask for password on non-interactive terminal.";
|
||||||
|
|
||||||
@ -285,12 +286,12 @@ pub fn password_prompt() -> Result<String, String> {
|
|||||||
print!("Type password: ");
|
print!("Type password: ");
|
||||||
flush_stdout();
|
flush_stdout();
|
||||||
|
|
||||||
let password = read_password().map_err(|_| STDIN_ERROR.to_owned())?;
|
let password = read_password().map_err(|_| STDIN_ERROR.to_owned())?.into();
|
||||||
|
|
||||||
print!("Repeat password: ");
|
print!("Repeat password: ");
|
||||||
flush_stdout();
|
flush_stdout();
|
||||||
|
|
||||||
let password_repeat = read_password().map_err(|_| STDIN_ERROR.to_owned())?;
|
let password_repeat = read_password().map_err(|_| STDIN_ERROR.to_owned())?.into();
|
||||||
|
|
||||||
if password != password_repeat {
|
if password != password_repeat {
|
||||||
return Err("Passwords do not match!".into());
|
return Err("Passwords do not match!".into());
|
||||||
@ -300,24 +301,24 @@ pub fn password_prompt() -> Result<String, String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Read a password from password file.
|
/// Read a password from password file.
|
||||||
pub fn password_from_file(path: String) -> Result<String, String> {
|
pub fn password_from_file(path: String) -> Result<Password, String> {
|
||||||
let passwords = passwords_from_files(&[path])?;
|
let passwords = passwords_from_files(&[path])?;
|
||||||
// use only first password from the file
|
// use only first password from the file
|
||||||
passwords.get(0).map(String::to_owned)
|
passwords.get(0).map(Password::clone)
|
||||||
.ok_or_else(|| "Password file seems to be empty.".to_owned())
|
.ok_or_else(|| "Password file seems to be empty.".to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads passwords from files. Treats each line as a separate password.
|
/// Reads passwords from files. Treats each line as a separate password.
|
||||||
pub fn passwords_from_files(files: &[String]) -> Result<Vec<String>, String> {
|
pub fn passwords_from_files(files: &[String]) -> Result<Vec<Password>, String> {
|
||||||
let passwords = files.iter().map(|filename| {
|
let passwords = files.iter().map(|filename| {
|
||||||
let file = File::open(filename).map_err(|_| format!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename))?;
|
let file = File::open(filename).map_err(|_| format!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename))?;
|
||||||
let reader = BufReader::new(&file);
|
let reader = BufReader::new(&file);
|
||||||
let lines = reader.lines()
|
let lines = reader.lines()
|
||||||
.filter_map(|l| l.ok())
|
.filter_map(|l| l.ok())
|
||||||
.map(|pwd| pwd.trim().to_owned())
|
.map(|pwd| pwd.trim().to_owned().into())
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<Password>>();
|
||||||
Ok(lines)
|
Ok(lines)
|
||||||
}).collect::<Result<Vec<Vec<String>>, String>>();
|
}).collect::<Result<Vec<Vec<Password>>, String>>();
|
||||||
Ok(passwords?.into_iter().flat_map(|x| x).collect())
|
Ok(passwords?.into_iter().flat_map(|x| x).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,6 +331,7 @@ mod tests {
|
|||||||
use ethereum_types::U256;
|
use ethereum_types::U256;
|
||||||
use ethcore::client::{Mode, BlockId};
|
use ethcore::client::{Mode, BlockId};
|
||||||
use ethcore::miner::PendingSet;
|
use ethcore::miner::PendingSet;
|
||||||
|
use ethkey::Password;
|
||||||
use super::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_address, to_addresses, to_price, geth_ipc_path, to_bootnodes, password_from_file};
|
use super::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_address, to_addresses, to_price, geth_ipc_path, to_bootnodes, password_from_file};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -435,7 +437,7 @@ ignored
|
|||||||
but the first password is trimmed
|
but the first password is trimmed
|
||||||
|
|
||||||
"#).unwrap();
|
"#).unwrap();
|
||||||
assert_eq!(&password_from_file(path.to_str().unwrap().into()).unwrap(), "password with trailing whitespace");
|
assert_eq!(password_from_file(path.to_str().unwrap().into()).unwrap(), Password::from("password with trailing whitespace"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -30,7 +30,7 @@ pub struct ImportWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(cmd: ImportWallet) -> Result<String, String> {
|
pub fn execute(cmd: ImportWallet) -> Result<String, String> {
|
||||||
let password: String = match cmd.password_file {
|
let password = match cmd.password_file {
|
||||||
Some(file) => password_from_file(file)?,
|
Some(file) => password_from_file(file)?,
|
||||||
None => password_prompt()?,
|
None => password_prompt()?,
|
||||||
};
|
};
|
||||||
|
@ -63,6 +63,7 @@ use rpc_apis;
|
|||||||
use secretstore;
|
use secretstore;
|
||||||
use signer;
|
use signer;
|
||||||
use db;
|
use db;
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
// how often to take periodic snapshots.
|
// how often to take periodic snapshots.
|
||||||
const SNAPSHOT_PERIOD: u64 = 5000;
|
const SNAPSHOT_PERIOD: u64 = 5000;
|
||||||
@ -1002,7 +1003,7 @@ fn print_running_environment(spec_name: &String, dirs: &Directories, db_dirs: &D
|
|||||||
info!("Path to dapps {}", Colour::White.bold().paint(dapps_conf.dapps_path.to_string_lossy().into_owned()));
|
info!("Path to dapps {}", Colour::White.bold().paint(dapps_conf.dapps_path.to_string_lossy().into_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str, cfg: AccountsConfig, passwords: &[String]) -> Result<AccountProvider, String> {
|
fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str, cfg: AccountsConfig, passwords: &[Password]) -> Result<AccountProvider, String> {
|
||||||
use ethcore::ethstore::EthStore;
|
use ethcore::ethstore::EthStore;
|
||||||
use ethcore::ethstore::accounts_dir::RootDiskDirectory;
|
use ethcore::ethstore::accounts_dir::RootDiskDirectory;
|
||||||
|
|
||||||
@ -1058,7 +1059,7 @@ fn insert_dev_account(account_provider: &AccountProvider) {
|
|||||||
let secret: ethkey::Secret = "4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7".into();
|
let secret: ethkey::Secret = "4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7".into();
|
||||||
let dev_account = ethkey::KeyPair::from_secret(secret.clone()).expect("Valid secret produces valid key;qed");
|
let dev_account = ethkey::KeyPair::from_secret(secret.clone()).expect("Valid secret produces valid key;qed");
|
||||||
if !account_provider.has_account(dev_account.address()) {
|
if !account_provider.has_account(dev_account.address()) {
|
||||||
match account_provider.insert_account(secret, "") {
|
match account_provider.insert_account(secret, &Password::from(String::new())) {
|
||||||
Err(e) => warn!("Unable to add development account: {}", e),
|
Err(e) => warn!("Unable to add development account: {}", e),
|
||||||
Ok(address) => {
|
Ok(address) => {
|
||||||
let _ = account_provider.set_account_name(address.clone(), "Development Account".into());
|
let _ = account_provider.set_account_name(address.clone(), "Development Account".into());
|
||||||
|
@ -95,7 +95,7 @@ pub struct Dependencies<'a> {
|
|||||||
/// Account provider.
|
/// Account provider.
|
||||||
pub account_provider: Arc<AccountProvider>,
|
pub account_provider: Arc<AccountProvider>,
|
||||||
/// Passed accounts passwords.
|
/// Passed accounts passwords.
|
||||||
pub accounts_passwords: &'a [String],
|
pub accounts_passwords: &'a [Password],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "secretstore"))]
|
#[cfg(not(feature = "secretstore"))]
|
||||||
@ -209,6 +209,7 @@ mod server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub use self::server::KeyServer;
|
pub use self::server::KeyServer;
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
impl Default for Configuration {
|
impl Default for Configuration {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
@ -31,7 +31,7 @@ use bytes::Bytes;
|
|||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use stats::Corpus;
|
use stats::Corpus;
|
||||||
|
|
||||||
use ethkey::Signature;
|
use ethkey::{Password, Signature};
|
||||||
use sync::LightSync;
|
use sync::LightSync;
|
||||||
use ethcore::ids::BlockId;
|
use ethcore::ids::BlockId;
|
||||||
use ethcore::client::BlockChainClient;
|
use ethcore::client::BlockChainClient;
|
||||||
@ -560,15 +560,15 @@ impl Future for ProspectiveSigner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Single-use account token.
|
/// Single-use account token.
|
||||||
pub type AccountToken = String;
|
pub type AccountToken = Password;
|
||||||
|
|
||||||
/// Values used to unlock accounts for signing.
|
/// Values used to unlock accounts for signing.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub enum SignWith {
|
pub enum SignWith {
|
||||||
/// Nothing -- implies the account is already unlocked.
|
/// Nothing -- implies the account is already unlocked.
|
||||||
Nothing,
|
Nothing,
|
||||||
/// Unlock with password.
|
/// Unlock with password.
|
||||||
Password(String),
|
Password(Password),
|
||||||
/// Unlock with single-use token.
|
/// Unlock with single-use token.
|
||||||
Token(AccountToken),
|
Token(AccountToken),
|
||||||
}
|
}
|
||||||
@ -584,8 +584,7 @@ impl SignWith {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A value, potentially accompanied by a signing token.
|
/// A value, potentially accompanied by a signing token.
|
||||||
#[derive(Debug)]
|
pub enum WithToken<T> {
|
||||||
pub enum WithToken<T: Debug> {
|
|
||||||
/// No token.
|
/// No token.
|
||||||
No(T),
|
No(T),
|
||||||
/// With token.
|
/// With token.
|
||||||
|
@ -27,6 +27,7 @@ use jsonrpc_core::Result;
|
|||||||
use v1::helpers::errors;
|
use v1::helpers::errors;
|
||||||
use v1::traits::ParityAccounts;
|
use v1::traits::ParityAccounts;
|
||||||
use v1::types::{H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, DappId, Derive, DeriveHierarchical, DeriveHash, ExtAccountInfo};
|
use v1::types::{H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, DappId, Derive, DeriveHierarchical, DeriveHash, ExtAccountInfo};
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
/// Account management (personal) rpc implementation.
|
/// Account management (personal) rpc implementation.
|
||||||
pub struct ParityAccountsClient {
|
pub struct ParityAccountsClient {
|
||||||
@ -74,21 +75,21 @@ impl ParityAccounts for ParityAccountsClient {
|
|||||||
Ok(accounts)
|
Ok(accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_account_from_phrase(&self, phrase: String, pass: String) -> Result<RpcH160> {
|
fn new_account_from_phrase(&self, phrase: String, pass: Password) -> Result<RpcH160> {
|
||||||
let brain = Brain::new(phrase).generate().unwrap();
|
let brain = Brain::new(phrase).generate().unwrap();
|
||||||
self.accounts.insert_account(brain.secret().clone(), &pass)
|
self.accounts.insert_account(brain.secret().clone(), &pass)
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.map_err(|e| errors::account("Could not create account.", e))
|
.map_err(|e| errors::account("Could not create account.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_account_from_wallet(&self, json: String, pass: String) -> Result<RpcH160> {
|
fn new_account_from_wallet(&self, json: String, pass: Password) -> Result<RpcH160> {
|
||||||
self.accounts.import_presale(json.as_bytes(), &pass)
|
self.accounts.import_presale(json.as_bytes(), &pass)
|
||||||
.or_else(|_| self.accounts.import_wallet(json.as_bytes(), &pass, true))
|
.or_else(|_| self.accounts.import_wallet(json.as_bytes(), &pass, true))
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.map_err(|e| errors::account("Could not create account.", e))
|
.map_err(|e| errors::account("Could not create account.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_account_from_secret(&self, secret: RpcH256, pass: String) -> Result<RpcH160> {
|
fn new_account_from_secret(&self, secret: RpcH256, pass: Password) -> Result<RpcH160> {
|
||||||
let secret = Secret::from_unsafe_slice(&secret.0)
|
let secret = Secret::from_unsafe_slice(&secret.0)
|
||||||
.map_err(|e| errors::account("Could not create account.", e))?;
|
.map_err(|e| errors::account("Could not create account.", e))?;
|
||||||
self.accounts.insert_account(secret, &pass)
|
self.accounts.insert_account(secret, &pass)
|
||||||
@ -96,7 +97,7 @@ impl ParityAccounts for ParityAccountsClient {
|
|||||||
.map_err(|e| errors::account("Could not create account.", e))
|
.map_err(|e| errors::account("Could not create account.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_password(&self, account: RpcH160, password: String) -> Result<bool> {
|
fn test_password(&self, account: RpcH160, password: Password) -> Result<bool> {
|
||||||
let account: Address = account.into();
|
let account: Address = account.into();
|
||||||
|
|
||||||
self.accounts
|
self.accounts
|
||||||
@ -104,7 +105,7 @@ impl ParityAccounts for ParityAccountsClient {
|
|||||||
.map_err(|e| errors::account("Could not fetch account info.", e))
|
.map_err(|e| errors::account("Could not fetch account info.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_password(&self, account: RpcH160, password: String, new_password: String) -> Result<bool> {
|
fn change_password(&self, account: RpcH160, password: Password, new_password: Password) -> Result<bool> {
|
||||||
let account: Address = account.into();
|
let account: Address = account.into();
|
||||||
self.accounts
|
self.accounts
|
||||||
.change_password(&account, password, new_password)
|
.change_password(&account, password, new_password)
|
||||||
@ -112,7 +113,7 @@ impl ParityAccounts for ParityAccountsClient {
|
|||||||
.map_err(|e| errors::account("Could not fetch account info.", e))
|
.map_err(|e| errors::account("Could not fetch account info.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kill_account(&self, account: RpcH160, password: String) -> Result<bool> {
|
fn kill_account(&self, account: RpcH160, password: Password) -> Result<bool> {
|
||||||
let account: Address = account.into();
|
let account: Address = account.into();
|
||||||
self.accounts
|
self.accounts
|
||||||
.kill_account(&account, &password)
|
.kill_account(&account, &password)
|
||||||
@ -209,14 +210,14 @@ impl ParityAccounts for ParityAccountsClient {
|
|||||||
Ok(into_vec(self.accounts.list_geth_accounts(false)))
|
Ok(into_vec(self.accounts.list_geth_accounts(false)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_vault(&self, name: String, password: String) -> Result<bool> {
|
fn create_vault(&self, name: String, password: Password) -> Result<bool> {
|
||||||
self.accounts
|
self.accounts
|
||||||
.create_vault(&name, &password)
|
.create_vault(&name, &password)
|
||||||
.map_err(|e| errors::account("Could not create vault.", e))
|
.map_err(|e| errors::account("Could not create vault.", e))
|
||||||
.map(|_| true)
|
.map(|_| true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_vault(&self, name: String, password: String) -> Result<bool> {
|
fn open_vault(&self, name: String, password: Password) -> Result<bool> {
|
||||||
self.accounts
|
self.accounts
|
||||||
.open_vault(&name, &password)
|
.open_vault(&name, &password)
|
||||||
.map_err(|e| errors::account("Could not open vault.", e))
|
.map_err(|e| errors::account("Could not open vault.", e))
|
||||||
@ -242,7 +243,7 @@ impl ParityAccounts for ParityAccountsClient {
|
|||||||
.map_err(|e| errors::account("Could not list vaults.", e))
|
.map_err(|e| errors::account("Could not list vaults.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_vault_password(&self, name: String, new_password: String) -> Result<bool> {
|
fn change_vault_password(&self, name: String, new_password: Password) -> Result<bool> {
|
||||||
self.accounts
|
self.accounts
|
||||||
.change_vault_password(&name, &new_password)
|
.change_vault_password(&name, &new_password)
|
||||||
.map_err(|e| errors::account("Could not change vault password.", e))
|
.map_err(|e| errors::account("Could not change vault password.", e))
|
||||||
@ -269,7 +270,7 @@ impl ParityAccounts for ParityAccountsClient {
|
|||||||
.map(|_| true)
|
.map(|_| true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_key_index(&self, addr: RpcH160, password: String, derivation: DeriveHierarchical, save_as_account: bool) -> Result<RpcH160> {
|
fn derive_key_index(&self, addr: RpcH160, password: Password, derivation: DeriveHierarchical, save_as_account: bool) -> Result<RpcH160> {
|
||||||
let addr: Address = addr.into();
|
let addr: Address = addr.into();
|
||||||
self.accounts
|
self.accounts
|
||||||
.derive_account(
|
.derive_account(
|
||||||
@ -282,7 +283,7 @@ impl ParityAccounts for ParityAccountsClient {
|
|||||||
.map_err(|e| errors::account("Could not derive account.", e))
|
.map_err(|e| errors::account("Could not derive account.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_key_hash(&self, addr: RpcH160, password: String, derivation: DeriveHash, save_as_account: bool) -> Result<RpcH160> {
|
fn derive_key_hash(&self, addr: RpcH160, password: Password, derivation: DeriveHash, save_as_account: bool) -> Result<RpcH160> {
|
||||||
let addr: Address = addr.into();
|
let addr: Address = addr.into();
|
||||||
self.accounts
|
self.accounts
|
||||||
.derive_account(
|
.derive_account(
|
||||||
@ -295,7 +296,7 @@ impl ParityAccounts for ParityAccountsClient {
|
|||||||
.map_err(|e| errors::account("Could not derive account.", e))
|
.map_err(|e| errors::account("Could not derive account.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn export_account(&self, addr: RpcH160, password: String) -> Result<KeyFile> {
|
fn export_account(&self, addr: RpcH160, password: Password) -> Result<KeyFile> {
|
||||||
let addr = addr.into();
|
let addr = addr.into();
|
||||||
self.accounts
|
self.accounts
|
||||||
.export_account(
|
.export_account(
|
||||||
@ -306,7 +307,7 @@ impl ParityAccounts for ParityAccountsClient {
|
|||||||
.map_err(|e| errors::account("Could not export account.", e))
|
.map_err(|e| errors::account("Could not export account.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_message(&self, addr: RpcH160, password: String, message: RpcH256) -> Result<RpcH520> {
|
fn sign_message(&self, addr: RpcH160, password: Password, message: RpcH256) -> Result<RpcH520> {
|
||||||
self.accounts
|
self.accounts
|
||||||
.sign(
|
.sign(
|
||||||
addr.into(),
|
addr.into(),
|
||||||
|
@ -119,7 +119,7 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_engine_signer(&self, address: H160, password: String) -> Result<bool> {
|
fn set_engine_signer(&self, address: H160, password: String) -> Result<bool> {
|
||||||
self.miner.set_author(address.into(), Some(password)).map_err(Into::into).map_err(errors::password)?;
|
self.miner.set_author(address.into(), Some(password.into())).map_err(Into::into).map_err(errors::password)?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ impl<D: Dispatcher + 'static> PersonalClient<D> {
|
|||||||
Box::new(dispatcher.fill_optional_fields(request.into(), default, false)
|
Box::new(dispatcher.fill_optional_fields(request.into(), default, false)
|
||||||
.and_then(move |filled| {
|
.and_then(move |filled| {
|
||||||
let condition = filled.condition.clone().map(Into::into);
|
let condition = filled.condition.clone().map(Into::into);
|
||||||
dispatcher.sign(accounts, filled, SignWith::Password(password))
|
dispatcher.sign(accounts, filled, SignWith::Password(password.into()))
|
||||||
.map(|tx| tx.into_value())
|
.map(|tx| tx.into_value())
|
||||||
.map(move |tx| PendingTransaction::new(tx, condition))
|
.map(move |tx| PendingTransaction::new(tx, condition))
|
||||||
.map(move |tx| (tx, dispatcher))
|
.map(move |tx| (tx, dispatcher))
|
||||||
@ -95,7 +95,7 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new_account(&self, pass: String) -> Result<RpcH160> {
|
fn new_account(&self, pass: String) -> Result<RpcH160> {
|
||||||
self.accounts.new_account(&pass)
|
self.accounts.new_account(&pass.into())
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.map_err(|e| errors::account("Could not create account.", e))
|
.map_err(|e| errors::account("Could not create account.", e))
|
||||||
}
|
}
|
||||||
@ -117,14 +117,14 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let r = match (self.allow_perm_unlock, duration) {
|
let r = match (self.allow_perm_unlock, duration) {
|
||||||
(false, None) => store.unlock_account_temporarily(account, account_pass),
|
(false, None) => store.unlock_account_temporarily(account, account_pass.into()),
|
||||||
(false, _) => return Err(errors::unsupported(
|
(false, _) => return Err(errors::unsupported(
|
||||||
"Time-unlocking is only supported in --geth compatibility mode.",
|
"Time-unlocking is only supported in --geth compatibility mode.",
|
||||||
Some("Restart your client with --geth flag or use personal_sendTransaction instead."),
|
Some("Restart your client with --geth flag or use personal_sendTransaction instead."),
|
||||||
)),
|
)),
|
||||||
(true, Some(0)) => store.unlock_account_permanently(account, account_pass),
|
(true, Some(0)) => store.unlock_account_permanently(account, account_pass.into()),
|
||||||
(true, Some(d)) => store.unlock_account_timed(account, account_pass, Duration::from_secs(d.into())),
|
(true, Some(d)) => store.unlock_account_timed(account, account_pass.into(), Duration::from_secs(d.into())),
|
||||||
(true, None) => store.unlock_account_timed(account, account_pass, Duration::from_secs(300)),
|
(true, None) => store.unlock_account_timed(account, account_pass.into(), Duration::from_secs(300)),
|
||||||
};
|
};
|
||||||
match r {
|
match r {
|
||||||
Ok(_) => Ok(true),
|
Ok(_) => Ok(true),
|
||||||
@ -140,7 +140,7 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
|
|||||||
|
|
||||||
Box::new(dispatch::from_rpc(payload, account.into(), &dispatcher)
|
Box::new(dispatch::from_rpc(payload, account.into(), &dispatcher)
|
||||||
.and_then(|payload| {
|
.and_then(|payload| {
|
||||||
dispatch::execute(dispatcher, accounts, payload, dispatch::SignWith::Password(password))
|
dispatch::execute(dispatcher, accounts, payload, dispatch::SignWith::Password(password.into()))
|
||||||
})
|
})
|
||||||
.map(|v| v.into_value())
|
.map(|v| v.into_value())
|
||||||
.then(|res| match res {
|
.then(|res| match res {
|
||||||
|
@ -29,6 +29,7 @@ use v1::helpers::secretstore::{generate_document_key, encrypt_document,
|
|||||||
decrypt_document, decrypt_document_with_shadow, ordered_servers_keccak};
|
decrypt_document, decrypt_document_with_shadow, ordered_servers_keccak};
|
||||||
use v1::traits::SecretStore;
|
use v1::traits::SecretStore;
|
||||||
use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey};
|
use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey};
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
/// Parity implementation.
|
/// Parity implementation.
|
||||||
pub struct SecretStoreClient {
|
pub struct SecretStoreClient {
|
||||||
@ -44,36 +45,36 @@ impl SecretStoreClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypt public key using account' private key
|
/// Decrypt public key using account' private key
|
||||||
fn decrypt_key(&self, address: H160, password: String, key: Bytes) -> Result<Vec<u8>> {
|
fn decrypt_key(&self, address: H160, password: Password, key: Bytes) -> Result<Vec<u8>> {
|
||||||
self.accounts.decrypt(address.into(), Some(password), &DEFAULT_MAC, &key.0)
|
self.accounts.decrypt(address.into(), Some(password), &DEFAULT_MAC, &key.0)
|
||||||
.map_err(|e| errors::account("Could not decrypt key.", e))
|
.map_err(|e| errors::account("Could not decrypt key.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypt secret key using account' private key
|
/// Decrypt secret key using account' private key
|
||||||
fn decrypt_secret(&self, address: H160, password: String, key: Bytes) -> Result<Secret> {
|
fn decrypt_secret(&self, address: H160, password: Password, key: Bytes) -> Result<Secret> {
|
||||||
self.decrypt_key(address, password, key)
|
self.decrypt_key(address, password, key)
|
||||||
.and_then(|s| Secret::from_unsafe_slice(&s).map_err(|e| errors::account("invalid secret", e)))
|
.and_then(|s| Secret::from_unsafe_slice(&s).map_err(|e| errors::account("invalid secret", e)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SecretStore for SecretStoreClient {
|
impl SecretStore for SecretStoreClient {
|
||||||
fn generate_document_key(&self, address: H160, password: String, server_key_public: H512) -> Result<EncryptedDocumentKey> {
|
fn generate_document_key(&self, address: H160, password: Password, server_key_public: H512) -> Result<EncryptedDocumentKey> {
|
||||||
let account_public = self.accounts.account_public(address.into(), &password)
|
let account_public = self.accounts.account_public(address.into(), &password)
|
||||||
.map_err(|e| errors::account("Could not read account public.", e))?;
|
.map_err(|e| errors::account("Could not read account public.", e))?;
|
||||||
generate_document_key(account_public, server_key_public.into())
|
generate_document_key(account_public, server_key_public.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encrypt(&self, address: H160, password: String, key: Bytes, data: Bytes) -> Result<Bytes> {
|
fn encrypt(&self, address: H160, password: Password, key: Bytes, data: Bytes) -> Result<Bytes> {
|
||||||
encrypt_document(self.decrypt_key(address, password, key)?, data.0)
|
encrypt_document(self.decrypt_key(address, password, key)?, data.0)
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrypt(&self, address: H160, password: String, key: Bytes, data: Bytes) -> Result<Bytes> {
|
fn decrypt(&self, address: H160, password: Password, key: Bytes, data: Bytes) -> Result<Bytes> {
|
||||||
decrypt_document(self.decrypt_key(address, password, key)?, data.0)
|
decrypt_document(self.decrypt_key(address, password, key)?, data.0)
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shadow_decrypt(&self, address: H160, password: String, decrypted_secret: H512, common_point: H512, decrypt_shadows: Vec<Bytes>, data: Bytes) -> Result<Bytes> {
|
fn shadow_decrypt(&self, address: H160, password: Password, decrypted_secret: H512, common_point: H512, decrypt_shadows: Vec<Bytes>, data: Bytes) -> Result<Bytes> {
|
||||||
let mut shadows = Vec::with_capacity(decrypt_shadows.len());
|
let mut shadows = Vec::with_capacity(decrypt_shadows.len());
|
||||||
for decrypt_shadow in decrypt_shadows {
|
for decrypt_shadow in decrypt_shadows {
|
||||||
shadows.push(self.decrypt_secret(address.clone(), password.clone(), decrypt_shadow)?);
|
shadows.push(self.decrypt_secret(address.clone(), password.clone(), decrypt_shadow)?);
|
||||||
@ -87,7 +88,7 @@ impl SecretStore for SecretStoreClient {
|
|||||||
Ok(ordered_servers_keccak(servers_set))
|
Ok(ordered_servers_keccak(servers_set))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_raw_hash(&self, address: H160, password: String, raw_hash: H256) -> Result<Bytes> {
|
fn sign_raw_hash(&self, address: H160, password: Password, raw_hash: H256) -> Result<Bytes> {
|
||||||
self.accounts
|
self.accounts
|
||||||
.sign(address.into(), Some(password), raw_hash.into())
|
.sign(address.into(), Some(password), raw_hash.into())
|
||||||
.map(|s| Bytes::new((*s).to_vec()))
|
.map(|s| Bytes::new((*s).to_vec()))
|
||||||
|
@ -169,7 +169,7 @@ impl<D: Dispatcher + 'static> Signer for SignerClient<D> {
|
|||||||
-> BoxFuture<ConfirmationResponse>
|
-> BoxFuture<ConfirmationResponse>
|
||||||
{
|
{
|
||||||
Box::new(self.confirm_internal(id, modification, move |dis, accounts, payload| {
|
Box::new(self.confirm_internal(id, modification, move |dis, accounts, payload| {
|
||||||
dispatch::execute(dis, accounts, payload, dispatch::SignWith::Password(pass))
|
dispatch::execute(dis, accounts, payload, dispatch::SignWith::Password(pass.into()))
|
||||||
}).map(|v| v.into_value()))
|
}).map(|v| v.into_value()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ impl<D: Dispatcher + 'static> Signer for SignerClient<D> {
|
|||||||
-> BoxFuture<ConfirmationResponseWithToken>
|
-> BoxFuture<ConfirmationResponseWithToken>
|
||||||
{
|
{
|
||||||
Box::new(self.confirm_internal(id, modification, move |dis, accounts, payload| {
|
Box::new(self.confirm_internal(id, modification, move |dis, accounts, payload| {
|
||||||
dispatch::execute(dis, accounts, payload, dispatch::SignWith::Token(token))
|
dispatch::execute(dis, accounts, payload, dispatch::SignWith::Token(token.into()))
|
||||||
}).and_then(|v| match v {
|
}).and_then(|v| match v {
|
||||||
WithToken::No(_) => Err(errors::internal("Unexpected response without token.", "")),
|
WithToken::No(_) => Err(errors::internal("Unexpected response without token.", "")),
|
||||||
WithToken::Yes(response, token) => Ok(ConfirmationResponseWithToken {
|
WithToken::Yes(response, token) => Ok(ConfirmationResponseWithToken {
|
||||||
|
@ -317,7 +317,7 @@ const POSITIVE_NONCE_SPEC: &'static [u8] = br#"{
|
|||||||
fn eth_transaction_count() {
|
fn eth_transaction_count() {
|
||||||
let secret = "8a283037bb19c4fed7b1c569e40c7dcff366165eb869110a1b11532963eb9cb2".parse().unwrap();
|
let secret = "8a283037bb19c4fed7b1c569e40c7dcff366165eb869110a1b11532963eb9cb2".parse().unwrap();
|
||||||
let tester = EthTester::from_spec(Spec::load(&env::temp_dir(), TRANSACTION_COUNT_SPEC).expect("invalid chain spec"));
|
let tester = EthTester::from_spec(Spec::load(&env::temp_dir(), TRANSACTION_COUNT_SPEC).expect("invalid chain spec"));
|
||||||
let address = tester.accounts.insert_account(secret, "").unwrap();
|
let address = tester.accounts.insert_account(secret, &"".into()).unwrap();
|
||||||
tester.accounts.unlock_account_permanently(address, "".into()).unwrap();
|
tester.accounts.unlock_account_permanently(address, "".into()).unwrap();
|
||||||
|
|
||||||
let req_before = r#"{
|
let req_before = r#"{
|
||||||
|
@ -35,6 +35,7 @@ use miner::pool::{verifier, VerifiedTransaction, QueueStatus};
|
|||||||
use parking_lot::{RwLock, Mutex};
|
use parking_lot::{RwLock, Mutex};
|
||||||
use transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction};
|
use transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction};
|
||||||
use txpool;
|
use txpool;
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
/// Test miner service.
|
/// Test miner service.
|
||||||
pub struct TestMinerService {
|
pub struct TestMinerService {
|
||||||
@ -49,7 +50,7 @@ pub struct TestMinerService {
|
|||||||
/// Next nonces.
|
/// Next nonces.
|
||||||
pub next_nonces: RwLock<HashMap<Address, U256>>,
|
pub next_nonces: RwLock<HashMap<Address, U256>>,
|
||||||
/// Password held by Engine.
|
/// Password held by Engine.
|
||||||
pub password: RwLock<String>,
|
pub password: RwLock<Password>,
|
||||||
|
|
||||||
authoring_params: RwLock<AuthoringParams>,
|
authoring_params: RwLock<AuthoringParams>,
|
||||||
}
|
}
|
||||||
@ -62,7 +63,7 @@ impl Default for TestMinerService {
|
|||||||
local_transactions: Mutex::new(BTreeMap::new()),
|
local_transactions: Mutex::new(BTreeMap::new()),
|
||||||
pending_receipts: Mutex::new(BTreeMap::new()),
|
pending_receipts: Mutex::new(BTreeMap::new()),
|
||||||
next_nonces: RwLock::new(HashMap::new()),
|
next_nonces: RwLock::new(HashMap::new()),
|
||||||
password: RwLock::new(String::new()),
|
password: RwLock::new("".into()),
|
||||||
authoring_params: RwLock::new(AuthoringParams {
|
authoring_params: RwLock::new(AuthoringParams {
|
||||||
author: Address::zero(),
|
author: Address::zero(),
|
||||||
gas_range_target: (12345.into(), 54321.into()),
|
gas_range_target: (12345.into(), 54321.into()),
|
||||||
@ -119,7 +120,7 @@ impl MinerService for TestMinerService {
|
|||||||
self.authoring_params.read().clone()
|
self.authoring_params.read().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_author(&self, author: Address, password: Option<String>) -> Result<(), AccountError> {
|
fn set_author(&self, author: Address, password: Option<Password>) -> Result<(), AccountError> {
|
||||||
self.authoring_params.write().author = author;
|
self.authoring_params.write().author = author;
|
||||||
if let Some(password) = password {
|
if let Some(password) = password {
|
||||||
*self.password.write() = password;
|
*self.password.write() = password;
|
||||||
|
@ -328,7 +328,7 @@ fn rpc_eth_submit_hashrate() {
|
|||||||
fn rpc_eth_sign() {
|
fn rpc_eth_sign() {
|
||||||
let tester = EthTester::default();
|
let tester = EthTester::default();
|
||||||
|
|
||||||
let account = tester.accounts_provider.insert_account(Secret::from([69u8; 32]), "abcd").unwrap();
|
let account = tester.accounts_provider.insert_account(Secret::from([69u8; 32]), &"abcd".into()).unwrap();
|
||||||
tester.accounts_provider.unlock_account_permanently(account, "abcd".into()).unwrap();
|
tester.accounts_provider.unlock_account_permanently(account, "abcd".into()).unwrap();
|
||||||
let _message = "0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f".from_hex().unwrap();
|
let _message = "0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f".from_hex().unwrap();
|
||||||
|
|
||||||
@ -362,11 +362,11 @@ fn rpc_eth_author() {
|
|||||||
assert_eq!(tester.io.handle_request_sync(req), Some(make_res(Address::zero())));
|
assert_eq!(tester.io.handle_request_sync(req), Some(make_res(Address::zero())));
|
||||||
|
|
||||||
// Account set - return first account
|
// Account set - return first account
|
||||||
let addr = tester.accounts_provider.new_account("123").unwrap();
|
let addr = tester.accounts_provider.new_account(&"123".into()).unwrap();
|
||||||
assert_eq!(tester.io.handle_request_sync(req), Some(make_res(addr)));
|
assert_eq!(tester.io.handle_request_sync(req), Some(make_res(addr)));
|
||||||
|
|
||||||
for i in 0..20 {
|
for i in 0..20 {
|
||||||
let addr = tester.accounts_provider.new_account(&format!("{}", i)).unwrap();
|
let addr = tester.accounts_provider.new_account(&format!("{}", i).into()).unwrap();
|
||||||
tester.miner.set_author(addr.clone(), None).unwrap();
|
tester.miner.set_author(addr.clone(), None).unwrap();
|
||||||
|
|
||||||
assert_eq!(tester.io.handle_request_sync(req), Some(make_res(addr)));
|
assert_eq!(tester.io.handle_request_sync(req), Some(make_res(addr)));
|
||||||
@ -394,7 +394,7 @@ fn rpc_eth_gas_price() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_accounts() {
|
fn rpc_eth_accounts() {
|
||||||
let tester = EthTester::default();
|
let tester = EthTester::default();
|
||||||
let address = tester.accounts_provider.new_account("").unwrap();
|
let address = tester.accounts_provider.new_account(&"".into()).unwrap();
|
||||||
tester.accounts_provider.set_new_dapps_addresses(None).unwrap();
|
tester.accounts_provider.set_new_dapps_addresses(None).unwrap();
|
||||||
tester.accounts_provider.set_address_name(1.into(), "1".into());
|
tester.accounts_provider.set_address_name(1.into(), "1".into());
|
||||||
tester.accounts_provider.set_address_name(10.into(), "10".into());
|
tester.accounts_provider.set_address_name(10.into(), "10".into());
|
||||||
@ -804,7 +804,7 @@ fn rpc_eth_estimate_gas_default_block() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_send_transaction() {
|
fn rpc_eth_send_transaction() {
|
||||||
let tester = EthTester::default();
|
let tester = EthTester::default();
|
||||||
let address = tester.accounts_provider.new_account("").unwrap();
|
let address = tester.accounts_provider.new_account(&"".into()).unwrap();
|
||||||
tester.accounts_provider.unlock_account_permanently(address, "".into()).unwrap();
|
tester.accounts_provider.unlock_account_permanently(address, "".into()).unwrap();
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
@ -855,7 +855,7 @@ fn rpc_eth_send_transaction() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_sign_transaction() {
|
fn rpc_eth_sign_transaction() {
|
||||||
let tester = EthTester::default();
|
let tester = EthTester::default();
|
||||||
let address = tester.accounts_provider.new_account("").unwrap();
|
let address = tester.accounts_provider.new_account(&"".into()).unwrap();
|
||||||
tester.accounts_provider.unlock_account_permanently(address, "".into()).unwrap();
|
tester.accounts_provider.unlock_account_permanently(address, "".into()).unwrap();
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
@ -912,7 +912,7 @@ fn rpc_eth_sign_transaction() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_send_transaction_with_bad_to() {
|
fn rpc_eth_send_transaction_with_bad_to() {
|
||||||
let tester = EthTester::default();
|
let tester = EthTester::default();
|
||||||
let address = tester.accounts_provider.new_account("").unwrap();
|
let address = tester.accounts_provider.new_account(&"".into()).unwrap();
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "eth_sendTransaction",
|
"method": "eth_sendTransaction",
|
||||||
@ -934,7 +934,7 @@ fn rpc_eth_send_transaction_with_bad_to() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_send_transaction_error() {
|
fn rpc_eth_send_transaction_error() {
|
||||||
let tester = EthTester::default();
|
let tester = EthTester::default();
|
||||||
let address = tester.accounts_provider.new_account("").unwrap();
|
let address = tester.accounts_provider.new_account(&"".into()).unwrap();
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "eth_sendTransaction",
|
"method": "eth_sendTransaction",
|
||||||
@ -972,7 +972,7 @@ fn rpc_eth_send_raw_transaction_error() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_send_raw_transaction() {
|
fn rpc_eth_send_raw_transaction() {
|
||||||
let tester = EthTester::default();
|
let tester = EthTester::default();
|
||||||
let address = tester.accounts_provider.new_account("abcd").unwrap();
|
let address = tester.accounts_provider.new_account(&"abcd".into()).unwrap();
|
||||||
tester.accounts_provider.unlock_account_permanently(address, "abcd".into()).unwrap();
|
tester.accounts_provider.unlock_account_permanently(address, "abcd".into()).unwrap();
|
||||||
|
|
||||||
let t = Transaction {
|
let t = Transaction {
|
||||||
|
@ -122,7 +122,7 @@ fn rpc_parity_accounts_info() {
|
|||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
deps.accounts.new_account("").unwrap();
|
deps.accounts.new_account(&"".into()).unwrap();
|
||||||
let accounts = deps.accounts.accounts().unwrap();
|
let accounts = deps.accounts.accounts().unwrap();
|
||||||
assert_eq!(accounts.len(), 1);
|
assert_eq!(accounts.len(), 1);
|
||||||
let address = accounts[0];
|
let address = accounts[0];
|
||||||
@ -155,7 +155,7 @@ fn rpc_parity_default_account() {
|
|||||||
assert_eq!(io.handle_request_sync(request), Some(response));
|
assert_eq!(io.handle_request_sync(request), Some(response));
|
||||||
|
|
||||||
// With account
|
// With account
|
||||||
deps.accounts.new_account("").unwrap();
|
deps.accounts.new_account(&"".into()).unwrap();
|
||||||
let accounts = deps.accounts.accounts().unwrap();
|
let accounts = deps.accounts.accounts().unwrap();
|
||||||
assert_eq!(accounts.len(), 1);
|
assert_eq!(accounts.len(), 1);
|
||||||
let address = accounts[0];
|
let address = accounts[0];
|
||||||
|
@ -64,7 +64,7 @@ fn setup_with_vaults_support(temp_path: &str) -> ParityAccountsTester {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_be_able_to_get_account_info() {
|
fn should_be_able_to_get_account_info() {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
tester.accounts.new_account("").unwrap();
|
tester.accounts.new_account(&"".into()).unwrap();
|
||||||
let accounts = tester.accounts.accounts().unwrap();
|
let accounts = tester.accounts.accounts().unwrap();
|
||||||
assert_eq!(accounts.len(), 1);
|
assert_eq!(accounts.len(), 1);
|
||||||
let address = accounts[0];
|
let address = accounts[0];
|
||||||
@ -82,7 +82,7 @@ fn should_be_able_to_get_account_info() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_be_able_to_set_name() {
|
fn should_be_able_to_set_name() {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
tester.accounts.new_account("").unwrap();
|
tester.accounts.new_account(&"".into()).unwrap();
|
||||||
let accounts = tester.accounts.accounts().unwrap();
|
let accounts = tester.accounts.accounts().unwrap();
|
||||||
assert_eq!(accounts.len(), 1);
|
assert_eq!(accounts.len(), 1);
|
||||||
let address = accounts[0];
|
let address = accounts[0];
|
||||||
@ -103,7 +103,7 @@ fn should_be_able_to_set_name() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_be_able_to_set_meta() {
|
fn should_be_able_to_set_meta() {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
tester.accounts.new_account("").unwrap();
|
tester.accounts.new_account(&"".into()).unwrap();
|
||||||
let accounts = tester.accounts.accounts().unwrap();
|
let accounts = tester.accounts.accounts().unwrap();
|
||||||
assert_eq!(accounts.len(), 1);
|
assert_eq!(accounts.len(), 1);
|
||||||
let address = accounts[0];
|
let address = accounts[0];
|
||||||
@ -224,7 +224,7 @@ fn rpc_parity_recent_dapps() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_be_able_to_kill_account() {
|
fn should_be_able_to_kill_account() {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
tester.accounts.new_account("password").unwrap();
|
tester.accounts.new_account(&"password".into()).unwrap();
|
||||||
let accounts = tester.accounts.accounts().unwrap();
|
let accounts = tester.accounts.accounts().unwrap();
|
||||||
assert_eq!(accounts.len(), 1);
|
assert_eq!(accounts.len(), 1);
|
||||||
let address = accounts[0];
|
let address = accounts[0];
|
||||||
@ -282,7 +282,7 @@ fn rpc_parity_new_vault() {
|
|||||||
|
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
assert!(tester.accounts.close_vault("vault1").is_ok());
|
assert!(tester.accounts.close_vault("vault1").is_ok());
|
||||||
assert!(tester.accounts.open_vault("vault1", "password1").is_ok());
|
assert!(tester.accounts.open_vault("vault1", &"password1".into()).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -290,7 +290,7 @@ fn rpc_parity_open_vault() {
|
|||||||
let tempdir = TempDir::new("").unwrap();
|
let tempdir = TempDir::new("").unwrap();
|
||||||
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
||||||
|
|
||||||
assert!(tester.accounts.create_vault("vault1", "password1").is_ok());
|
assert!(tester.accounts.create_vault("vault1", &"password1".into()).is_ok());
|
||||||
assert!(tester.accounts.close_vault("vault1").is_ok());
|
assert!(tester.accounts.close_vault("vault1").is_ok());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_openVault", "params":["vault1", "password1"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_openVault", "params":["vault1", "password1"], "id": 1}"#;
|
||||||
@ -304,7 +304,7 @@ fn rpc_parity_close_vault() {
|
|||||||
let tempdir = TempDir::new("").unwrap();
|
let tempdir = TempDir::new("").unwrap();
|
||||||
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
||||||
|
|
||||||
assert!(tester.accounts.create_vault("vault1", "password1").is_ok());
|
assert!(tester.accounts.create_vault("vault1", &"password1".into()).is_ok());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_closeVault", "params":["vault1"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_closeVault", "params":["vault1"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
@ -317,7 +317,7 @@ fn rpc_parity_change_vault_password() {
|
|||||||
let tempdir = TempDir::new("").unwrap();
|
let tempdir = TempDir::new("").unwrap();
|
||||||
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
||||||
|
|
||||||
assert!(tester.accounts.create_vault("vault1", "password1").is_ok());
|
assert!(tester.accounts.create_vault("vault1", &"password1".into()).is_ok());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_changeVaultPassword", "params":["vault1", "password2"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_changeVaultPassword", "params":["vault1", "password2"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
@ -330,8 +330,8 @@ fn rpc_parity_change_vault() {
|
|||||||
let tempdir = TempDir::new("").unwrap();
|
let tempdir = TempDir::new("").unwrap();
|
||||||
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
||||||
|
|
||||||
let (address, _) = tester.accounts.new_account_and_public("root_password").unwrap();
|
let (address, _) = tester.accounts.new_account_and_public(&"root_password".into()).unwrap();
|
||||||
assert!(tester.accounts.create_vault("vault1", "password1").is_ok());
|
assert!(tester.accounts.create_vault("vault1", &"password1".into()).is_ok());
|
||||||
|
|
||||||
let request = format!(r#"{{"jsonrpc": "2.0", "method": "parity_changeVault", "params":["0x{:x}", "vault1"], "id": 1}}"#, address);
|
let request = format!(r#"{{"jsonrpc": "2.0", "method": "parity_changeVault", "params":["0x{:x}", "vault1"], "id": 1}}"#, address);
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
@ -344,9 +344,9 @@ fn rpc_parity_vault_adds_vault_field_to_acount_meta() {
|
|||||||
let tempdir = TempDir::new("").unwrap();
|
let tempdir = TempDir::new("").unwrap();
|
||||||
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
||||||
|
|
||||||
let (address1, _) = tester.accounts.new_account_and_public("root_password1").unwrap();
|
let (address1, _) = tester.accounts.new_account_and_public(&"root_password1".into()).unwrap();
|
||||||
let uuid1 = tester.accounts.account_meta(address1.clone()).unwrap().uuid.unwrap();
|
let uuid1 = tester.accounts.account_meta(address1.clone()).unwrap().uuid.unwrap();
|
||||||
assert!(tester.accounts.create_vault("vault1", "password1").is_ok());
|
assert!(tester.accounts.create_vault("vault1", &"password1".into()).is_ok());
|
||||||
assert!(tester.accounts.change_vault(address1, "vault1").is_ok());
|
assert!(tester.accounts.change_vault(address1, "vault1").is_ok());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_allAccountsInfo", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_allAccountsInfo", "params":[], "id": 1}"#;
|
||||||
@ -368,8 +368,8 @@ fn rpc_parity_list_vaults() {
|
|||||||
let tempdir = TempDir::new("").unwrap();
|
let tempdir = TempDir::new("").unwrap();
|
||||||
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
||||||
|
|
||||||
assert!(tester.accounts.create_vault("vault1", "password1").is_ok());
|
assert!(tester.accounts.create_vault("vault1", &"password1".into()).is_ok());
|
||||||
assert!(tester.accounts.create_vault("vault2", "password2").is_ok());
|
assert!(tester.accounts.create_vault("vault2", &"password2".into()).is_ok());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_listVaults", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_listVaults", "params":[], "id": 1}"#;
|
||||||
let response1 = r#"{"jsonrpc":"2.0","result":["vault1","vault2"],"id":1}"#;
|
let response1 = r#"{"jsonrpc":"2.0","result":["vault1","vault2"],"id":1}"#;
|
||||||
@ -385,9 +385,9 @@ fn rpc_parity_list_opened_vaults() {
|
|||||||
let tempdir = TempDir::new("").unwrap();
|
let tempdir = TempDir::new("").unwrap();
|
||||||
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
||||||
|
|
||||||
assert!(tester.accounts.create_vault("vault1", "password1").is_ok());
|
assert!(tester.accounts.create_vault("vault1", &"password1".into()).is_ok());
|
||||||
assert!(tester.accounts.create_vault("vault2", "password2").is_ok());
|
assert!(tester.accounts.create_vault("vault2", &"password2".into()).is_ok());
|
||||||
assert!(tester.accounts.create_vault("vault3", "password3").is_ok());
|
assert!(tester.accounts.create_vault("vault3", &"password3".into()).is_ok());
|
||||||
assert!(tester.accounts.close_vault("vault2").is_ok());
|
assert!(tester.accounts.close_vault("vault2").is_ok());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_listOpenedVaults", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_listOpenedVaults", "params":[], "id": 1}"#;
|
||||||
@ -404,7 +404,7 @@ fn rpc_parity_get_set_vault_meta() {
|
|||||||
let tempdir = TempDir::new("").unwrap();
|
let tempdir = TempDir::new("").unwrap();
|
||||||
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
let tester = setup_with_vaults_support(tempdir.path().to_str().unwrap());
|
||||||
|
|
||||||
assert!(tester.accounts.create_vault("vault1", "password1").is_ok());
|
assert!(tester.accounts.create_vault("vault1", &"password1".into()).is_ok());
|
||||||
|
|
||||||
// when no meta set
|
// when no meta set
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getVaultMeta", "params":["vault1"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_getVaultMeta", "params":["vault1"], "id": 1}"#;
|
||||||
@ -441,7 +441,7 @@ fn derive_key_hash() {
|
|||||||
let hash = tester.accounts
|
let hash = tester.accounts
|
||||||
.insert_account(
|
.insert_account(
|
||||||
"0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a".parse().unwrap(),
|
"0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a".parse().unwrap(),
|
||||||
"password1")
|
&"password1".into())
|
||||||
.expect("account should be inserted ok");
|
.expect("account should be inserted ok");
|
||||||
|
|
||||||
assert_eq!(hash, "c171033d5cbff7175f29dfd3a63dda3d6f8f385e".parse().unwrap());
|
assert_eq!(hash, "c171033d5cbff7175f29dfd3a63dda3d6f8f385e".parse().unwrap());
|
||||||
@ -461,7 +461,7 @@ fn derive_key_index() {
|
|||||||
let hash = tester.accounts
|
let hash = tester.accounts
|
||||||
.insert_account(
|
.insert_account(
|
||||||
"0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a".parse().unwrap(),
|
"0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a".parse().unwrap(),
|
||||||
"password1")
|
&"password1".into())
|
||||||
.expect("account should be inserted ok");
|
.expect("account should be inserted ok");
|
||||||
|
|
||||||
assert_eq!(hash, "c171033d5cbff7175f29dfd3a63dda3d6f8f385e".parse().unwrap());
|
assert_eq!(hash, "c171033d5cbff7175f29dfd3a63dda3d6f8f385e".parse().unwrap());
|
||||||
@ -478,7 +478,7 @@ fn should_export_account() {
|
|||||||
// given
|
// given
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
let wallet = r#"{"id":"6a186c80-7797-cff2-bc2e-7c1d6a6cc76e","version":3,"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"a1c6ff99070f8032ca1c4e8add006373"},"ciphertext":"df27e3db64aa18d984b6439443f73660643c2d119a6f0fa2fa9a6456fc802d75","kdf":"pbkdf2","kdfparams":{"c":10240,"dklen":32,"prf":"hmac-sha256","salt":"ddc325335cda5567a1719313e73b4842511f3e4a837c9658eeb78e51ebe8c815"},"mac":"3dc888ae79cbb226ff9c455669f6cf2d79be72120f2298f6cb0d444fddc0aa3d"},"address":"0042e5d2a662eeaca8a7e828c174f98f35d8925b","name":"parity-export-test","meta":"{\"passwordHint\":\"parity-export-test\",\"timestamp\":1490017814987}"}"#;
|
let wallet = r#"{"id":"6a186c80-7797-cff2-bc2e-7c1d6a6cc76e","version":3,"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"a1c6ff99070f8032ca1c4e8add006373"},"ciphertext":"df27e3db64aa18d984b6439443f73660643c2d119a6f0fa2fa9a6456fc802d75","kdf":"pbkdf2","kdfparams":{"c":10240,"dklen":32,"prf":"hmac-sha256","salt":"ddc325335cda5567a1719313e73b4842511f3e4a837c9658eeb78e51ebe8c815"},"mac":"3dc888ae79cbb226ff9c455669f6cf2d79be72120f2298f6cb0d444fddc0aa3d"},"address":"0042e5d2a662eeaca8a7e828c174f98f35d8925b","name":"parity-export-test","meta":"{\"passwordHint\":\"parity-export-test\",\"timestamp\":1490017814987}"}"#;
|
||||||
tester.accounts.import_wallet(wallet.as_bytes(), "parity-export-test", false).unwrap();
|
tester.accounts.import_wallet(wallet.as_bytes(), &"parity-export-test".into(), false).unwrap();
|
||||||
let accounts = tester.accounts.accounts().unwrap();
|
let accounts = tester.accounts.accounts().unwrap();
|
||||||
assert_eq!(accounts.len(), 1);
|
assert_eq!(accounts.len(), 1);
|
||||||
|
|
||||||
@ -525,7 +525,7 @@ fn should_sign_message() {
|
|||||||
let hash = tester.accounts
|
let hash = tester.accounts
|
||||||
.insert_account(
|
.insert_account(
|
||||||
"0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a".parse().unwrap(),
|
"0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a".parse().unwrap(),
|
||||||
"password1")
|
&"password1".into())
|
||||||
.expect("account should be inserted ok");
|
.expect("account should be inserted ok");
|
||||||
|
|
||||||
assert_eq!(hash, "c171033d5cbff7175f29dfd3a63dda3d6f8f385e".parse().unwrap());
|
assert_eq!(hash, "c171033d5cbff7175f29dfd3a63dda3d6f8f385e".parse().unwrap());
|
||||||
|
@ -178,7 +178,7 @@ fn rpc_parity_set_engine_signer() {
|
|||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
assert_eq!(miner.authoring_params().author, Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
|
assert_eq!(miner.authoring_params().author, Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
|
||||||
assert_eq!(*miner.password.read(), "password".to_string());
|
assert_eq!(*miner.password.read(), "password".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -74,7 +74,7 @@ fn setup() -> PersonalTester {
|
|||||||
#[test]
|
#[test]
|
||||||
fn accounts() {
|
fn accounts() {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
let address = tester.accounts.new_account("").unwrap();
|
let address = tester.accounts.new_account(&"".into()).unwrap();
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "personal_listAccounts", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "personal_listAccounts", "params": [], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":[""#.to_owned() + &format!("0x{:x}", address) + r#""],"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":[""#.to_owned() + &format!("0x{:x}", address) + r#""],"id":1}"#;
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ fn new_account() {
|
|||||||
fn invalid_password_test(method: &str)
|
fn invalid_password_test(method: &str)
|
||||||
{
|
{
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
let address = tester.accounts.new_account("password123").unwrap();
|
let address = tester.accounts.new_account(&"password123".into()).unwrap();
|
||||||
|
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
@ -122,7 +122,7 @@ fn invalid_password_test(method: &str)
|
|||||||
#[test]
|
#[test]
|
||||||
fn sign() {
|
fn sign() {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
let address = tester.accounts.new_account("password123").unwrap();
|
let address = tester.accounts.new_account(&"password123".into()).unwrap();
|
||||||
let data = vec![5u8];
|
let data = vec![5u8];
|
||||||
|
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
@ -148,7 +148,7 @@ fn sign() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn sign_with_invalid_password() {
|
fn sign_with_invalid_password() {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
let address = tester.accounts.new_account("password123").unwrap();
|
let address = tester.accounts.new_account(&"password123".into()).unwrap();
|
||||||
|
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
@ -188,7 +188,7 @@ fn sign_and_send_transaction() {
|
|||||||
|
|
||||||
fn sign_and_send_test(method: &str) {
|
fn sign_and_send_test(method: &str) {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
let address = tester.accounts.new_account("password123").unwrap();
|
let address = tester.accounts.new_account(&"password123".into()).unwrap();
|
||||||
|
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
@ -241,7 +241,7 @@ fn sign_and_send_test(method: &str) {
|
|||||||
#[test]
|
#[test]
|
||||||
fn ec_recover() {
|
fn ec_recover() {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
let address = tester.accounts.new_account("password123").unwrap();
|
let address = tester.accounts.new_account(&"password123".into()).unwrap();
|
||||||
let data = vec![5u8];
|
let data = vec![5u8];
|
||||||
|
|
||||||
let hash = eth_data_hash(data.clone());
|
let hash = eth_data_hash(data.clone());
|
||||||
@ -287,7 +287,7 @@ fn ec_recover_invalid_signature() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_unlock_not_account_temporarily_if_allow_perm_is_disabled() {
|
fn should_unlock_not_account_temporarily_if_allow_perm_is_disabled() {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
let address = tester.accounts.new_account("password123").unwrap();
|
let address = tester.accounts.new_account(&"password123".into()).unwrap();
|
||||||
|
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
@ -308,7 +308,7 @@ fn should_unlock_not_account_temporarily_if_allow_perm_is_disabled() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_unlock_account_permanently() {
|
fn should_unlock_account_permanently() {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
let address = tester.accounts.new_account("password123").unwrap();
|
let address = tester.accounts.new_account(&"password123".into()).unwrap();
|
||||||
|
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
|
@ -57,7 +57,7 @@ fn rpc_secretstore_encrypt_and_decrypt() {
|
|||||||
|
|
||||||
// insert new account
|
// insert new account
|
||||||
let secret = "c1f1cfe279a5c350d13795bce162941967340c8a228e6ba175489afc564a5bef".parse().unwrap();
|
let secret = "c1f1cfe279a5c350d13795bce162941967340c8a228e6ba175489afc564a5bef".parse().unwrap();
|
||||||
deps.accounts.insert_account(secret, "password").unwrap();
|
deps.accounts.insert_account(secret, &"password".into()).unwrap();
|
||||||
|
|
||||||
// execute encryption request
|
// execute encryption request
|
||||||
let encryption_request = r#"{"jsonrpc": "2.0", "method": "secretstore_encrypt", "params":[
|
let encryption_request = r#"{"jsonrpc": "2.0", "method": "secretstore_encrypt", "params":[
|
||||||
@ -87,7 +87,7 @@ fn rpc_secretstore_shadow_decrypt() {
|
|||||||
|
|
||||||
// insert new account
|
// insert new account
|
||||||
let secret = "82758356bf46b42710d3946a8efa612b7bf5e125e4d49f28facf1139db4a46f4".parse().unwrap();
|
let secret = "82758356bf46b42710d3946a8efa612b7bf5e125e4d49f28facf1139db4a46f4".parse().unwrap();
|
||||||
deps.accounts.insert_account(secret, "password").unwrap();
|
deps.accounts.insert_account(secret, &"password".into()).unwrap();
|
||||||
|
|
||||||
// execute decryption request
|
// execute decryption request
|
||||||
let decryption_request = r#"{"jsonrpc": "2.0", "method": "secretstore_shadowDecrypt", "params":[
|
let decryption_request = r#"{"jsonrpc": "2.0", "method": "secretstore_shadowDecrypt", "params":[
|
||||||
@ -131,7 +131,7 @@ fn rpc_secretstore_sign_raw_hash() {
|
|||||||
// insert new account
|
// insert new account
|
||||||
let secret = "82758356bf46b42710d3946a8efa612b7bf5e125e4d49f28facf1139db4a46f4".parse().unwrap();
|
let secret = "82758356bf46b42710d3946a8efa612b7bf5e125e4d49f28facf1139db4a46f4".parse().unwrap();
|
||||||
let key_pair = KeyPair::from_secret(secret).unwrap();
|
let key_pair = KeyPair::from_secret(secret).unwrap();
|
||||||
deps.accounts.insert_account(key_pair.secret().clone(), "password").unwrap();
|
deps.accounts.insert_account(key_pair.secret().clone(), &"password".into()).unwrap();
|
||||||
|
|
||||||
// execute signing request
|
// execute signing request
|
||||||
let signing_request = r#"{"jsonrpc": "2.0", "method": "secretstore_signRawHash", "params":[
|
let signing_request = r#"{"jsonrpc": "2.0", "method": "secretstore_signRawHash", "params":[
|
||||||
@ -154,7 +154,7 @@ fn rpc_secretstore_generate_document_key() {
|
|||||||
// insert new account
|
// insert new account
|
||||||
let secret = "82758356bf46b42710d3946a8efa612b7bf5e125e4d49f28facf1139db4a46f4".parse().unwrap();
|
let secret = "82758356bf46b42710d3946a8efa612b7bf5e125e4d49f28facf1139db4a46f4".parse().unwrap();
|
||||||
let key_pair = KeyPair::from_secret(secret).unwrap();
|
let key_pair = KeyPair::from_secret(secret).unwrap();
|
||||||
deps.accounts.insert_account(key_pair.secret().clone(), "password").unwrap();
|
deps.accounts.insert_account(key_pair.secret().clone(), &"password".into()).unwrap();
|
||||||
|
|
||||||
// execute generation request
|
// execute generation request
|
||||||
let generation_request = r#"{"jsonrpc": "2.0", "method": "secretstore_generateDocumentKey", "params":[
|
let generation_request = r#"{"jsonrpc": "2.0", "method": "secretstore_generateDocumentKey", "params":[
|
||||||
|
@ -178,7 +178,7 @@ fn should_not_remove_sign_if_password_is_invalid() {
|
|||||||
fn should_confirm_transaction_and_dispatch() {
|
fn should_confirm_transaction_and_dispatch() {
|
||||||
//// given
|
//// given
|
||||||
let tester = signer_tester();
|
let tester = signer_tester();
|
||||||
let address = tester.accounts.new_account("test").unwrap();
|
let address = tester.accounts.new_account(&"test".into()).unwrap();
|
||||||
let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap();
|
let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap();
|
||||||
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::SendTransaction(FilledTransactionRequest {
|
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::SendTransaction(FilledTransactionRequest {
|
||||||
from: address,
|
from: address,
|
||||||
@ -247,7 +247,7 @@ fn should_alter_the_sender_and_nonce() {
|
|||||||
data: vec![]
|
data: vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
let address = tester.accounts.new_account("test").unwrap();
|
let address = tester.accounts.new_account(&"test".into()).unwrap();
|
||||||
let signature = tester.accounts.sign(address, Some("test".into()), t.hash(None)).unwrap();
|
let signature = tester.accounts.sign(address, Some("test".into()), t.hash(None)).unwrap();
|
||||||
let t = t.with_signature(signature, None);
|
let t = t.with_signature(signature, None);
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ fn should_alter_the_sender_and_nonce() {
|
|||||||
fn should_confirm_transaction_with_token() {
|
fn should_confirm_transaction_with_token() {
|
||||||
// given
|
// given
|
||||||
let tester = signer_tester();
|
let tester = signer_tester();
|
||||||
let address = tester.accounts.new_account("test").unwrap();
|
let address = tester.accounts.new_account(&"test".into()).unwrap();
|
||||||
let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap();
|
let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap();
|
||||||
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::SendTransaction(FilledTransactionRequest {
|
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::SendTransaction(FilledTransactionRequest {
|
||||||
from: address,
|
from: address,
|
||||||
@ -305,7 +305,7 @@ fn should_confirm_transaction_with_token() {
|
|||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc":"2.0",
|
"jsonrpc":"2.0",
|
||||||
"method":"signer_confirmRequestWithToken",
|
"method":"signer_confirmRequestWithToken",
|
||||||
"params":["0x1", {"gasPrice":"0x1000"}, ""#.to_owned() + &token + r#""],
|
"params":["0x1", {"gasPrice":"0x1000"}, ""#.to_owned() + token.as_str() + r#""],
|
||||||
"id":1
|
"id":1
|
||||||
}"#;
|
}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":{"result":""#.to_owned() +
|
let response = r#"{"jsonrpc":"2.0","result":{"result":""#.to_owned() +
|
||||||
@ -323,7 +323,7 @@ fn should_confirm_transaction_with_token() {
|
|||||||
fn should_confirm_transaction_with_rlp() {
|
fn should_confirm_transaction_with_rlp() {
|
||||||
// given
|
// given
|
||||||
let tester = signer_tester();
|
let tester = signer_tester();
|
||||||
let address = tester.accounts.new_account("test").unwrap();
|
let address = tester.accounts.new_account(&"test".into()).unwrap();
|
||||||
let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap();
|
let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap();
|
||||||
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::SendTransaction(FilledTransactionRequest {
|
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::SendTransaction(FilledTransactionRequest {
|
||||||
from: address,
|
from: address,
|
||||||
@ -370,7 +370,7 @@ fn should_confirm_transaction_with_rlp() {
|
|||||||
fn should_return_error_when_sender_does_not_match() {
|
fn should_return_error_when_sender_does_not_match() {
|
||||||
// given
|
// given
|
||||||
let tester = signer_tester();
|
let tester = signer_tester();
|
||||||
let address = tester.accounts.new_account("test").unwrap();
|
let address = tester.accounts.new_account(&"test".into()).unwrap();
|
||||||
let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap();
|
let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap();
|
||||||
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::SendTransaction(FilledTransactionRequest {
|
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::SendTransaction(FilledTransactionRequest {
|
||||||
from: Address::default(),
|
from: Address::default(),
|
||||||
@ -417,7 +417,7 @@ fn should_return_error_when_sender_does_not_match() {
|
|||||||
fn should_confirm_sign_transaction_with_rlp() {
|
fn should_confirm_sign_transaction_with_rlp() {
|
||||||
// given
|
// given
|
||||||
let tester = signer_tester();
|
let tester = signer_tester();
|
||||||
let address = tester.accounts.new_account("test").unwrap();
|
let address = tester.accounts.new_account(&"test".into()).unwrap();
|
||||||
let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap();
|
let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap();
|
||||||
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::SignTransaction(FilledTransactionRequest {
|
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::SignTransaction(FilledTransactionRequest {
|
||||||
from: address,
|
from: address,
|
||||||
@ -482,7 +482,7 @@ fn should_confirm_sign_transaction_with_rlp() {
|
|||||||
fn should_confirm_data_sign_with_signature() {
|
fn should_confirm_data_sign_with_signature() {
|
||||||
// given
|
// given
|
||||||
let tester = signer_tester();
|
let tester = signer_tester();
|
||||||
let address = tester.accounts.new_account("test").unwrap();
|
let address = tester.accounts.new_account(&"test".into()).unwrap();
|
||||||
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::EthSignMessage(
|
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::EthSignMessage(
|
||||||
address,
|
address,
|
||||||
vec![1, 2, 3, 4].into(),
|
vec![1, 2, 3, 4].into(),
|
||||||
@ -512,7 +512,7 @@ fn should_confirm_data_sign_with_signature() {
|
|||||||
fn should_confirm_decrypt_with_phrase() {
|
fn should_confirm_decrypt_with_phrase() {
|
||||||
// given
|
// given
|
||||||
let tester = signer_tester();
|
let tester = signer_tester();
|
||||||
let address = tester.accounts.new_account("test").unwrap();
|
let address = tester.accounts.new_account(&"test".into()).unwrap();
|
||||||
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::Decrypt(
|
let _confirmation_future = tester.signer.add_request(ConfirmationPayload::Decrypt(
|
||||||
address,
|
address,
|
||||||
vec![1, 2, 3, 4].into(),
|
vec![1, 2, 3, 4].into(),
|
||||||
|
@ -212,7 +212,7 @@ fn should_sign_if_account_is_unlocked() {
|
|||||||
// given
|
// given
|
||||||
let tester = eth_signing();
|
let tester = eth_signing();
|
||||||
let data = vec![5u8];
|
let data = vec![5u8];
|
||||||
let acc = tester.accounts.insert_account(Secret::from([69u8; 32]), "test").unwrap();
|
let acc = tester.accounts.insert_account(Secret::from([69u8; 32]), &"test".into()).unwrap();
|
||||||
tester.accounts.unlock_account_permanently(acc, "test".into()).unwrap();
|
tester.accounts.unlock_account_permanently(acc, "test".into()).unwrap();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -275,7 +275,7 @@ fn should_add_transaction_to_queue() {
|
|||||||
fn should_add_sign_transaction_to_the_queue() {
|
fn should_add_sign_transaction_to_the_queue() {
|
||||||
// given
|
// given
|
||||||
let tester = eth_signing();
|
let tester = eth_signing();
|
||||||
let address = tester.accounts.new_account("test").unwrap();
|
let address = tester.accounts.new_account(&"test".into()).unwrap();
|
||||||
|
|
||||||
assert_eq!(tester.signer.requests().len(), 0);
|
assert_eq!(tester.signer.requests().len(), 0);
|
||||||
|
|
||||||
@ -354,7 +354,7 @@ fn should_add_sign_transaction_to_the_queue() {
|
|||||||
fn should_dispatch_transaction_if_account_is_unlock() {
|
fn should_dispatch_transaction_if_account_is_unlock() {
|
||||||
// given
|
// given
|
||||||
let tester = eth_signing();
|
let tester = eth_signing();
|
||||||
let acc = tester.accounts.new_account("test").unwrap();
|
let acc = tester.accounts.new_account(&"test".into()).unwrap();
|
||||||
tester.accounts.unlock_account_permanently(acc, "test".into()).unwrap();
|
tester.accounts.unlock_account_permanently(acc, "test".into()).unwrap();
|
||||||
|
|
||||||
let t = Transaction {
|
let t = Transaction {
|
||||||
@ -393,7 +393,7 @@ fn should_decrypt_message_if_account_is_unlocked() {
|
|||||||
let mut tester = eth_signing();
|
let mut tester = eth_signing();
|
||||||
let parity = parity::Dependencies::new();
|
let parity = parity::Dependencies::new();
|
||||||
tester.io.extend_with(parity.client(None).to_delegate());
|
tester.io.extend_with(parity.client(None).to_delegate());
|
||||||
let (address, public) = tester.accounts.new_account_and_public("test").unwrap();
|
let (address, public) = tester.accounts.new_account_and_public(&"test".into()).unwrap();
|
||||||
tester.accounts.unlock_account_permanently(address, "test".into()).unwrap();
|
tester.accounts.unlock_account_permanently(address, "test".into()).unwrap();
|
||||||
|
|
||||||
// First encrypt message
|
// First encrypt message
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use jsonrpc_core::Result;
|
use jsonrpc_core::Result;
|
||||||
|
use ethkey::Password;
|
||||||
use ethstore::KeyFile;
|
use ethstore::KeyFile;
|
||||||
use v1::types::{H160, H256, H520, DappId, DeriveHash, DeriveHierarchical, ExtAccountInfo};
|
use v1::types::{H160, H256, H520, DappId, DeriveHash, DeriveHierarchical, ExtAccountInfo};
|
||||||
|
|
||||||
@ -31,32 +32,32 @@ build_rpc_trait! {
|
|||||||
/// Creates new account from the given phrase using standard brainwallet mechanism.
|
/// Creates new account from the given phrase using standard brainwallet mechanism.
|
||||||
/// Second parameter is password for the new account.
|
/// Second parameter is password for the new account.
|
||||||
#[rpc(name = "parity_newAccountFromPhrase")]
|
#[rpc(name = "parity_newAccountFromPhrase")]
|
||||||
fn new_account_from_phrase(&self, String, String) -> Result<H160>;
|
fn new_account_from_phrase(&self, String, Password) -> Result<H160>;
|
||||||
|
|
||||||
/// Creates new account from the given JSON wallet.
|
/// Creates new account from the given JSON wallet.
|
||||||
/// Second parameter is password for the wallet and the new account.
|
/// Second parameter is password for the wallet and the new account.
|
||||||
#[rpc(name = "parity_newAccountFromWallet")]
|
#[rpc(name = "parity_newAccountFromWallet")]
|
||||||
fn new_account_from_wallet(&self, String, String) -> Result<H160>;
|
fn new_account_from_wallet(&self, String, Password) -> Result<H160>;
|
||||||
|
|
||||||
/// Creates new account from the given raw secret.
|
/// Creates new account from the given raw secret.
|
||||||
/// Second parameter is password for the new account.
|
/// Second parameter is password for the new account.
|
||||||
#[rpc(name = "parity_newAccountFromSecret")]
|
#[rpc(name = "parity_newAccountFromSecret")]
|
||||||
fn new_account_from_secret(&self, H256, String) -> Result<H160>;
|
fn new_account_from_secret(&self, H256, Password) -> Result<H160>;
|
||||||
|
|
||||||
/// Returns true if given `password` would unlock given `account`.
|
/// Returns true if given `password` would unlock given `account`.
|
||||||
/// Arguments: `account`, `password`.
|
/// Arguments: `account`, `password`.
|
||||||
#[rpc(name = "parity_testPassword")]
|
#[rpc(name = "parity_testPassword")]
|
||||||
fn test_password(&self, H160, String) -> Result<bool>;
|
fn test_password(&self, H160, Password) -> Result<bool>;
|
||||||
|
|
||||||
/// Changes an account's password.
|
/// Changes an account's password.
|
||||||
/// Arguments: `account`, `password`, `new_password`.
|
/// Arguments: `account`, `password`, `new_password`.
|
||||||
#[rpc(name = "parity_changePassword")]
|
#[rpc(name = "parity_changePassword")]
|
||||||
fn change_password(&self, H160, String, String) -> Result<bool>;
|
fn change_password(&self, H160, Password, Password) -> Result<bool>;
|
||||||
|
|
||||||
/// Permanently deletes an account.
|
/// Permanently deletes an account.
|
||||||
/// Arguments: `account`, `password`.
|
/// Arguments: `account`, `password`.
|
||||||
#[rpc(name = "parity_killAccount")]
|
#[rpc(name = "parity_killAccount")]
|
||||||
fn kill_account(&self, H160, String) -> Result<bool>;
|
fn kill_account(&self, H160, Password) -> Result<bool>;
|
||||||
|
|
||||||
/// Permanently deletes an address from the addressbook
|
/// Permanently deletes an address from the addressbook
|
||||||
/// Arguments: `address`
|
/// Arguments: `address`
|
||||||
@ -132,11 +133,11 @@ build_rpc_trait! {
|
|||||||
|
|
||||||
/// Create new vault.
|
/// Create new vault.
|
||||||
#[rpc(name = "parity_newVault")]
|
#[rpc(name = "parity_newVault")]
|
||||||
fn create_vault(&self, String, String) -> Result<bool>;
|
fn create_vault(&self, String, Password) -> Result<bool>;
|
||||||
|
|
||||||
/// Open existing vault.
|
/// Open existing vault.
|
||||||
#[rpc(name = "parity_openVault")]
|
#[rpc(name = "parity_openVault")]
|
||||||
fn open_vault(&self, String, String) -> Result<bool>;
|
fn open_vault(&self, String, Password) -> Result<bool>;
|
||||||
|
|
||||||
/// Close previously opened vault.
|
/// Close previously opened vault.
|
||||||
#[rpc(name = "parity_closeVault")]
|
#[rpc(name = "parity_closeVault")]
|
||||||
@ -152,7 +153,7 @@ build_rpc_trait! {
|
|||||||
|
|
||||||
/// Change vault password.
|
/// Change vault password.
|
||||||
#[rpc(name = "parity_changeVaultPassword")]
|
#[rpc(name = "parity_changeVaultPassword")]
|
||||||
fn change_vault_password(&self, String, String) -> Result<bool>;
|
fn change_vault_password(&self, String, Password) -> Result<bool>;
|
||||||
|
|
||||||
/// Change vault of the given address.
|
/// Change vault of the given address.
|
||||||
#[rpc(name = "parity_changeVault")]
|
#[rpc(name = "parity_changeVault")]
|
||||||
@ -169,21 +170,21 @@ build_rpc_trait! {
|
|||||||
/// Derive new address from given account address using specific hash.
|
/// Derive new address from given account address using specific hash.
|
||||||
/// Resulting address can be either saved as a new account (with the same password).
|
/// Resulting address can be either saved as a new account (with the same password).
|
||||||
#[rpc(name = "parity_deriveAddressHash")]
|
#[rpc(name = "parity_deriveAddressHash")]
|
||||||
fn derive_key_hash(&self, H160, String, DeriveHash, bool) -> Result<H160>;
|
fn derive_key_hash(&self, H160, Password, DeriveHash, bool) -> Result<H160>;
|
||||||
|
|
||||||
/// Derive new address from given account address using
|
/// Derive new address from given account address using
|
||||||
/// hierarchical derivation (sequence of 32-bit integer indices).
|
/// hierarchical derivation (sequence of 32-bit integer indices).
|
||||||
/// Resulting address can be either saved as a new account (with the same password).
|
/// Resulting address can be either saved as a new account (with the same password).
|
||||||
#[rpc(name = "parity_deriveAddressIndex")]
|
#[rpc(name = "parity_deriveAddressIndex")]
|
||||||
fn derive_key_index(&self, H160, String, DeriveHierarchical, bool) -> Result<H160>;
|
fn derive_key_index(&self, H160, Password, DeriveHierarchical, bool) -> Result<H160>;
|
||||||
|
|
||||||
/// Exports an account with given address if provided password matches.
|
/// Exports an account with given address if provided password matches.
|
||||||
#[rpc(name = "parity_exportAccount")]
|
#[rpc(name = "parity_exportAccount")]
|
||||||
fn export_account(&self, H160, String) -> Result<KeyFile>;
|
fn export_account(&self, H160, Password) -> Result<KeyFile>;
|
||||||
|
|
||||||
/// Sign raw hash with the key corresponding to address and password.
|
/// Sign raw hash with the key corresponding to address and password.
|
||||||
#[rpc(name = "parity_signMessage")]
|
#[rpc(name = "parity_signMessage")]
|
||||||
fn sign_message(&self, H160, String, H256) -> Result<H520>;
|
fn sign_message(&self, H160, Password, H256) -> Result<H520>;
|
||||||
|
|
||||||
/// Send a PinMatrixAck to a hardware wallet, unlocking it
|
/// Send a PinMatrixAck to a hardware wallet, unlocking it
|
||||||
#[rpc(name = "parity_hardwarePinMatrixAck")]
|
#[rpc(name = "parity_hardwarePinMatrixAck")]
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use jsonrpc_core::Result;
|
use jsonrpc_core::Result;
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey};
|
use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey};
|
||||||
|
|
||||||
@ -27,22 +28,22 @@ build_rpc_trait! {
|
|||||||
/// Generate document key to store in secret store.
|
/// Generate document key to store in secret store.
|
||||||
/// Arguments: `account`, `password`, `server_key_public`.
|
/// Arguments: `account`, `password`, `server_key_public`.
|
||||||
#[rpc(name = "secretstore_generateDocumentKey")]
|
#[rpc(name = "secretstore_generateDocumentKey")]
|
||||||
fn generate_document_key(&self, H160, String, H512) -> Result<EncryptedDocumentKey>;
|
fn generate_document_key(&self, H160, Password, H512) -> Result<EncryptedDocumentKey>;
|
||||||
|
|
||||||
/// Encrypt data with key, received from secret store.
|
/// Encrypt data with key, received from secret store.
|
||||||
/// Arguments: `account`, `password`, `key`, `data`.
|
/// Arguments: `account`, `password`, `key`, `data`.
|
||||||
#[rpc(name = "secretstore_encrypt")]
|
#[rpc(name = "secretstore_encrypt")]
|
||||||
fn encrypt(&self, H160, String, Bytes, Bytes) -> Result<Bytes>;
|
fn encrypt(&self, H160, Password, Bytes, Bytes) -> Result<Bytes>;
|
||||||
|
|
||||||
/// Decrypt data with key, received from secret store.
|
/// Decrypt data with key, received from secret store.
|
||||||
/// Arguments: `account`, `password`, `key`, `data`.
|
/// Arguments: `account`, `password`, `key`, `data`.
|
||||||
#[rpc(name = "secretstore_decrypt")]
|
#[rpc(name = "secretstore_decrypt")]
|
||||||
fn decrypt(&self, H160, String, Bytes, Bytes) -> Result<Bytes>;
|
fn decrypt(&self, H160, Password, Bytes, Bytes) -> Result<Bytes>;
|
||||||
|
|
||||||
/// Decrypt data with shadow key, received from secret store.
|
/// Decrypt data with shadow key, received from secret store.
|
||||||
/// Arguments: `account`, `password`, `decrypted_secret`, `common_point`, `decrypt_shadows`, `data`.
|
/// Arguments: `account`, `password`, `decrypted_secret`, `common_point`, `decrypt_shadows`, `data`.
|
||||||
#[rpc(name = "secretstore_shadowDecrypt")]
|
#[rpc(name = "secretstore_shadowDecrypt")]
|
||||||
fn shadow_decrypt(&self, H160, String, H512, H512, Vec<Bytes>, Bytes) -> Result<Bytes>;
|
fn shadow_decrypt(&self, H160, Password, H512, H512, Vec<Bytes>, Bytes) -> Result<Bytes>;
|
||||||
|
|
||||||
/// Calculates the hash (keccak256) of servers set for using in ServersSetChange session.
|
/// Calculates the hash (keccak256) of servers set for using in ServersSetChange session.
|
||||||
/// Returned hash must be signed later by using `secretstore_signRawHash` method.
|
/// Returned hash must be signed later by using `secretstore_signRawHash` method.
|
||||||
@ -54,6 +55,6 @@ build_rpc_trait! {
|
|||||||
/// Passed hash is treated as an input to the `sign` function (no prefixes added, no hash function is applied).
|
/// Passed hash is treated as an input to the `sign` function (no prefixes added, no hash function is applied).
|
||||||
/// Arguments: `account`, `password`, `raw_hash`.
|
/// Arguments: `account`, `password`, `raw_hash`.
|
||||||
#[rpc(name = "secretstore_signRawHash")]
|
#[rpc(name = "secretstore_signRawHash")]
|
||||||
fn sign_raw_hash(&self, H160, String, H256) -> Result<Bytes>;
|
fn sign_raw_hash(&self, H160, Password, H256) -> Result<Bytes>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ use bytes::ToPretty;
|
|||||||
|
|
||||||
use v1::types::{U256, TransactionRequest, RichRawTransaction, H160, H256, H520, Bytes, TransactionCondition, Origin};
|
use v1::types::{U256, TransactionRequest, RichRawTransaction, H160, H256, H520, Bytes, TransactionCondition, Origin};
|
||||||
use v1::helpers;
|
use v1::helpers;
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
/// Confirmation waiting in a queue
|
/// Confirmation waiting in a queue
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||||
@ -149,12 +150,12 @@ impl Serialize for ConfirmationResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Confirmation response with additional token for further requests
|
/// Confirmation response with additional token for further requests
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
#[derive(Clone, PartialEq, Serialize)]
|
||||||
pub struct ConfirmationResponseWithToken {
|
pub struct ConfirmationResponseWithToken {
|
||||||
/// Actual response
|
/// Actual response
|
||||||
pub result: ConfirmationResponse,
|
pub result: ConfirmationResponse,
|
||||||
/// New token
|
/// New token
|
||||||
pub token: String,
|
pub token: Password,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Confirmation payload, i.e. the thing to be confirmed
|
/// Confirmation payload, i.e. the thing to be confirmed
|
||||||
|
@ -20,6 +20,7 @@ use ethkey::{KeyPair, Public, Signature, Error as EthKeyError, sign, public_to_a
|
|||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethereum_types::{H256, Address};
|
use ethereum_types::{H256, Address};
|
||||||
use traits::NodeKeyPair;
|
use traits::NodeKeyPair;
|
||||||
|
use ethkey::Password;
|
||||||
|
|
||||||
pub struct PlainNodeKeyPair {
|
pub struct PlainNodeKeyPair {
|
||||||
key_pair: KeyPair,
|
key_pair: KeyPair,
|
||||||
@ -29,7 +30,7 @@ pub struct KeyStoreNodeKeyPair {
|
|||||||
account_provider: Arc<AccountProvider>,
|
account_provider: Arc<AccountProvider>,
|
||||||
address: Address,
|
address: Address,
|
||||||
public: Public,
|
public: Public,
|
||||||
password: String,
|
password: Password,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlainNodeKeyPair {
|
impl PlainNodeKeyPair {
|
||||||
@ -61,7 +62,7 @@ impl NodeKeyPair for PlainNodeKeyPair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl KeyStoreNodeKeyPair {
|
impl KeyStoreNodeKeyPair {
|
||||||
pub fn new(account_provider: Arc<AccountProvider>, address: Address, password: String) -> Result<Self, EthKeyError> {
|
pub fn new(account_provider: Arc<AccountProvider>, address: Address, password: Password) -> Result<Self, EthKeyError> {
|
||||||
let public = account_provider.account_public(address.clone(), &password).map_err(|e| EthKeyError::Custom(format!("{}", e)))?;
|
let public = account_provider.account_public(address.clone(), &password).map_err(|e| EthKeyError::Custom(format!("{}", e)))?;
|
||||||
Ok(KeyStoreNodeKeyPair {
|
Ok(KeyStoreNodeKeyPair {
|
||||||
account_provider: account_provider,
|
account_provider: account_provider,
|
||||||
|
@ -31,11 +31,9 @@ impl<T: AsMut<[u8]>> From<T> for Memzero<T> {
|
|||||||
|
|
||||||
impl<T: AsMut<[u8]>> Drop for Memzero<T> {
|
impl<T: AsMut<[u8]>> Drop for Memzero<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let n = self.mem.as_mut().len();
|
unsafe {
|
||||||
let p = self.mem.as_mut().as_mut_ptr();
|
for byte_ref in self.mem.as_mut() {
|
||||||
for i in 0..n {
|
ptr::write_volatile(byte_ref, 0)
|
||||||
unsafe {
|
|
||||||
ptr::write_volatile(p.offset(i as isize), 0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user