From 3529d88ab8d5cf36af3a72e66f79eb6bf40c53cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 8 Sep 2020 22:45:28 +0200 Subject: [PATCH 1/3] Support hex encoded secret key for `--node-key` Adds support for reading a hex encoded secret key when being passed as file via `--node-key`. --- client/cli/src/params/node_key_params.rs | 80 +++++++++++++++--------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/client/cli/src/params/node_key_params.rs b/client/cli/src/params/node_key_params.rs index 689cc6c681c83..c7f2da811aaf9 100644 --- a/client/cli/src/params/node_key_params.rs +++ b/client/cli/src/params/node_key_params.rs @@ -16,9 +16,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use sc_network::config::NodeKeyConfig; +use sc_network::{config::identity::ed25519, config::NodeKeyConfig}; use sp_core::H256; -use std::{path::PathBuf, str::FromStr}; +use std::{path::{PathBuf, Path}, str::FromStr, fs::File, io::Read}; use structopt::StructOpt; use crate::arg_enums::NodeKeyType; @@ -83,7 +83,7 @@ pub struct NodeKeyParams { /// as follows: /// /// `ed25519`: - /// The file must contain an unencoded 32 byte Ed25519 secret key. + /// The file must contain an unencoded 32 byte or hex encoded Ed25519 secret key. /// /// If the file does not exist, it is created with a newly generated secret key of /// the chosen type. @@ -99,13 +99,10 @@ impl NodeKeyParams { NodeKeyType::Ed25519 => { let secret = if let Some(node_key) = self.node_key.as_ref() { parse_ed25519_secret(node_key)? + } else if let Some(path) = &self.node_key_file { + open_ed25519_secret(&path)? } else { - let path = self - .node_key_file - .clone() - .unwrap_or_else(|| net_config_dir.join(NODE_KEY_ED25519_FILE)); - - sc_network::config::Secret::File(path) + sc_network::config::Secret::File(net_config_dir.join(NODE_KEY_ED25519_FILE)) }; NodeKeyConfig::Ed25519(secret) @@ -124,16 +121,36 @@ fn parse_ed25519_secret(hex: &str) -> error::Result error::Result { + let mut file = File::open(file) + .map_err(|e| format!("Failed to open ed25519 secret: {:?}", e))?; + + let mut content = Vec::new(); + file.read_to_end(&mut content).map_err(|e| format!("Failed to read ed25519 secret: {:?}", e))?; + + let secret_key = match String::from_utf8(content.clone()) + .ok() + .and_then(|s| H256::from_str(&s).ok()) + { + Some(bytes) => ed25519::SecretKey::from_bytes(bytes), + None => ed25519::SecretKey::from_bytes(content), + }; + + secret_key.map(sc_network::config::Secret::Input).map_err(invalid_node_key) +} + #[cfg(test)] mod tests { use super::*; use sc_network::config::identity::ed25519; + use std::fs; #[test] fn test_node_key_config_input() { @@ -164,28 +181,31 @@ mod tests { #[test] fn test_node_key_config_file() { - fn secret_file(net_config_dir: &PathBuf) -> error::Result<()> { - NodeKeyType::variants().iter().try_for_each(|t| { - let node_key_type = NodeKeyType::from_str(t).unwrap(); - let tmp = tempfile::Builder::new().prefix("alice").tempdir()?; - let file = tmp.path().join(format!("{}_mysecret", t)).to_path_buf(); - let params = NodeKeyParams { - node_key_type, - node_key: None, - node_key_file: Some(file.clone()), - }; - params.node_key(net_config_dir).and_then(|c| match c { - NodeKeyConfig::Ed25519(sc_network::config::Secret::File(ref f)) - if node_key_type == NodeKeyType::Ed25519 && f == &file => - { - Ok(()) - } - _ => Err(error::Error::Input("Unexpected node key config".into())), - }) - }) + fn check_key(file: PathBuf, key: &ed25519::SecretKey) { + let params = NodeKeyParams { + node_key_type: NodeKeyType::Ed25519, + node_key: None, + node_key_file: Some(file), + }; + + let node_key = params.node_key(&PathBuf::from("not-used")).expect("Creates node key"); + + match node_key { + NodeKeyConfig::Ed25519(sc_network::config::Secret::Input(ref secret)) + if secret.as_ref() == key.as_ref() => {} + _ => panic!("Invalid key"), + } } - assert!(secret_file(&PathBuf::from_str("x").unwrap()).is_ok()); + let tmp = tempfile::Builder::new().prefix("alice").tempdir().expect("Creates tempfile"); + let file = tmp.path().join("mysecret").to_path_buf(); + let key = ed25519::SecretKey::generate(); + + fs::write(&file, hex::encode(key.as_ref())).expect("Writes secret key"); + check_key(file.clone(), &key); + + fs::write(&file, &key).expect("Writes secret key"); + check_key(file.clone(), &key); } #[test] From f8a08aa76e3abaa03604122526a385680ad629bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 9 Sep 2020 16:29:19 +0200 Subject: [PATCH 2/3] Make the key loading uniform --- client/cli/src/params/node_key_params.rs | 40 ++++++++---------------- client/network/src/config.rs | 22 +++++++++++-- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/client/cli/src/params/node_key_params.rs b/client/cli/src/params/node_key_params.rs index c7f2da811aaf9..875411fbfb620 100644 --- a/client/cli/src/params/node_key_params.rs +++ b/client/cli/src/params/node_key_params.rs @@ -18,7 +18,7 @@ use sc_network::{config::identity::ed25519, config::NodeKeyConfig}; use sp_core::H256; -use std::{path::{PathBuf, Path}, str::FromStr, fs::File, io::Read}; +use std::{path::PathBuf, str::FromStr}; use structopt::StructOpt; use crate::arg_enums::NodeKeyType; @@ -99,10 +99,12 @@ impl NodeKeyParams { NodeKeyType::Ed25519 => { let secret = if let Some(node_key) = self.node_key.as_ref() { parse_ed25519_secret(node_key)? - } else if let Some(path) = &self.node_key_file { - open_ed25519_secret(&path)? } else { - sc_network::config::Secret::File(net_config_dir.join(NODE_KEY_ED25519_FILE)) + sc_network::config::Secret::File( + self.node_key_file + .clone() + .unwrap_or_else(|| net_config_dir.join(NODE_KEY_ED25519_FILE)) + ) }; NodeKeyConfig::Ed25519(secret) @@ -127,29 +129,10 @@ fn parse_ed25519_secret(hex: &str) -> error::Result error::Result { - let mut file = File::open(file) - .map_err(|e| format!("Failed to open ed25519 secret: {:?}", e))?; - - let mut content = Vec::new(); - file.read_to_end(&mut content).map_err(|e| format!("Failed to read ed25519 secret: {:?}", e))?; - - let secret_key = match String::from_utf8(content.clone()) - .ok() - .and_then(|s| H256::from_str(&s).ok()) - { - Some(bytes) => ed25519::SecretKey::from_bytes(bytes), - None => ed25519::SecretKey::from_bytes(content), - }; - - secret_key.map(sc_network::config::Secret::Input).map_err(invalid_node_key) -} - #[cfg(test)] mod tests { use super::*; - use sc_network::config::identity::ed25519; + use sc_network::config::identity::{ed25519, Keypair}; use std::fs; #[test] @@ -188,11 +171,14 @@ mod tests { node_key_file: Some(file), }; - let node_key = params.node_key(&PathBuf::from("not-used")).expect("Creates node key"); + let node_key = params.node_key(&PathBuf::from("not-used")) + .expect("Creates node key config") + .into_keypair() + .expect("Creates node key pair"); match node_key { - NodeKeyConfig::Ed25519(sc_network::config::Secret::Input(ref secret)) - if secret.as_ref() == key.as_ref() => {} + Keypair::Ed25519(ref pair) + if pair.secret().as_ref() == key.as_ref() => {} _ => panic!("Invalid key"), } } diff --git a/client/network/src/config.rs b/client/network/src/config.rs index cf1f8393f380d..177adb5898ad6 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -625,10 +625,26 @@ impl NodeKeyConfig { Ok(Keypair::Ed25519(k.into())), Ed25519(Secret::File(f)) => - get_secret(f, - |mut b| ed25519::SecretKey::from_bytes(&mut b), + get_secret( + f, + |mut b| { + match String::from_utf8(b.to_vec()) + .ok() + .and_then(|s|{ + if s.len() == 64 { + sp_core::H256::from_str(&s).ok() + } else { + None + }} + ) + { + Some(s) => ed25519::SecretKey::from_bytes(s), + _ => ed25519::SecretKey::from_bytes(&mut b), + } + }, ed25519::SecretKey::generate, - |b| b.as_ref().to_vec()) + |b| b.as_ref().to_vec() + ) .map(ed25519::Keypair::from) .map(Keypair::Ed25519), } From e51cc7db9b9309ddaa204b480a25c158ab628b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 11 Sep 2020 13:19:22 +0200 Subject: [PATCH 3/3] Switch to `hex::decode` --- client/network/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 177adb5898ad6..4949af031f085 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -632,7 +632,7 @@ impl NodeKeyConfig { .ok() .and_then(|s|{ if s.len() == 64 { - sp_core::H256::from_str(&s).ok() + hex::decode(&s).ok() } else { None }}