diff --git a/ethstore/src/account/safe_account.rs b/ethstore/src/account/safe_account.rs index 3b3dcf2ee..98d8017d3 100644 --- a/ethstore/src/account/safe_account.rs +++ b/ethstore/src/account/safe_account.rs @@ -23,7 +23,7 @@ use account::{Version, Cipher, Kdf, Aes128Ctr, Pbkdf2, Prf}; #[derive(Debug, PartialEq, Clone)] pub struct Crypto { pub cipher: Cipher, - pub ciphertext: [u8; 32], + pub ciphertext: Vec, pub kdf: Kdf, pub mac: [u8; 32], } @@ -95,7 +95,7 @@ impl Crypto { cipher: Cipher::Aes128Ctr(Aes128Ctr { iv: iv, }), - ciphertext: ciphertext, + ciphertext: ciphertext.to_vec(), kdf: Kdf::Pbkdf2(Pbkdf2 { dklen: crypto::KEY_LENGTH as u32, salt: salt, @@ -107,6 +107,10 @@ impl Crypto { } pub fn secret(&self, password: &str) -> Result { + if self.ciphertext.len() > 32 { + return Err(Error::InvalidSecret); + } + let (derived_left_bits, derived_right_bits) = match self.kdf { Kdf::Pbkdf2(ref params) => crypto::derive_key_iterations(password, ¶ms.salt, params.c), Kdf::Scrypt(ref params) => crypto::derive_key_scrypt(password, ¶ms.salt, params.n, params.p, params.r), @@ -122,7 +126,8 @@ impl Crypto { match self.cipher { Cipher::Aes128Ctr(ref params) => { - crypto::aes::decrypt(&derived_left_bits, ¶ms.iv, &self.ciphertext, &mut *secret) + let from = 32 - self.ciphertext.len(); + crypto::aes::decrypt(&derived_left_bits, ¶ms.iv, &self.ciphertext, &mut (&mut *secret)[from..]) }, } diff --git a/ethstore/src/json/bytes.rs b/ethstore/src/json/bytes.rs new file mode 100644 index 000000000..fd4a3b995 --- /dev/null +++ b/ethstore/src/json/bytes.rs @@ -0,0 +1,58 @@ +use std::{ops, str}; +use serde::{Deserialize, Deserializer, Error, Serialize, Serializer}; +use rustc_serialize::hex::{ToHex, FromHex, FromHexError}; + +#[derive(Debug, PartialEq)] +pub struct Bytes(Vec); + +impl ops::Deref for Bytes { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Deserialize for Bytes { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer + { + let s = try!(String::deserialize(deserializer)); + let data = try!(s.from_hex().map_err(|e| Error::custom(format!("Invalid hex value {}", e)))); + Ok(Bytes(data)) + } +} + +impl Serialize for Bytes { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer { + serializer.serialize_str(&self.0.to_hex()) + } +} + +impl str::FromStr for Bytes { + type Err = FromHexError; + + fn from_str(s: &str) -> Result { + s.from_hex().map(Bytes) + } +} + +impl From<&'static str> for Bytes { + fn from(s: &'static str) -> Self { + s.parse().expect(&format!("invalid string literal for {}: '{}'", stringify!(Self), s)) + } +} + +impl From> for Bytes { + fn from(v: Vec) -> Self { + Bytes(v) + } +} + +impl From for Vec { + fn from(b: Bytes) -> Self { + b.0 + } +} + diff --git a/ethstore/src/json/crypto.rs b/ethstore/src/json/crypto.rs index 9ff8c1e44..180d1e2d7 100644 --- a/ethstore/src/json/crypto.rs +++ b/ethstore/src/json/crypto.rs @@ -17,12 +17,14 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer, Error}; use serde::de::{Visitor, MapVisitor}; use serde::ser; -use super::{Cipher, CipherSer, CipherSerParams, Kdf, KdfSer, KdfSerParams, H256}; +use super::{Cipher, CipherSer, CipherSerParams, Kdf, KdfSer, KdfSerParams, H256, Bytes}; + +pub type CipherText = Bytes; #[derive(Debug, PartialEq)] pub struct Crypto { pub cipher: Cipher, - pub ciphertext: H256, + pub ciphertext: CipherText, pub kdf: Kdf, pub mac: H256, } diff --git a/ethstore/src/json/hash.rs b/ethstore/src/json/hash.rs index 0079b4f81..25bf51130 100644 --- a/ethstore/src/json/hash.rs +++ b/ethstore/src/json/hash.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::fmt; -use std::ops; -use std::str::FromStr; +use std::{ops, fmt, str}; use rustc_serialize::hex::{FromHex, ToHex}; use serde::{Serialize, Serializer, Deserialize, Deserializer, Error as SerdeError}; use serde::de::Visitor; @@ -65,7 +63,7 @@ macro_rules! impl_hash { type Value = $name; fn visit_str(&mut self, value: &str) -> Result where E: SerdeError { - FromStr::from_str(value).map_err(SerdeError::custom) + value.parse().map_err(SerdeError::custom) } fn visit_string(&mut self, value: String) -> Result where E: SerdeError { @@ -77,7 +75,7 @@ macro_rules! impl_hash { } } - impl FromStr for $name { + impl str::FromStr for $name { type Err = Error; fn from_str(value: &str) -> Result { @@ -92,6 +90,12 @@ macro_rules! impl_hash { } } + impl From<&'static str> for $name { + fn from(s: &'static str) -> Self { + s.parse().expect(&format!("invalid string literal for {}: '{}'", stringify!(Self), s)) + } + } + impl From<[u8; $size]> for $name { fn from(bytes: [u8; $size]) -> Self { $name(bytes) diff --git a/ethstore/src/json/id.rs b/ethstore/src/json/id.rs index 2e896458c..ff282a9f8 100644 --- a/ethstore/src/json/id.rs +++ b/ethstore/src/json/id.rs @@ -15,8 +15,7 @@ // along with Parity. If not, see . //! Universaly unique identifier. -use std::str::FromStr; -use std::fmt; +use std::{fmt, str}; use rustc_serialize::hex::{ToHex, FromHex}; use serde::{Deserialize, Serialize, Deserializer, Serializer, Error as SerdeError}; use serde::de::Visitor; @@ -73,7 +72,7 @@ fn copy_into(from: &str, into: &mut [u8]) -> Result<(), Error> { Ok(()) } -impl FromStr for UUID { +impl str::FromStr for UUID { type Err = Error; fn from_str(s: &str) -> Result { @@ -95,6 +94,12 @@ impl FromStr for UUID { } } +impl From<&'static str> for UUID { + fn from(s: &'static str) -> Self { + s.parse().expect(&format!("invalid string literal for {}: '{}'", stringify!(Self), s)) + } +} + impl Serialize for UUID { fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { @@ -116,7 +121,7 @@ impl Visitor for UUIDVisitor { type Value = UUID; fn visit_str(&mut self, value: &str) -> Result where E: SerdeError { - UUID::from_str(value).map_err(SerdeError::custom) + value.parse().map_err(SerdeError::custom) } fn visit_string(&mut self, value: String) -> Result where E: SerdeError { @@ -126,19 +131,18 @@ impl Visitor for UUIDVisitor { #[cfg(test)] mod tests { - use std::str::FromStr; use super::UUID; #[test] fn uuid_from_str() { - let uuid = UUID::from_str("3198bc9c-6672-5ab3-d995-4942343ae5b6").unwrap(); + let uuid: UUID = "3198bc9c-6672-5ab3-d995-4942343ae5b6".into(); assert_eq!(uuid, UUID::from([0x31, 0x98, 0xbc, 0x9c, 0x66, 0x72, 0x5a, 0xb3, 0xd9, 0x95, 0x49, 0x42, 0x34, 0x3a, 0xe5, 0xb6])); } #[test] fn uuid_from_and_to_str() { let from = "3198bc9c-6672-5ab3-d995-4942343ae5b6"; - let uuid = UUID::from_str(from).unwrap(); + let uuid: UUID = from.into(); let to: String = uuid.into(); assert_eq!(from, &to); } diff --git a/ethstore/src/json/key_file.rs b/ethstore/src/json/key_file.rs index 7d970a15c..6e37c7c89 100644 --- a/ethstore/src/json/key_file.rs +++ b/ethstore/src/json/key_file.rs @@ -98,7 +98,7 @@ impl Visitor for KeyFileVisitor { Some(KeyFileField::Version) => { version = Some(try!(visitor.visit_value())); } Some(KeyFileField::Crypto) => { crypto = Some(try!(visitor.visit_value())); } Some(KeyFileField::Address) => { address = Some(try!(visitor.visit_value())); } - Some(KeyFileField::Name) => { name = visitor.visit_value().ok(); } // ignore anyhing that is not a string to be permissive. + Some(KeyFileField::Name) => { name = visitor.visit_value().ok(); } // ignore anyhing that is not a string to be permissive. Some(KeyFileField::Meta) => { meta = visitor.visit_value().ok(); } // ignore anyhing that is not a string to be permissive. None => { break; } } @@ -153,7 +153,7 @@ impl KeyFile { mod tests { use std::str::FromStr; use serde_json; - use json::{KeyFile, UUID, Version, Crypto, Cipher, Aes128Ctr, Kdf, Scrypt, H128, H160, H256}; + use json::{KeyFile, UUID, Version, Crypto, Cipher, Aes128Ctr, Kdf, Scrypt}; #[test] fn basic_keyfile() { @@ -185,20 +185,20 @@ mod tests { let expected = KeyFile { id: UUID::from_str("8777d9f6-7860-4b9b-88b7-0b57ee6b3a73").unwrap(), version: Version::V3, - address: H160::from_str("6edddfc6349aff20bc6467ccf276c5b52487f7a8").unwrap(), + address: "6edddfc6349aff20bc6467ccf276c5b52487f7a8".into(), crypto: Crypto { cipher: Cipher::Aes128Ctr(Aes128Ctr { - iv: H128::from_str("b5a7ec855ec9e2c405371356855fec83").unwrap(), + iv: "b5a7ec855ec9e2c405371356855fec83".into(), }), - ciphertext: H256::from_str("7203da0676d141b138cd7f8e1a4365f59cc1aa6978dc5443f364ca943d7cb4bc").unwrap(), + ciphertext: "7203da0676d141b138cd7f8e1a4365f59cc1aa6978dc5443f364ca943d7cb4bc".into(), kdf: Kdf::Scrypt(Scrypt { n: 262144, dklen: 32, p: 1, r: 8, - salt: H256::from_str("1e8642fdf1f87172492c1412fc62f8db75d796cdfa9c53c3f2b11e44a2a1b209").unwrap(), + salt: "1e8642fdf1f87172492c1412fc62f8db75d796cdfa9c53c3f2b11e44a2a1b209".into(), }), - mac: H256::from_str("46325c5d4e8c991ad2683d525c7854da387138b6ca45068985aa4959fa2b8c8f").unwrap(), + mac: "46325c5d4e8c991ad2683d525c7854da387138b6ca45068985aa4959fa2b8c8f".into(), }, name: Some("Test".to_owned()), meta: Some("{}".to_owned()), @@ -234,22 +234,22 @@ mod tests { }"#; let expected = KeyFile { - id: UUID::from_str("8777d9f6-7860-4b9b-88b7-0b57ee6b3a73").unwrap(), + id: "8777d9f6-7860-4b9b-88b7-0b57ee6b3a73".into(), version: Version::V3, - address: H160::from_str("6edddfc6349aff20bc6467ccf276c5b52487f7a8").unwrap(), + address: "6edddfc6349aff20bc6467ccf276c5b52487f7a8".into(), crypto: Crypto { cipher: Cipher::Aes128Ctr(Aes128Ctr { - iv: H128::from_str("b5a7ec855ec9e2c405371356855fec83").unwrap(), + iv: "b5a7ec855ec9e2c405371356855fec83".into(), }), - ciphertext: H256::from_str("7203da0676d141b138cd7f8e1a4365f59cc1aa6978dc5443f364ca943d7cb4bc").unwrap(), + ciphertext: "7203da0676d141b138cd7f8e1a4365f59cc1aa6978dc5443f364ca943d7cb4bc".into(), kdf: Kdf::Scrypt(Scrypt { n: 262144, dklen: 32, p: 1, r: 8, - salt: H256::from_str("1e8642fdf1f87172492c1412fc62f8db75d796cdfa9c53c3f2b11e44a2a1b209").unwrap(), + salt: "1e8642fdf1f87172492c1412fc62f8db75d796cdfa9c53c3f2b11e44a2a1b209".into(), }), - mac: H256::from_str("46325c5d4e8c991ad2683d525c7854da387138b6ca45068985aa4959fa2b8c8f").unwrap(), + mac: "46325c5d4e8c991ad2683d525c7854da387138b6ca45068985aa4959fa2b8c8f".into(), }, name: None, meta: None, @@ -262,22 +262,22 @@ mod tests { #[test] fn to_and_from_json() { let file = KeyFile { - id: UUID::from_str("8777d9f6-7860-4b9b-88b7-0b57ee6b3a73").unwrap(), + id: "8777d9f6-7860-4b9b-88b7-0b57ee6b3a73".into(), version: Version::V3, - address: H160::from_str("6edddfc6349aff20bc6467ccf276c5b52487f7a8").unwrap(), + address: "6edddfc6349aff20bc6467ccf276c5b52487f7a8".into(), crypto: Crypto { cipher: Cipher::Aes128Ctr(Aes128Ctr { - iv: H128::from_str("b5a7ec855ec9e2c405371356855fec83").unwrap(), + iv: "b5a7ec855ec9e2c405371356855fec83".into(), }), - ciphertext: H256::from_str("7203da0676d141b138cd7f8e1a4365f59cc1aa6978dc5443f364ca943d7cb4bc").unwrap(), + ciphertext: "7203da0676d141b138cd7f8e1a4365f59cc1aa6978dc5443f364ca943d7cb4bc".into(), kdf: Kdf::Scrypt(Scrypt { n: 262144, dklen: 32, p: 1, r: 8, - salt: H256::from_str("1e8642fdf1f87172492c1412fc62f8db75d796cdfa9c53c3f2b11e44a2a1b209").unwrap(), + salt: "1e8642fdf1f87172492c1412fc62f8db75d796cdfa9c53c3f2b11e44a2a1b209".into(), }), - mac: H256::from_str("46325c5d4e8c991ad2683d525c7854da387138b6ca45068985aa4959fa2b8c8f").unwrap(), + mac: "46325c5d4e8c991ad2683d525c7854da387138b6ca45068985aa4959fa2b8c8f".into(), }, name: Some("Test".to_owned()), meta: None, diff --git a/ethstore/src/json/mod.rs.in b/ethstore/src/json/mod.rs.in index 4f9fdbfe3..133d9821e 100644 --- a/ethstore/src/json/mod.rs.in +++ b/ethstore/src/json/mod.rs.in @@ -1,3 +1,4 @@ +mod bytes; mod cipher; mod crypto; mod error; @@ -8,8 +9,9 @@ mod key_file; mod presale; mod version; +pub use self::bytes::Bytes; pub use self::cipher::{Cipher, CipherSer, CipherSerParams, Aes128Ctr}; -pub use self::crypto::Crypto; +pub use self::crypto::{Crypto, CipherText}; pub use self::error::Error; pub use self::hash::{H128, H160, H256}; pub use self::id::UUID; diff --git a/ethstore/src/json/presale.rs b/ethstore/src/json/presale.rs index 77394fcb1..d1cffcb6a 100644 --- a/ethstore/src/json/presale.rs +++ b/ethstore/src/json/presale.rs @@ -1,30 +1,8 @@ use std::io::Read; -use std::ops::Deref; use serde_json; -use serde::{Deserialize, Deserializer, Error}; -use rustc_serialize::hex::FromHex; -use super::{H160}; +use super::{H160, Bytes}; -#[derive(Debug, PartialEq)] -pub struct Encseed(Vec); - -impl Deref for Encseed { - type Target = [u8]; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl Deserialize for Encseed { - fn deserialize(deserializer: &mut D) -> Result - where D: Deserializer - { - let s = try!(String::deserialize(deserializer)); - let data = try!(s.from_hex().map_err(|e| Error::custom(format!("Invalid hex value {}", e)))); - Ok(Encseed(data)) - } -} +pub type Encseed = Bytes; #[derive(Debug, PartialEq, Deserialize)] pub struct PresaleWallet { @@ -43,8 +21,7 @@ impl PresaleWallet { mod tests { use std::str::FromStr; use serde_json; - use rustc_serialize::hex::FromHex; - use json::{PresaleWallet, H160, Encseed}; + use json::{PresaleWallet, H160}; #[test] fn presale_wallet() { @@ -57,7 +34,7 @@ mod tests { } "#; let expected = PresaleWallet { - encseed: Encseed("137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066".from_hex().unwrap()), + encseed: "137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066".into(), address: H160::from_str("ede84640d1a1d3e06902048e67aa7db8d52c2ce1").unwrap(), }; @@ -77,7 +54,7 @@ mod tests { } "#; let expected = PresaleWallet { - encseed: Encseed("137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0d".from_hex().unwrap()), + encseed: "137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0dcf0d".into(), address: H160::from_str("ede84640d1a1d3e06902048e67aa7db8d52c2ce1").unwrap(), }; diff --git a/ethstore/tests/api.rs b/ethstore/tests/api.rs index 83aa04874..e1667607b 100644 --- a/ethstore/tests/api.rs +++ b/ethstore/tests/api.rs @@ -19,9 +19,8 @@ extern crate ethstore; mod util; -use std::str::FromStr; use ethstore::{SecretStore, EthStore}; -use ethstore::ethkey::{Random, Generator, Secret, Address}; +use ethstore::ethkey::{Random, Generator, Secret, KeyPair, verify_address}; use ethstore::dir::DiskDirectory; use util::TransientDir; @@ -103,14 +102,21 @@ fn pat_path() -> &'static str { } } +fn ciphertext_path() -> &'static str { + match ::std::fs::metadata("ethstore") { + Ok(_) => "ethstore/tests/res/ciphertext", + Err(_) => "tests/res/ciphertext", + } +} + #[test] fn secret_store_laod_geth_files() { let dir = DiskDirectory::at(test_path()); let store = EthStore::open(Box::new(dir)).unwrap(); assert_eq!(store.accounts().unwrap(), vec![ - Address::from_str("3f49624084b67849c7b4e805c5988c21a430f9d9").unwrap(), - Address::from_str("5ba4dcf897e97c2bdf8315b9ef26c13c085988cf").unwrap(), - Address::from_str("63121b431a52f8043c16fcf0d1df9cb7b5f66649").unwrap(), + "3f49624084b67849c7b4e805c5988c21a430f9d9".into(), + "5ba4dcf897e97c2bdf8315b9ef26c13c085988cf".into(), + "63121b431a52f8043c16fcf0d1df9cb7b5f66649".into(), ]); } @@ -119,9 +125,30 @@ fn secret_store_load_pat_files() { let dir = DiskDirectory::at(pat_path()); let store = EthStore::open(Box::new(dir)).unwrap(); assert_eq!(store.accounts().unwrap(), vec![ - Address::from_str("3f49624084b67849c7b4e805c5988c21a430f9d9").unwrap(), - Address::from_str("5ba4dcf897e97c2bdf8315b9ef26c13c085988cf").unwrap(), + "3f49624084b67849c7b4e805c5988c21a430f9d9".into(), + "5ba4dcf897e97c2bdf8315b9ef26c13c085988cf".into(), ]); } +#[test] +fn test_decrypting_files_with_short_ciphertext() { + // 31e9d1e6d844bd3a536800ef8d8be6a9975db509, 30 + let kp1 = KeyPair::from_secret("000081c29e8142bb6a81bef5a92bda7a8328a5c85bb2f9542e76f9b0f94fc018".into()).unwrap(); + // d1e64e5480bfaf733ba7d48712decb8227797a4e , 31 + let kp2 = KeyPair::from_secret("00fa7b3db73dc7dfdf8c5fbdb796d741e4488628c41fc4febd9160a866ba0f35".into()).unwrap(); + let dir = DiskDirectory::at(ciphertext_path()); + let store = EthStore::open(Box::new(dir)).unwrap(); + let accounts = store.accounts().unwrap(); + assert_eq!(accounts, vec![ + "31e9d1e6d844bd3a536800ef8d8be6a9975db509".into(), + "d1e64e5480bfaf733ba7d48712decb8227797a4e".into(), + ]); + let message = Default::default(); + + let s1 = store.sign(&accounts[0], "foo", &message).unwrap(); + let s2 = store.sign(&accounts[1], "foo", &message).unwrap(); + assert!(verify_address(&accounts[0], &s1, &message).unwrap()); + assert!(verify_address(&kp1.address(), &s1, &message).unwrap()); + assert!(verify_address(&kp2.address(), &s2, &message).unwrap()); +} diff --git a/ethstore/tests/res/ciphertext/30.json b/ethstore/tests/res/ciphertext/30.json new file mode 100644 index 000000000..c4f5ad184 --- /dev/null +++ b/ethstore/tests/res/ciphertext/30.json @@ -0,0 +1,21 @@ +{ + "address" : "31e9d1e6d844bd3a536800ef8d8be6a9975db509", + "crypto" : { + "cipher" : "aes-128-ctr", + "cipherparams" : { + "iv" : "3ca92af36ad7c2cd92454c59cea5ef00" + }, + "ciphertext" : "108b7d34f3442fc26ab1ab90ca91476ba6bfa8c00975a49ef9051dc675aa", + "kdf" : "scrypt", + "kdfparams" : { + "dklen" : 32, + "n" : 2, + "r" : 8, + "p" : 1, + "salt" : "d0769e608fb86cda848065642a9c6fa046845c928175662b8e356c77f914cd3b" + }, + "mac" : "75d0e6759f7b3cefa319c3be41680ab6beea7d8328653474bd06706d4cc67420" + }, + "id" : "a37e1559-5955-450d-8075-7b8931b392b2", + "version" : 3 +} diff --git a/ethstore/tests/res/ciphertext/31.json b/ethstore/tests/res/ciphertext/31.json new file mode 100644 index 000000000..9c2612b03 --- /dev/null +++ b/ethstore/tests/res/ciphertext/31.json @@ -0,0 +1,21 @@ +{ + "address" : "d1e64e5480bfaf733ba7d48712decb8227797a4e", + "crypto" : { + "cipher" : "aes-128-ctr", + "cipherparams" : { + "iv" : "e0c41130a323adc1446fc82f724bca2f" + }, + "ciphertext" : "9517cd5bdbe69076f9bf5057248c6c050141e970efa36ce53692d5d59a3984", + "kdf" : "scrypt", + "kdfparams" : { + "dklen" : 32, + "n" : 2, + "r" : 8, + "p" : 1, + "salt" : "711f816911c92d649fb4c84b047915679933555030b3552c1212609b38208c63" + }, + "mac" : "d5e116151c6aa71470e67a7d42c9620c75c4d23229847dcc127794f0732b0db5" + }, + "id" : "fecfc4ce-e956-48fd-953b-30f8b52ed66c", + "version" : 3 +}