Skip to content

Commit

Permalink
rename gorc keys {cosmos,eth} import to recover; add gorc keys eth im…
Browse files Browse the repository at this point in the history
…port (#82)
  • Loading branch information
levicook authored Jul 20, 2021
1 parent 550b158 commit 66dc93f
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 47 deletions.
8 changes: 4 additions & 4 deletions orchestrator/gorc/src/commands/keys/cosmos.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod add;
mod delete;
mod import;
mod list;
mod recover;
mod rename;
mod show;

Expand All @@ -12,12 +12,12 @@ pub enum CosmosKeysCmd {
#[options(help = "add [name]")]
Add(add::AddCosmosKeyCmd),

#[options(help = "import [name] (bip39-mnemnoic)")]
Import(import::ImportCosmosKeyCmd),

#[options(help = "delete [name]")]
Delete(delete::DeleteCosmosKeyCmd),

#[options(help = "import [name] (bip39-mnemnoic)")]
Recover(recover::RecoverCosmosKeyCmd),

#[options(help = "rename [name] [new-name]")]
Rename(rename::RenameCosmosKeyCmd),

Expand Down
1 change: 0 additions & 1 deletion orchestrator/gorc/src/commands/keys/cosmos/add.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use super::show::ShowCosmosKeyCmd;
use crate::application::APP;
use abscissa_core::{Application, Command, Options, Runnable};
use bip32;
use k256::pkcs8::ToPrivateKey;
use rand_core::OsRng;
use signatory::FsKeyStore;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
use super::show::ShowCosmosKeyCmd;
use crate::application::APP;
use abscissa_core::{Application, Command, Options, Runnable};
use bip32;
use k256::pkcs8::ToPrivateKey;
use signatory::FsKeyStore;
use std::path;

#[derive(Command, Debug, Default, Options)]
pub struct ImportCosmosKeyCmd {
#[options(free, help = "import [name] (bip39-mnemonic)")]
pub struct RecoverCosmosKeyCmd {
#[options(free, help = "recover [name] (bip39-mnemonic)")]
pub args: Vec<String>,

#[options(help = "overwrite existing key")]
pub overwrite: bool,
}

// `gorc keys cosmos import [name] (bip39-mnemonic)`
// `gorc keys cosmos recover [name] (bip39-mnemonic)`
// - [name] required; key name
// - (bip39-mnemonic) optional; when absent the user will be prompted to enter it
impl Runnable for ImportCosmosKeyCmd {
impl Runnable for RecoverCosmosKeyCmd {
fn run(&self) {
let config = APP.config();
let keystore = path::Path::new(&config.keystore);
let keystore = FsKeyStore::create_or_open(keystore).expect("Could not open keystore");
let keystore =
FsKeyStore::create_or_open(keystore).expect("Could not open keystore");

let name = self.args.get(0).expect("name is required");
let name = name.parse().expect("Could not parse name");
Expand All @@ -35,8 +35,10 @@ impl Runnable for ImportCosmosKeyCmd {

let mnemonic = match self.args.get(1) {
Some(mnemonic) => mnemonic.clone(),
None => rpassword::read_password_from_tty(Some("> Enter your bip39-mnemonic:\n"))
.expect("Could not read mnemonic"),
None => rpassword::read_password_from_tty(Some(
"> Enter your bip39-mnemonic:\n",
))
.expect("Could not read mnemonic"),
};

let mnemonic = bip32::Mnemonic::new(mnemonic.trim(), Default::default())
Expand Down
18 changes: 11 additions & 7 deletions orchestrator/gorc/src/commands/keys/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ mod add;
mod delete;
mod import;
mod list;
mod show;
mod recover;
mod rename;
mod show;

use abscissa_core::{Command, Options, Runnable};

Expand All @@ -12,18 +13,21 @@ pub enum EthKeysCmd {
#[options(help = "add [name]")]
Add(add::AddEthKeyCmd),

#[options(help = "import [name] (bip39-mnemonic)")]
Import(import::ImportEthKeyCmd),

#[options(help = "delete [name]")]
Delete(delete::DeleteEthKeyCmd),

#[options(help = "rename [name] [new-name]")]
Rename(rename::RenameEthKeyCmd),
#[options(help = "import [name] (private-key)")]
Import(import::ImportEthKeyCmd),

#[options(help = "list")]
List(list::ListEthKeyCmd),

#[options(help = "recover [name] (bip39-mnemonic)")]
Recover(recover::RecoverEthKeyCmd),

#[options(help = "rename [name] [new-name]")]
Rename(rename::RenameEthKeyCmd),

#[options(help = "show [name]")]
Show(show::ShowEthKeyCmd),
}
}
12 changes: 9 additions & 3 deletions orchestrator/gorc/src/commands/keys/eth/add.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use super::show::ShowEthKeyCmd;
use crate::application::APP;
use abscissa_core::{Application, Command, Options, Runnable};
use bip32;
use k256::pkcs8::ToPrivateKey;
use rand_core::OsRng;
use signatory::FsKeyStore;
Expand All @@ -14,6 +13,9 @@ pub struct AddEthKeyCmd {

#[options(help = "overwrite existing key")]
pub overwrite: bool,

#[options(help = "show private key")]
show_private_key: bool,
}

// Entry point for `gorc keys eth add [name]`
Expand Down Expand Up @@ -49,10 +51,14 @@ impl Runnable for AddEthKeyCmd {
let key = key
.to_pkcs8_der()
.expect("Could not PKCS8 encod private key");

keystore.store(&name, &key).expect("Could not store key");

let args = vec![name.to_string()];
let show_cmd = ShowEthKeyCmd { args };
let show_cmd = ShowEthKeyCmd {
args: vec![name.to_string()],
show_private_key: self.show_private_key,
show_name: false,
};
show_cmd.run();
}
}
41 changes: 21 additions & 20 deletions orchestrator/gorc/src/commands/keys/eth/import.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
use super::show::ShowEthKeyCmd;
use crate::application::APP;
use abscissa_core::{Application, Command, Options, Runnable};
use k256::pkcs8::ToPrivateKey;
use k256::{pkcs8::ToPrivateKey, SecretKey};

use signatory::FsKeyStore;
use std::path;

#[derive(Command, Debug, Default, Options)]
pub struct ImportEthKeyCmd {
#[options(free, help = "import [name] (bip39-mnemonic)")]
#[options(free, help = "import [name] (private-key)")]
pub args: Vec<String>,

#[options(help = "overwrite existing key")]
pub overwrite: bool,

#[options(help = "show private key")]
show_private_key: bool,
}

// Entry point for `gorc keys eth import [name] (bip39-mnemonic)`
// Entry point for `gorc keys eth import [name] (private-key)`
// - [name] required; key name
// - (bip39-mnemonic) optional; when absent the user will be prompted to enter it
// - (private-key) optional; when absent the user will be prompted to enter it
impl Runnable for ImportEthKeyCmd {
fn run(&self) {
let config = APP.config();
Expand All @@ -32,32 +36,29 @@ impl Runnable for ImportEthKeyCmd {
}
}

let mnemonic = match self.args.get(1) {
Some(mnemonic) => mnemonic.clone(),
None => rpassword::read_password_from_tty(Some("> Enter your bip39-mnemonic:\n"))
.expect("Could not read mnemonic"),
let key = match self.args.get(1) {
Some(private_key) => private_key.clone(),
None => rpassword::read_password_from_tty(Some("> Enter your private-key:\n"))
.expect("Could not read private-key"),
};

let mnemonic = bip32::Mnemonic::new(mnemonic.trim(), Default::default())
.expect("Could not parse mnemonic");

let seed = mnemonic.to_seed("");
let key = key
.parse::<clarity::PrivateKey>()
.expect("Could not parse private-key");

let path = config.ethereum.key_derivation_path.trim();
let path = path
.parse::<bip32::DerivationPath>()
.expect("Could not parse derivation path");
let key = SecretKey::from_bytes(key.to_bytes()).expect("Could not convert private-key");

let key = bip32::XPrv::derive_from_path(seed, &path).expect("Could not derive key");
let key = k256::SecretKey::from(key.private_key());
let key = key
.to_pkcs8_der()
.expect("Could not PKCS8 encod private key");

keystore.store(&name, &key).expect("Could not store key");

let args = vec![name.to_string()];
let show_cmd = ShowEthKeyCmd { args };
let show_cmd = ShowEthKeyCmd {
args: vec![name.to_string()],
show_private_key: self.show_private_key,
show_name: false,
};
show_cmd.run();
}
}
12 changes: 9 additions & 3 deletions orchestrator/gorc/src/commands/keys/eth/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use abscissa_core::{Application, Command, Options, Runnable};
use std::path;

#[derive(Command, Debug, Default, Options)]
pub struct ListEthKeyCmd {}
pub struct ListEthKeyCmd {
#[options(help = "show private key")]
pub show_private_key: bool,
}

// Entry point for `gorc keys eth list`
impl Runnable for ListEthKeyCmd {
Expand All @@ -19,8 +22,11 @@ impl Runnable for ListEthKeyCmd {
if extension == "pem" {
let name = path.file_stem().unwrap();
let name = name.to_str().unwrap();
let args = vec![name.to_string()];
let show_cmd = ShowEthKeyCmd { args };
let show_cmd = ShowEthKeyCmd {
args: vec![name.to_string()],
show_private_key: self.show_private_key,
show_name: true,
};
show_cmd.run();
}
}
Expand Down
72 changes: 72 additions & 0 deletions orchestrator/gorc/src/commands/keys/eth/recover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use super::show::ShowEthKeyCmd;
use crate::application::APP;
use abscissa_core::{Application, Command, Options, Runnable};
use k256::pkcs8::ToPrivateKey;
use signatory::FsKeyStore;
use std::path;

#[derive(Command, Debug, Default, Options)]
pub struct RecoverEthKeyCmd {
#[options(free, help = "recover [name] (bip39-mnemonic)")]
pub args: Vec<String>,

#[options(help = "overwrite existing key")]
pub overwrite: bool,

#[options(help = "show private key")]
show_private_key: bool,
}

// Entry point for `gorc keys eth recover [name] (bip39-mnemonic)`
// - [name] required; key name
// - (bip39-mnemonic) optional; when absent the user will be prompted to enter it
impl Runnable for RecoverEthKeyCmd {
fn run(&self) {
let config = APP.config();
let keystore = path::Path::new(&config.keystore);
let keystore =
FsKeyStore::create_or_open(keystore).expect("Could not open keystore");

let name = self.args.get(0).expect("name is required");
let name = name.parse().expect("Could not parse name");
if let Ok(_info) = keystore.info(&name) {
if !self.overwrite {
eprintln!("Key already exists, exiting.");
return;
}
}

let mnemonic = match self.args.get(1) {
Some(mnemonic) => mnemonic.clone(),
None => rpassword::read_password_from_tty(Some(
"> Enter your bip39-mnemonic:\n",
))
.expect("Could not read mnemonic"),
};

let mnemonic = bip32::Mnemonic::new(mnemonic.trim(), Default::default())
.expect("Could not parse mnemonic");

let seed = mnemonic.to_seed("");

let path = config.ethereum.key_derivation_path.trim();
let path = path
.parse::<bip32::DerivationPath>()
.expect("Could not parse derivation path");

let key = bip32::XPrv::derive_from_path(seed, &path).expect("Could not derive key");
let key = k256::SecretKey::from(key.private_key());
let key = key
.to_pkcs8_der()
.expect("Could not PKCS8 encod private key");

keystore.store(&name, &key).expect("Could not store key");

let show_cmd = ShowEthKeyCmd {
args: vec![name.to_string()],
show_private_key: self.show_private_key,
show_name: false,
};
show_cmd.run();
}
}
15 changes: 14 additions & 1 deletion orchestrator/gorc/src/commands/keys/eth/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ use abscissa_core::{Application, Command, Options, Runnable};
pub struct ShowEthKeyCmd {
#[options(free, help = "show [name]")]
pub args: Vec<String>,

#[options(help = "show private key")]
pub show_private_key: bool,

pub show_name: bool,
}

// Entry point for `gorc keys eth show [name]`
Expand All @@ -16,6 +21,14 @@ impl Runnable for ShowEthKeyCmd {

let pub_key = key.to_public_key().expect("Could not build public key");

println!("{}\t{}", name, pub_key);
if self.show_name {
print!("{}\t", name);
}

if self.show_private_key {
println!("{}\t{}", pub_key, key);
} else {
println!("{}", pub_key);
}
}
}

0 comments on commit 66dc93f

Please sign in to comment.