Skip to content

Commit

Permalink
Merge pull request #210 from r8d8/issue/windows_force_pbkdf2
Browse files Browse the repository at this point in the history
Windows uses low values for scrypt, due to a poor perfomance
  • Loading branch information
r8d8 authored Jul 27, 2017
2 parents 5d1bb2c + 850efe2 commit a1ca3aa
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 19 deletions.
2 changes: 1 addition & 1 deletion emerald-cli/usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ Options:
+ Mac OS X: ~/Library/Emerald
+ Linux: ~/.emerald
+ Windows: %USERDIR%\.emerald
--security-level <normal|high|ultra> Level of security for cryptographic operations [default: normal]
--security-level <normal|high|ultra> Level of security for cryptographic operations [default: ultra]
-c, --chain <mainnet|testnet> Chain name [default: mainnet]
40 changes: 24 additions & 16 deletions emerald-core/src/hdwallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ pub use self::error::Error;
pub use self::keystore::HdwalletCrypto;
use super::{Address, ECDSA_SIGNATURE_BYTES, Signature, to_arr, to_bytes};
use hidapi::{HidApi, HidDevice, HidDeviceInfo};
use regex::Regex;
use std::{thread, time};
use std::str::{FromStr, from_utf8};


const GET_ETH_ADDRESS: u8 = 0x02;
const SIGN_ETH_TRANSACTION: u8 = 0x04;
const CHUNK_SIZE: usize = 255;
Expand Down Expand Up @@ -86,21 +86,28 @@ impl From<HidDeviceInfo> for Device {

/// Parse HD path into byte array
pub fn path_to_arr(hd_str: &str) -> Result<Vec<u8>, Error> {
let mut buf = Vec::new();
lazy_static! {
static ref INVALID_PATH_RE: Regex = Regex::new(r#"[^0-9'/]"#).unwrap();
}

hd_str
.split("/")
.map(|s| {
if INVALID_PATH_RE.is_match(hd_str) {
return Err(Error::HDWalletError(
format!("Invalid `hd_path` format: {}", hd_str),
));
}

let mut buf = Vec::new();
{
let parse = |s: &str| {
let mut str = s.to_string();
let mut v: u64 = 0;

if str.ends_with("'") {
v += 0x80000000;
str.remove(s.len() - 1);
}

match str.parse::<u32>() {
Ok(d) => v += d as u64,
match str.parse::<u64>() {
Ok(d) => v += d,
Err(_) => {
return Err(Error::HDWalletError(
format!("Invalid `hd_path` format: {}", hd_str),
Expand All @@ -109,8 +116,10 @@ pub fn path_to_arr(hd_str: &str) -> Result<Vec<u8>, Error> {
}
buf.extend(to_bytes(v, 4));
Ok(())
})
.collect::<Vec<_>>();
};

hd_str.split("/").map(parse).collect::<Vec<_>>();
}

Ok(buf)
}
Expand Down Expand Up @@ -468,26 +477,25 @@ mod tests {

#[test]
pub fn should_parse_hd_path() {
let path_str = "44\'/60\'/160720\'/0\'/0";
let path_str = "44'/60'/160720'/0'/0";
assert_eq!(
ETC_DERIVATION_PATH[1..].to_vec(),
path_to_arr(&path_str).unwrap()
);
}

#[test]
#[ignore]
pub fn should_fail_parse_hd_path() {
let mut path_str = "44\'/60\'/160A+_0\'/0\'/0";
let mut path_str = "44'/60'/160A+_0'/0'/0";
assert!(path_to_arr(&path_str).is_err());

path_str = "44\'/60\'/16011_11111111111111111zz1111111111111111111111111111111\'/0\'/0";
path_str = "44'/60'/16011_11111111111111111zz1111111111111111111111111111111'/0'/0";
assert!(path_to_arr(&path_str).is_err());
}

#[test]
pub fn should_parse_hd_path_prefixed() {
let path_str = "44\'/60\'/160720\'/0\'/0";
pub fn should_parse_hd_path_into_prefixed() {
let path_str = "44'/60'/160720'/0'/0";
assert_eq!(
ETC_DERIVATION_PATH.to_vec(),
to_prefixed_path(&path_str).unwrap()
Expand Down
12 changes: 10 additions & 2 deletions emerald-core/src/keystore/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod serialize;

pub use self::cipher::Cipher;
pub use self::error::Error;
pub use self::kdf::{Kdf, KdfDepthLevel};
pub use self::kdf::{Kdf, KdfDepthLevel, PBKDF2_KDF_NAME};
pub use self::prf::Prf;
pub use self::serialize::{CoreCrypto, Iv, Mac, Salt, decode_str, hide, list_accounts, unhide};
use super::core::{self, Address, PrivateKey};
Expand All @@ -20,6 +20,7 @@ pub use hdwallet::HdwalletCrypto;
use rand::{OsRng, Rng};
use std::{cmp, fmt};
use std::convert::From;
use std::str::FromStr;
use uuid::Uuid;

/// Key derivation function salt length in bytes
Expand Down Expand Up @@ -76,10 +77,17 @@ impl KeyFile {
) -> Result<KeyFile, Error> {
let mut rng = os_random();

let kdf;
if cfg!(target_os = "windows") {
kdf = Kdf::from_str(PBKDF2_KDF_NAME)?;
} else {
kdf = Kdf::from(*sec_level);
}

Self::new_custom(
PrivateKey::gen_custom(&mut rng),
passphrase,
Kdf::from(*sec_level),
kdf,
&mut rng,
name,
description,
Expand Down
2 changes: 2 additions & 0 deletions emerald-core/tests/keystore_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ fn should_decode_hd_wallet_keyfile() {
}

#[test]
//TODO:1 remove condition after fix for `scrypt` on Windows
#[cfg(not(target_os = "windows"))]
fn should_use_security_level() {
let sec = KdfDepthLevel::Normal;
let kf = KeyFile::new("1234567890", &sec, None, None).unwrap();
Expand Down

0 comments on commit a1ca3aa

Please sign in to comment.