Skip to content

Commit

Permalink
feat: support generating PEM encoded ed25519 keys from init
Browse files Browse the repository at this point in the history
  • Loading branch information
QuinnWilton committed Mar 12, 2024
1 parent 388b953 commit af45e14
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 4 deletions.
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions homestar-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ console-subscriber = { version = "0.2", default-features = false, features = [
const_format = { workspace = true }
crossbeam = "0.8"
dagga = "0.2"
ed25519-compact = "2.1"
ed25519-dalek = { version = "2.1", features = ["pem"] }
dashmap = "5.5"
derive-getters = "0.3"
Expand Down
50 changes: 46 additions & 4 deletions homestar-runtime/src/cli/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,12 @@ impl Display for PubkeyConfigOption {

/// Handle the `init` command.
pub fn handle_init_command(init_args: InitArgs) -> Result<()> {
let output_path = init_args.output_path.clone().unwrap_or_else(Settings::path);
let output_mode = if init_args.dry_run {
OutputMode::StdOut
} else {
OutputMode::File {
path: init_args.output_path.unwrap_or_else(Settings::path),
path: output_path.clone(),
}
};

Expand All @@ -108,7 +109,7 @@ pub fn handle_init_command(init_args: InitArgs) -> Result<()> {

let mut writer = handle_quiet(init_args.quiet)?;
let key_type = handle_key_type(init_args.key_type, no_input, &mut writer)?;
let keypair_config = handle_key(key_arg, key_type, no_input, &mut writer)?;
let keypair_config = handle_key(key_arg, key_type, output_path, no_input, &mut writer)?;

let network = network_builder
.keypair_config(keypair_config)
Expand Down Expand Up @@ -243,6 +244,7 @@ fn handle_key_type(
fn handle_key(
key_arg: Option<KeyArg>,
key_type: KeyType,
output_path: PathBuf,
no_input: bool,
_writer: &mut Box<dyn Write>,
) -> Result<PubkeyConfig> {
Expand Down Expand Up @@ -282,7 +284,9 @@ fn handle_key(
message: "Enter the path for the key",
formatter: &|p: PathBuf| p.display().to_string(),
default_value_formatter: &|p| p.display().to_string(),
default: None,
default: output_path
.parent()
.map(|parent| parent.join("homestar.pem")),
validators: vec![],
placeholder: None,
error_message: "Please type a valid path".to_string(),
Expand All @@ -293,11 +297,17 @@ fn handle_key(
.prompt()
.map_err(|e| miette!(e))?;

generate_key_file(&path, &key_type)?;

PubkeyConfig::Existing(ExistingKeyPath::new(key_type, path))
}
}
}
Some(KeyArg::File { path }) => PubkeyConfig::Existing(ExistingKeyPath::new(key_type, path)),
Some(KeyArg::File { path }) => {
generate_key_file(&path, &key_type)?;

PubkeyConfig::Existing(ExistingKeyPath::new(key_type, path))
}
Some(KeyArg::Seed { seed: None }) => {
let seed = rand::thread_rng().gen::<[u8; 32]>();

Expand All @@ -318,3 +328,35 @@ fn handle_key(

Ok(config)
}

fn generate_key_file(path: &PathBuf, key_type: &KeyType) -> Result<()> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).expect("to create parent directory");
}

let key_file = File::options()
.read(true)
.write(true)
.create_new(true)
.open(path);

match key_file {
// file did not exist, generate the key
Ok(mut file) => {
let key = match *key_type {
KeyType::Ed25519 => ed25519_compact::KeyPair::generate().sk.to_pem(),
KeyType::Secp256k1 => bail!("Aborting... generating secp256k1 keys is not yet supported, please provide an existing key file, or choose another key type."),
};

file.write_all(key.as_bytes())
.expect("to write to key file");
}
// file did exist, do nothing and use existing key
Err(err) if err.kind() == std::io::ErrorKind::AlreadyExists => {}
err => {
err.expect("to open key file");
}
};

Ok(())
}

0 comments on commit af45e14

Please sign in to comment.