From 4f8e61dce99c8ba8c850764a617724d24e7932df Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 11 Apr 2017 16:24:56 +0800 Subject: [PATCH] easy to use conversion from and to string for ethstore::Crypto (#5437) * easy to use conversion from and to string for ethstore::Crypto * ethstore uses tempdir instead of devtools * ethstore does not depend on ethcore-util --- Cargo.lock | 4 ++-- ethcrypto/src/lib.rs | 4 ++-- ethstore/Cargo.toml | 4 ++-- ethstore/src/account/crypto.rs | 27 +++++++++++++++++++------ ethstore/src/dir/disk.rs | 18 +++++++++-------- ethstore/src/dir/vault.rs | 36 ++++++++++++++++++---------------- ethstore/src/ethstore.rs | 11 ++++++----- ethstore/src/json/crypto.rs | 17 +++++++++++++++- ethstore/src/lib.rs | 6 +++--- ethstore/src/secret_store.rs | 2 +- 10 files changed, 82 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e9edecc88..830e1e75a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -784,8 +784,7 @@ name = "ethstore" version = "0.1.0" dependencies = [ "docopt 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-devtools 1.7.0", - "ethcore-util 1.7.0", + "ethcore-bigint 0.1.2", "ethcrypto 0.1.0", "ethkey 0.2.0", "itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -800,6 +799,7 @@ dependencies = [ "serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/ethcrypto/src/lib.rs b/ethcrypto/src/lib.rs index 9c1352087..ea0ea9754 100644 --- a/ethcrypto/src/lib.rs +++ b/ethcrypto/src/lib.rs @@ -94,11 +94,11 @@ pub trait Keccak256 { fn keccak256(&self) -> T where T: Sized; } -impl Keccak256<[u8; 32]> for [u8] { +impl Keccak256<[u8; 32]> for T where T: AsRef<[u8]> { fn keccak256(&self) -> [u8; 32] { let mut keccak = Keccak::new_keccak256(); let mut result = [0u8; 32]; - keccak.update(self); + keccak.update(self.as_ref()); keccak.finalize(&mut result); result } diff --git a/ethstore/Cargo.toml b/ethstore/Cargo.toml index a6a0d1752..cd2a11db1 100755 --- a/ethstore/Cargo.toml +++ b/ethstore/Cargo.toml @@ -19,10 +19,10 @@ time = "0.1.34" itertools = "0.5" parking_lot = "0.4" ethcrypto = { path = "../ethcrypto" } -ethcore-util = { path = "../util" } +ethcore-bigint = { path = "../util/bigint" } smallvec = "0.3.1" -ethcore-devtools = { path = "../devtools" } parity-wordlist = "1.0" +tempdir = "0.3" [features] cli = ["docopt"] diff --git a/ethstore/src/account/crypto.rs b/ethstore/src/account/crypto.rs index adcae997d..8c4825a22 100755 --- a/ethstore/src/account/crypto.rs +++ b/ethstore/src/account/crypto.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::iter::repeat; +use std::str; use ethkey::Secret; use {json, Error, crypto}; use crypto::Keccak256; @@ -46,17 +47,31 @@ impl From for Crypto { } } -impl Into for Crypto { - fn into(self) -> json::Crypto { +impl From for json::Crypto { + fn from(c: Crypto) -> Self { json::Crypto { - cipher: self.cipher.into(), - ciphertext: self.ciphertext.into(), - kdf: self.kdf.into(), - mac: self.mac.into(), + cipher: c.cipher.into(), + ciphertext: c.ciphertext.into(), + kdf: c.kdf.into(), + mac: c.mac.into(), } } } +impl str::FromStr for Crypto { + type Err = ::Err; + + fn from_str(s: &str) -> Result { + s.parse::().map(Into::into) + } +} + +impl From for String { + fn from(c: Crypto) -> Self { + json::Crypto::from(c).into() + } +} + impl Crypto { pub fn with_secret(secret: &Secret, password: &str, iterations: u32) -> Self { Crypto::with_plain(&*secret, password, iterations) diff --git a/ethstore/src/dir/disk.rs b/ethstore/src/dir/disk.rs index afca0955d..3f56ebe40 100755 --- a/ethstore/src/dir/disk.rs +++ b/ethstore/src/dir/disk.rs @@ -225,8 +225,8 @@ impl KeyDirectory for DiskDirectory where T: KeyFileManager { Some(self) } - fn unique_repr(&self) -> Result { - self.files_hash() + fn unique_repr(&self) -> Result { + self.files_hash() } } @@ -280,12 +280,14 @@ impl KeyFileManager for DiskKeyFileManager { #[cfg(test)] mod test { + extern crate tempdir; + use std::{env, fs}; use super::RootDiskDirectory; use dir::{KeyDirectory, VaultKey}; use account::SafeAccount; use ethkey::{Random, Generator}; - use devtools::RandomTempPath; + use self::tempdir::TempDir; #[test] fn should_create_new_account() { @@ -344,7 +346,7 @@ mod test { #[test] fn should_list_vaults() { // given - let temp_path = RandomTempPath::new(); + let temp_path = TempDir::new("").unwrap(); let directory = RootDiskDirectory::create(&temp_path).unwrap(); let vault_provider = directory.as_vault_provider().unwrap(); vault_provider.create("vault1", VaultKey::new("password1", 1)).unwrap(); @@ -359,11 +361,11 @@ mod test { #[test] fn hash_of_files() { - let temp_path = RandomTempPath::new(); + let temp_path = TempDir::new("").unwrap(); let directory = RootDiskDirectory::create(&temp_path).unwrap(); - let hash = directory.files_hash().expect("Files hash should be calculated ok"); - assert_eq!( + let hash = directory.files_hash().expect("Files hash should be calculated ok"); + assert_eq!( hash, 15130871412783076140 ); @@ -373,7 +375,7 @@ mod test { let account = SafeAccount::create(&keypair, [0u8; 16], password, 1024, "Test".to_owned(), "{}".to_owned()); directory.insert(account).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"); assert!(new_hash != hash, "hash of the file list should change once directory content changed"); } diff --git a/ethstore/src/dir/vault.rs b/ethstore/src/dir/vault.rs index f321e3fbb..31c99fcc4 100755 --- a/ethstore/src/dir/vault.rs +++ b/ethstore/src/dir/vault.rs @@ -18,7 +18,7 @@ use std::{fs, io}; use std::path::{PathBuf, Path}; use parking_lot::Mutex; use {json, SafeAccount, Error}; -use util::sha3::Hashable; +use crypto::Keccak256; use super::super::account::Crypto; use super::{KeyDirectory, VaultKeyDirectory, VaultKey, SetKeyError}; use super::disk::{DiskDirectory, KeyFileManager}; @@ -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 fn create_vault_file

(vault_dir_path: P, key: &VaultKey, meta: &str) -> Result<(), Error> where P: AsRef { - let password_hash = key.password.sha3(); + let password_hash = key.password.keccak256(); let crypto = Crypto::with_plain(&password_hash, &key.password, key.iterations); let mut vault_file_path: PathBuf = vault_dir_path.as_ref().into(); @@ -268,8 +268,8 @@ fn read_vault_file

(vault_dir_path: P, key: Option<&VaultKey>) -> Result(vault_dir_path: P, key: Option<&VaultKey>) -> Result KeyPair { Random.generate().unwrap() @@ -642,13 +643,13 @@ mod tests { struct RootDiskDirectoryGuard { pub key_dir: Option>, - _path: RandomTempPath, + _path: TempDir, } impl RootDiskDirectoryGuard { pub fn new() -> Self { - let temp_path = RandomTempPath::new(); - let disk_dir = Box::new(RootDiskDirectory::create(temp_path.as_path()).unwrap()); + let temp_path = TempDir::new("").unwrap(); + let disk_dir = Box::new(RootDiskDirectory::create(temp_path.path()).unwrap()); RootDiskDirectoryGuard { key_dir: Some(disk_dir), diff --git a/ethstore/src/json/crypto.rs b/ethstore/src/json/crypto.rs index 63d73845f..ee1f08502 100644 --- a/ethstore/src/json/crypto.rs +++ b/ethstore/src/json/crypto.rs @@ -14,10 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::fmt; +use std::{fmt, str}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::ser::SerializeStruct; use serde::de::{Visitor, MapVisitor, Error}; +use serde_json; use super::{Cipher, CipherSer, CipherSerParams, Kdf, KdfSer, KdfSerParams, H256, Bytes}; pub type CipherText = Bytes; @@ -30,6 +31,20 @@ pub struct Crypto { pub mac: H256, } +impl str::FromStr for Crypto { + type Err = serde_json::error::Error; + + fn from_str(s: &str) -> Result { + serde_json::from_str(s) + } +} + +impl From for String { + fn from(c: Crypto) -> Self { + serde_json::to_string(&c).expect("serialization cannot fail, cause all crypto keys are strings") + } +} + enum CryptoField { Cipher, CipherParams, diff --git a/ethstore/src/lib.rs b/ethstore/src/lib.rs index 3661cf8f2..145a58023 100755 --- a/ethstore/src/lib.rs +++ b/ethstore/src/lib.rs @@ -29,9 +29,9 @@ extern crate serde_json; extern crate smallvec; extern crate time; extern crate tiny_keccak; +extern crate tempdir; -extern crate ethcore_devtools as devtools; -extern crate ethcore_util as util; +extern crate ethcore_bigint as bigint; extern crate ethcrypto as crypto; extern crate ethkey as _ethkey; extern crate parity_wordlist; @@ -54,7 +54,7 @@ mod presale; mod random; mod secret_store; -pub use self::account::SafeAccount; +pub use self::account::{SafeAccount, Crypto}; pub use self::error::Error; pub use self::ethstore::{EthStore, EthMultiStore}; pub use self::import::{import_accounts, read_geth_accounts}; diff --git a/ethstore/src/secret_store.rs b/ethstore/src/secret_store.rs index fd7eea50d..b292f0ef4 100755 --- a/ethstore/src/secret_store.rs +++ b/ethstore/src/secret_store.rs @@ -19,7 +19,7 @@ use std::path::PathBuf; use ethkey::{Address, Message, Signature, Secret, Public}; use Error; use json::{Uuid, OpaqueKeyFile}; -use util::H256; +use bigint::hash::H256; /// Key directory reference #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]