diff --git a/ethtools/Cargo.toml b/ethtools/Cargo.toml index 5529c1d33..0ff934421 100644 --- a/ethtools/Cargo.toml +++ b/ethtools/Cargo.toml @@ -8,3 +8,5 @@ authors = ["Ethcore "] [dependencies] ethcore-util = { path = "../util" } +rustc-serialize = "0.3" +ethcore-devtools = { path = "../devtools" } diff --git a/ethtools/res/geth_keystore/UTC--2016-02-17T09-20-45.721400158Z--3f49624084b67849c7b4e805c5988c21a430f9d9 b/ethtools/res/geth_keystore/UTC--2016-02-17T09-20-45.721400158Z--3f49624084b67849c7b4e805c5988c21a430f9d9 index a62d3056c..afc376774 100644 --- a/ethtools/res/geth_keystore/UTC--2016-02-17T09-20-45.721400158Z--3f49624084b67849c7b4e805c5988c21a430f9d9 +++ b/ethtools/res/geth_keystore/UTC--2016-02-17T09-20-45.721400158Z--3f49624084b67849c7b4e805c5988c21a430f9d9 @@ -1 +1,21 @@ -{"address":"3f49624084b67849c7b4e805c5988c21a430f9d9","Crypto":{"cipher":"aes-128-ctr","ciphertext":"9f27e3dd4fc73e7103ed61e5493662189a3eb52223ae49e3d1deacc04c889eae","cipherparams":{"iv":"457494bf05f2618c397dc74dbb5181c0"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"db14edb18c41ee7f5ec4397df89c3a2ae4d0af60884c52bb54ce490574f8df33"},"mac":"572d24532438d31fdf513c744a3ff26c933ffda5744ee42bc71661cbe3f2112e"},"id":"62a0ad73-556d-496a-8e1c-0783d30d3ace","version":3} \ No newline at end of file +{ + "address": "3f49624084b67849c7b4e805c5988c21a430f9d9", + "Crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "9f27e3dd4fc73e7103ed61e5493662189a3eb52223ae49e3d1deacc04c889eae", + "cipherparams": { + "iv": "457494bf05f2618c397dc74dbb5181c0" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "db14edb18c41ee7f5ec4397df89c3a2ae4d0af60884c52bb54ce490574f8df33" + }, + "mac": "572d24532438d31fdf513c744a3ff26c933ffda5744ee42bc71661cbe3f2112e" + }, + "id": "62a0ad73-556d-496a-8e1c-0783d30d3ace", + "version": 3 +} diff --git a/ethtools/res/geth_keystore/UTC--2016-02-20T09-33-03.984382741Z--5ba4dcf897e97c2bdf8315b9ef26c13c085988cf b/ethtools/res/geth_keystore/UTC--2016-02-20T09-33-03.984382741Z--5ba4dcf897e97c2bdf8315b9ef26c13c085988cf index b6caa1c47..b14922037 100644 --- a/ethtools/res/geth_keystore/UTC--2016-02-20T09-33-03.984382741Z--5ba4dcf897e97c2bdf8315b9ef26c13c085988cf +++ b/ethtools/res/geth_keystore/UTC--2016-02-20T09-33-03.984382741Z--5ba4dcf897e97c2bdf8315b9ef26c13c085988cf @@ -1 +1,21 @@ -{"address":"5ba4dcf897e97c2bdf8315b9ef26c13c085988cf","Crypto":{"cipher":"aes-128-ctr","ciphertext":"d4a08ec930163778273920f6ad1d49b71836337be6fd9863993ac700a612fddd","cipherparams":{"iv":"89ce5ec129fc27cd5bcbeb8c92bdad50"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"612ab108dc37e69ee8af37a7b24bf7f2234086d7bbf945bacdeccce331f7f84a"},"mac":"4152caa7444e06784223d735cea80cd2690b4c587ad8db3d5529442227b25695"},"id":"35086353-fb12-4029-b56b-033cd61ce35b","version":3} \ No newline at end of file +{ + "address": "5ba4dcf897e97c2bdf8315b9ef26c13c085988cf", + "Crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "d4a08ec930163778273920f6ad1d49b71836337be6fd9863993ac700a612fddd", + "cipherparams": { + "iv": "89ce5ec129fc27cd5bcbeb8c92bdad50" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "612ab108dc37e69ee8af37a7b24bf7f2234086d7bbf945bacdeccce331f7f84a" + }, + "mac": "4152caa7444e06784223d735cea80cd2690b4c587ad8db3d5529442227b25695" + }, + "id": "35086353-fb12-4029-b56b-033cd61ce35b", + "version": 3 +} diff --git a/ethtools/src/geth_keys.rs b/ethtools/src/geth_keys.rs index 58dc2a0b1..3148407dd 100644 --- a/ethtools/src/geth_keys.rs +++ b/ethtools/src/geth_keys.rs @@ -17,13 +17,18 @@ //! Geth keys import/export tool use util::hash::*; +use util::keys::store::SecretStore; +use util::keys::directory::KeyFileContent; use std::path::Path; use std::result::*; use std::fs; use std::str::FromStr; +use std::io; +use std::io::Read; +use rustc_serialize::json::Json; /// Enumerates all geth keys in the directory and returns collection of tuples `(accountId, filename)` -pub fn enumerate_geth_keys(path: &Path) -> Result, ::std::io::Error> { +pub fn enumerate_geth_keys(path: &Path) -> Result, io::Error> { let mut entries = Vec::new(); for entry in try!(fs::read_dir(path)) { let entry = try!(entry); @@ -44,14 +49,57 @@ pub fn enumerate_geth_keys(path: &Path) -> Result, ::std: Ok(entries) } +#[derive(Debug)] +pub enum ImportError { + IoError(io::Error), + FormatError, +} + +impl From for ImportError { + fn from (err: io::Error) -> ImportError { + ImportError::IoError(err) + } +} + +pub fn import_geth_key(secret_store: &mut SecretStore, geth_keyfile_path: &Path) -> Result<(), ImportError> { + let mut file = try!(fs::File::open(geth_keyfile_path)); + let mut buf = String::new(); + try!(file.read_to_string(&mut buf)); + + let mut json = match Json::from_str(&buf) { + Ok(parsed_json) => try!(parsed_json.as_object().ok_or(ImportError::FormatError)).clone(), + Err(_) => { return Err(ImportError::FormatError); } + }; + let crypto_object = try!(json.get("Crypto").and_then(|crypto| crypto.as_object()).ok_or(ImportError::FormatError)).clone(); + json.insert("crypto".to_owned(), Json::Object(crypto_object.clone())); + json.remove("Crypto"); + match KeyFileContent::load(&Json::Object(json.clone())) { + Ok(key_file) => try!(secret_store.import_key(key_file)), + Err(_) => { return Err(ImportError::FormatError); } + }; + Ok(()) +} + #[cfg(test)] mod tests { use super::*; use std::path::Path; + use util::hash::*; + use util::keys::store::SecretStore; + use std::str::FromStr; #[test] fn can_enumerate() { let keys = enumerate_geth_keys(Path::new("res/geth_keystore")).unwrap(); assert_eq!(2, keys.len()); } + + #[test] + fn can_import() { + let temp = ::devtools::RandomTempPath::new(); + let mut secret_store = SecretStore::new_in(temp.as_path()); + import_geth_key(&mut secret_store, Path::new("res/geth_keystore/UTC--2016-02-17T09-20-45.721400158Z--3f49624084b67849c7b4e805c5988c21a430f9d9")).unwrap(); + let key = secret_store.account(&Address::from_str("3f49624084b67849c7b4e805c5988c21a430f9d9").unwrap()); + assert!(key.is_some()); + } } diff --git a/ethtools/src/lib.rs b/ethtools/src/lib.rs index 41dd69cf9..1509f6d81 100644 --- a/ethtools/src/lib.rs +++ b/ethtools/src/lib.rs @@ -17,5 +17,7 @@ //! Ethereum Tools Library extern crate ethcore_util as util; +extern crate rustc_serialize; +extern crate ethcore_devtools as devtools; pub mod geth_keys;