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
This commit is contained in:
parent
d3b2bcdd79
commit
4f8e61dce9
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -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)",
|
||||
]
|
||||
|
@ -94,11 +94,11 @@ pub trait Keccak256<T> {
|
||||
fn keccak256(&self) -> T where T: Sized;
|
||||
}
|
||||
|
||||
impl Keccak256<[u8; 32]> for [u8] {
|
||||
impl<T> 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
|
||||
}
|
||||
|
@ -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"]
|
||||
|
@ -15,6 +15,7 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::iter::repeat;
|
||||
use std::str;
|
||||
use ethkey::Secret;
|
||||
use {json, Error, crypto};
|
||||
use crypto::Keccak256;
|
||||
@ -46,17 +47,31 @@ impl From<json::Crypto> for Crypto {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<json::Crypto> for Crypto {
|
||||
fn into(self) -> json::Crypto {
|
||||
impl From<Crypto> 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 = <json::Crypto as str::FromStr>::Err;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
s.parse::<json::Crypto>().map(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Crypto> 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)
|
||||
|
@ -225,8 +225,8 @@ impl<T> KeyDirectory for DiskDirectory<T> where T: KeyFileManager {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn unique_repr(&self) -> Result<u64, Error> {
|
||||
self.files_hash()
|
||||
fn unique_repr(&self) -> Result<u64, Error> {
|
||||
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");
|
||||
}
|
||||
|
@ -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<P>(vault_dir_path: P, key: &VaultKey, meta: &str) -> Result<(), Error> where P: AsRef<Path> {
|
||||
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<P>(vault_dir_path: P, key: Option<&VaultKey>) -> Result<Strin
|
||||
|
||||
if let Some(key) = key {
|
||||
let password_bytes = vault_file_crypto.decrypt(&key.password)?;
|
||||
let password_hash = key.password.sha3();
|
||||
if &*password_hash != password_bytes.as_slice() {
|
||||
let password_hash = key.password.keccak256();
|
||||
if password_hash != password_bytes.as_slice() {
|
||||
return Err(Error::InvalidPassword);
|
||||
}
|
||||
}
|
||||
@ -279,12 +279,14 @@ fn read_vault_file<P>(vault_dir_path: P, key: Option<&VaultKey>) -> Result<Strin
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
extern crate tempdir;
|
||||
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use dir::VaultKey;
|
||||
use super::{VAULT_FILE_NAME, check_vault_name, make_vault_dir_path, create_vault_file, read_vault_file, VaultDiskDirectory};
|
||||
use devtools::RandomTempPath;
|
||||
use self::tempdir::TempDir;
|
||||
|
||||
#[test]
|
||||
fn check_vault_name_succeeds() {
|
||||
@ -320,9 +322,9 @@ mod test {
|
||||
#[test]
|
||||
fn create_vault_file_succeeds() {
|
||||
// given
|
||||
let temp_path = RandomTempPath::new();
|
||||
let temp_path = TempDir::new("").unwrap();
|
||||
let key = VaultKey::new("password", 1024);
|
||||
let mut vault_dir: PathBuf = temp_path.as_path().into();
|
||||
let mut vault_dir: PathBuf = temp_path.path().into();
|
||||
vault_dir.push("vault");
|
||||
fs::create_dir_all(&vault_dir).unwrap();
|
||||
|
||||
@ -339,10 +341,10 @@ mod test {
|
||||
#[test]
|
||||
fn read_vault_file_succeeds() {
|
||||
// given
|
||||
let temp_path = RandomTempPath::create_dir();
|
||||
let temp_path = TempDir::new("").unwrap();
|
||||
let key = VaultKey::new("password", 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 dir: PathBuf = temp_path.as_path().into();
|
||||
let dir: PathBuf = temp_path.path().into();
|
||||
let mut vault_file_path: PathBuf = dir.clone();
|
||||
vault_file_path.push(VAULT_FILE_NAME);
|
||||
{
|
||||
@ -360,9 +362,9 @@ mod test {
|
||||
#[test]
|
||||
fn read_vault_file_fails() {
|
||||
// given
|
||||
let temp_path = RandomTempPath::create_dir();
|
||||
let temp_path = TempDir::new("").unwrap();
|
||||
let key = VaultKey::new("password1", 1024);
|
||||
let dir: PathBuf = temp_path.as_path().into();
|
||||
let dir: PathBuf = temp_path.path().into();
|
||||
let mut vault_file_path: PathBuf = dir.clone();
|
||||
vault_file_path.push(VAULT_FILE_NAME);
|
||||
|
||||
@ -389,9 +391,9 @@ mod test {
|
||||
#[test]
|
||||
fn vault_directory_can_be_created() {
|
||||
// given
|
||||
let temp_path = RandomTempPath::new();
|
||||
let temp_path = TempDir::new("").unwrap();
|
||||
let key = VaultKey::new("password", 1024);
|
||||
let dir: PathBuf = temp_path.as_path().into();
|
||||
let dir: PathBuf = temp_path.path().into();
|
||||
|
||||
// when
|
||||
let vault = VaultDiskDirectory::create(&dir, "vault", key.clone());
|
||||
@ -409,9 +411,9 @@ mod test {
|
||||
#[test]
|
||||
fn vault_directory_cannot_be_created_if_already_exists() {
|
||||
// given
|
||||
let temp_path = RandomTempPath::new();
|
||||
let temp_path = TempDir::new("").unwrap();
|
||||
let key = VaultKey::new("password", 1024);
|
||||
let dir: PathBuf = temp_path.as_path().into();
|
||||
let dir: PathBuf = temp_path.path().into();
|
||||
let mut vault_dir = dir.clone();
|
||||
vault_dir.push("vault");
|
||||
fs::create_dir_all(&vault_dir).unwrap();
|
||||
@ -426,9 +428,9 @@ mod test {
|
||||
#[test]
|
||||
fn vault_directory_cannot_be_opened_if_not_exists() {
|
||||
// given
|
||||
let temp_path = RandomTempPath::create_dir();
|
||||
let temp_path = TempDir::new("").unwrap();
|
||||
let key = VaultKey::new("password", 1024);
|
||||
let dir: PathBuf = temp_path.as_path().into();
|
||||
let dir: PathBuf = temp_path.path().into();
|
||||
|
||||
// when
|
||||
let vault = VaultDiskDirectory::at(&dir, "vault", key);
|
||||
|
@ -620,13 +620,14 @@ impl SimpleSecretStore for EthMultiStore {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
extern crate tempdir;
|
||||
|
||||
use dir::{KeyDirectory, MemoryDirectory, RootDiskDirectory};
|
||||
use ethkey::{Random, Generator, KeyPair};
|
||||
use secret_store::{SimpleSecretStore, SecretStore, SecretVaultRef, StoreAccountRef, Derivation};
|
||||
use super::{EthStore, EthMultiStore};
|
||||
use devtools::RandomTempPath;
|
||||
use util::H256;
|
||||
use self::tempdir::TempDir;
|
||||
use bigint::hash::H256;
|
||||
|
||||
fn keypair() -> KeyPair {
|
||||
Random.generate().unwrap()
|
||||
@ -642,13 +643,13 @@ mod tests {
|
||||
|
||||
struct RootDiskDirectoryGuard {
|
||||
pub key_dir: Option<Box<KeyDirectory>>,
|
||||
_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),
|
||||
|
@ -14,10 +14,11 @@
|
||||
// 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;
|
||||
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<Self, Self::Err> {
|
||||
serde_json::from_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Crypto> 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,
|
||||
|
@ -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};
|
||||
|
@ -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)]
|
||||
|
Loading…
Reference in New Issue
Block a user