Skip to content
This repository has been archived by the owner on Feb 3, 2023. It is now read-only.

Signing 2 - hc keygen #974

Merged
merged 19 commits into from
Feb 11, 2019
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
### Changed
- Added command `hc keygen` which creates a new key pair, asks for a passphrase and writes an encrypted key bundle file to `~/.holochain/keys`.
- core now depends on `pretty_assertions` crate
- `ChainHeader::sources()` is now `ChainHeader::provenances()`
- Headers from other agents are stored in the EAV
Expand Down
4 changes: 4 additions & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ holochain_core_types = { path = "../core_types" }
holochain_core = { path = "../core" }
holochain_cas_implementations = { path = "../cas_implementations" }
holochain_conductor_api = { path = "../conductor_api" }
holochain_dpki = { path = "../hc_dpki" }
holochain_sodium = { path = "../sodium" }
holochain_wasm_utils = { path = "../wasm_utils" }
structopt = "0.2"
failure = "^0.1"
Expand All @@ -25,3 +27,5 @@ dir-diff = "0.3.1"
colored = "1.6"
ignore = "0.4.3"
rustyline = "^2.1"
rpassword = "2.1.0"
directories = "1.0"
50 changes: 50 additions & 0 deletions cli/src/cli/keygen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use error::DefaultResult;
use holochain_dpki::{
bundle::KeyBundle,
keypair::{Keypair, SEEDSIZE},
util::PwHashConfig,
};
use holochain_sodium::{pwhash, random::random_secbuf, secbuf::SecBuf};
use rpassword;
use std::{
fs::{create_dir_all, File},
io::prelude::*,
path::PathBuf,
};

pub fn keygen() -> DefaultResult<()> {
let passphrase = rpassword::read_password_from_tty(Some("Passphrase: ")).unwrap();

let mut seed = SecBuf::with_secure(SEEDSIZE);
random_secbuf(&mut seed);
let mut keypair = Keypair::new_from_seed(&mut seed).unwrap();
let passphrase_bytes = passphrase.as_bytes();
let mut passphrase_buf = SecBuf::with_insecure(passphrase_bytes.len());
passphrase_buf
.write(0, passphrase_bytes)
.expect("SecBuf must be writeable");

let bundle: KeyBundle = keypair
.get_bundle(
&mut passphrase_buf,
"hint".to_string(),
Some(PwHashConfig(
pwhash::OPSLIMIT_INTERACTIVE,
pwhash::MEMLIMIT_INTERACTIVE,
pwhash::ALG_ARGON2ID13,
)),
)
.unwrap();

let path = match directories::UserDirs::new() {
Some(user_dirs) => user_dirs.home_dir().join(".holochain").join("keys"),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on what I added into the tree about directories, I propose that we create a new crate, or shareable file, that keeps track of and documents all the “magic strings” representing paths on devices. I find that they get scattered in the code and the act as high risk points of failure for our system I think. If we could start in that direction in this Pr that would be amazing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I'm in favor of creating these directories with the XDG_CONFIG convention in mind. The directories crate already does that for you, we just have to use it.

None => PathBuf::new(),
};

create_dir_all(path.clone())?;
let path = path.join(keypair.pub_keys);
let mut file = File::create(path.clone())?;
file.write_all(serde_json::to_string(&bundle).unwrap().as_bytes())?;
println!("Wrote {}.", path.to_str().unwrap());
Ok(())
}
2 changes: 2 additions & 0 deletions cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod agent;
mod generate;
mod init;
mod keygen;
pub mod package;
mod run;
mod scaffold;
Expand All @@ -11,6 +12,7 @@ pub use self::{
agent::agent,
generate::generate,
init::init,
keygen::keygen,
package::{package, unpack},
run::run,
test::{test, TEST_DIR_NAME},
Expand Down
10 changes: 10 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ extern crate holochain_cas_implementations;
extern crate holochain_conductor_api;
extern crate holochain_core;
extern crate holochain_core_types;
extern crate holochain_dpki;
extern crate holochain_net;
extern crate holochain_sodium;
extern crate holochain_wasm_utils;
extern crate structopt;
#[macro_use]
Expand All @@ -19,6 +21,7 @@ extern crate toml;
#[macro_use]
extern crate serde_json;
extern crate ignore;
extern crate rpassword;
extern crate rustyline;
extern crate tempfile;
extern crate uuid;
Expand Down Expand Up @@ -142,6 +145,12 @@ enum Cli {
#[structopt(long = "skip-package", short = "s", help = "Skip packaging DNA")]
skip_build: bool,
},
#[structopt(
name = "keygen",
alias = "k",
about = "Creates a new agent key pair, asks for a passphrase and writes an encrypted key bundle to ~/.holochain/keys"
lucksus marked this conversation as resolved.
Show resolved Hide resolved
)]
KeyGen,
}

fn main() {
Expand Down Expand Up @@ -183,6 +192,7 @@ fn run() -> HolochainResult<()> {
cli::test(&current_path, &dir, &testfile, skip_build)
}
.map_err(HolochainError::Default)?,
Cli::KeyGen => cli::keygen().map_err(|e| HolochainError::Default(format_err!("{}", e)))?,
}

Ok(())
Expand Down
1 change: 1 addition & 0 deletions hc_dpki/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/// The bundle_type tells if the bundle is a RootSeed bundle | DeviceSeed bundle | DevicePINSeed Bundle | ApplicationKeys Bundle
///
/// the data includes a base64 encoded string of the ReturnBundleData Struct that was created by combining all the keys in one SecBuf
#[derive(Serialize, Deserialize)]
pub struct KeyBundle {
pub bundle_type: String,
pub hint: String,
Expand Down
5 changes: 3 additions & 2 deletions hc_dpki/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ extern crate holochain_sodium;
#[macro_use]
extern crate arrayref;
extern crate base64;
extern crate rustc_serialize;

extern crate bip39;
extern crate boolinator;
extern crate rustc_serialize;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed again?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. I've just moved this by two lines for alphanumeric sorting.

#[macro_use]
extern crate serde;

pub mod bundle;
pub mod error;
Expand Down