diff --git a/src/cli.rs b/src/cli.rs index c7eab10..51533e2 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -36,7 +36,11 @@ pub struct KeyPairCmd { #[clap(long, parse(from_os_str))] pub from_private_key_file: Option, /// Read the private key raw bytes directly, with no hex decoding - #[clap(long, requires("from-private-key-file"))] + #[clap( + long, + requires("from-private-key-file"), + conflicts_with("from-private-key") + )] pub from_raw_private_key: bool, /// Only output the public part of the key pair #[clap(long, conflicts_with("only-private-key"))] @@ -51,8 +55,8 @@ pub struct KeyPairCmd { #[clap(long, requires("only-private-key"))] pub raw_private_key_output: bool, /// Key algorithm: ed25519 (default) or secp256r1 - #[clap(long, default_value_t)] - pub key_algorithm: Algorithm, + #[clap(long)] + pub key_algorithm: Option, } /// Generate a biscuit from a private key and an authority block @@ -84,8 +88,8 @@ pub struct Generate { #[clap(long, conflicts_with = "private-key", requires = "private-key-file")] pub raw_private_key: bool, /// Key algorithm: ed25519 (default) or secp256r1 - #[clap(long, default_value_t)] - pub key_algorithm: Algorithm, + #[clap(long)] + pub key_algorithm: Option, /// The optional context string attached to the authority block #[clap(long)] pub context: Option, @@ -150,8 +154,8 @@ pub struct Inspect { #[clap(long, requires("public-key-file"), conflicts_with("public-key"))] pub raw_public_key: bool, /// Key algorithm: ed25519 (default) or secp256r1 - #[clap(long, default_value_t)] - pub key_algorithm: Algorithm, + #[clap(long)] + pub key_algorithm: Option, #[clap(flatten)] pub run_limits_args: common_args::RunLimitArgs, #[clap(flatten)] @@ -228,8 +232,8 @@ pub struct GenerateThirdPartyBlock { #[clap(long, conflicts_with = "private-key", requires = "private-key-file")] pub raw_private_key: bool, /// Key algorithm: ed25519 (default) or secp256r1 - #[clap(long, default_value_t)] - pub key_algorithm: Algorithm, + #[clap(long)] + pub key_algorithm: Option, /// Output the block raw bytes directly, with no base64 encoding #[clap(long)] pub raw_output: bool, diff --git a/src/input.rs b/src/input.rs index b6e18d7..49c7dc2 100644 --- a/src/input.rs +++ b/src/input.rs @@ -270,44 +270,84 @@ fn read_authorizer_from_snapshot( Ok(builder) } -pub fn read_private_key_from(from: &KeyBytes, alg: Algorithm) -> Result { - let bytes = match from { - KeyBytes::FromStdin(KeyFormat::RawBytes) => read_stdin_bytes()?, +pub fn read_private_key_from(from: &KeyBytes, alg: &Option) -> Result { + let key = match from { + KeyBytes::FromStdin(KeyFormat::RawBytes) => { + let bytes = read_stdin_bytes()?; + PrivateKey::from_bytes(&bytes, alg.unwrap_or_default()) + .map_err(|e| ParseError("private key".to_string(), format!("{}", &e)))? + } KeyBytes::FromStdin(KeyFormat::HexKey) => { - hex::decode(read_stdin_string("hex-encoded private key")?)? + let str = read_stdin_string("hex-encoded private key")?; + str.parse() + .map_err(|e| ParseError("private key".to_string(), format!("{}", &e)))? } KeyBytes::FromFile(KeyFormat::RawBytes, path) => { - fs::read(path).map_err(|_| FileNotFound(path.clone()))? + let bytes = fs::read(path).map_err(|_| FileNotFound(path.clone()))?; + PrivateKey::from_bytes(&bytes, alg.unwrap_or_default()) + .map_err(|e| ParseError("private key".to_string(), format!("{}", &e)))? } - KeyBytes::FromFile(KeyFormat::HexKey, path) => hex::decode( - fs::read_to_string(path) - .map_err(|_| FileNotFound(path.clone()))? - .trim(), - )?, - KeyBytes::HexString(str) => hex::decode(str)?, + KeyBytes::FromFile(KeyFormat::HexKey, path) => { + let str = fs::read_to_string(path).map_err(|_| FileNotFound(path.clone()))?; + str.parse() + .map_err(|e| ParseError("private key".to_string(), format!("{}", &e)))? + } + KeyBytes::HexString(str) => str + .parse() + .map_err(|e| ParseError("private key".to_string(), format!("{}", &e)))?, }; - PrivateKey::from_bytes(&bytes, alg) - .map_err(|e| ParseError("private key".to_string(), format!("{}", &e)).into()) + let key_alg = key.algorithm().into(); + + if let Some(a) = alg { + if *a != key_alg { + Err(std::io::Error::other(format!( + "Inconsistent algorithm: key algorithm is {}, expected algorithm is {}", + key_alg, a + )))? + } + } + + Ok(key) } -pub fn read_public_key_from(from: &KeyBytes, alg: Algorithm) -> Result { - let bytes = match from { - KeyBytes::FromStdin(KeyFormat::RawBytes) => read_stdin_bytes()?, +pub fn read_public_key_from(from: &KeyBytes, alg: &Option) -> Result { + let key = match from { + KeyBytes::FromStdin(KeyFormat::RawBytes) => { + let bytes = read_stdin_bytes()?; + PublicKey::from_bytes(&bytes, alg.unwrap_or_default()) + .map_err(|e| ParseError("public key".to_string(), format!("{}", &e)))? + } KeyBytes::FromStdin(KeyFormat::HexKey) => { - hex::decode(read_stdin_string("hex-encoded public key")?)? + let str = read_stdin_string("hex-encoded public key")?; + str.parse() + .map_err(|e| ParseError("public key".to_string(), format!("{}", &e)))? } KeyBytes::FromFile(KeyFormat::RawBytes, path) => { - fs::read(path).map_err(|_| FileNotFound(path.clone()))? + let bytes = fs::read(path).map_err(|_| FileNotFound(path.clone()))?; + PublicKey::from_bytes(&bytes, alg.unwrap_or_default()) + .map_err(|e| ParseError("public key".to_string(), format!("{}", &e)))? } - KeyBytes::FromFile(KeyFormat::HexKey, path) => hex::decode( - fs::read_to_string(path) - .map_err(|_| FileNotFound(path.clone()))? - .trim(), - )?, - KeyBytes::HexString(str) => hex::decode(str)?, + KeyBytes::FromFile(KeyFormat::HexKey, path) => { + let str = fs::read_to_string(path).map_err(|_| FileNotFound(path.clone()))?; + str.parse() + .map_err(|e| ParseError("public key".to_string(), format!("{}", &e)))? + } + KeyBytes::HexString(str) => str + .parse() + .map_err(|e| ParseError("public key".to_string(), format!("{}", &e)))?, }; - PublicKey::from_bytes(&bytes, alg) - .map_err(|e| ParseError("public key".to_string(), format!("{}", &e)).into()) + let key_alg = key.algorithm().into(); + + if let Some(a) = alg { + if *a != key_alg { + Err(std::io::Error::other(format!( + "Inconsistent algorithm: key algorithm is {}, expected algorithm is {}", + key_alg, a + )))? + } + } + + Ok(key) } pub fn read_biscuit_from(from: &BiscuitBytes) -> Result { diff --git a/src/inspect.rs b/src/inspect.rs index bcd8c4e..8871817 100644 --- a/src/inspect.rs +++ b/src/inspect.rs @@ -487,7 +487,7 @@ pub fn handle_inspect_inner(inspect: &Inspect) -> Result { let query_result; if let Some(key_from) = public_key_from { - let key = read_public_key_from(&key_from, inspect.key_algorithm)?; + let key = read_public_key_from(&key_from, &inspect.key_algorithm)?; let sig_result = biscuit.verify(key); signatures_check = Some(sig_result.is_ok()); diff --git a/src/main.rs b/src/main.rs index 8d9daac..a25aa6d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,7 +62,7 @@ fn handle_keypair(key_pair_cmd: &KeyPairCmd) -> Result<()> { }; let private_key: Option = if let Some(f) = private_key_from { - Some(read_private_key_from(f, key_pair_cmd.key_algorithm)?) + Some(read_private_key_from(f, &key_pair_cmd.key_algorithm)?) } else { None }; @@ -70,7 +70,7 @@ fn handle_keypair(key_pair_cmd: &KeyPairCmd) -> Result<()> { let key_pair = if let Some(private) = private_key { KeyPair::from(&private) } else { - KeyPair::new_with_algorithm(key_pair_cmd.key_algorithm) + KeyPair::new_with_algorithm(key_pair_cmd.key_algorithm.unwrap_or_default()) }; match ( @@ -85,23 +85,20 @@ fn handle_keypair(key_pair_cmd: &KeyPairCmd) -> Result<()> { } else { println!("Generating a new random keypair"); } - println!( - "Private key: {}", - hex::encode(key_pair.private().to_bytes()) - ); - println!("Public key: {}", hex::encode(key_pair.public().to_bytes())); + println!("Private key: {}", key_pair.private().to_prefixed_string()); + println!("Public key: {}", key_pair.public()); } (true, true, false, false) => { let _ = io::stdout().write_all(&key_pair.private().to_bytes()); } (true, false, false, false) => { - println!("{}", hex::encode(key_pair.private().to_bytes())); + println!("{}", key_pair.private().to_prefixed_string()); } (false, false, true, true) => { let _ = io::stdout().write_all(&key_pair.public().to_bytes()); } (false, false, true, false) => { - println!("{}", hex::encode(key_pair.public().to_bytes())); + println!("{}", key_pair.public()); } // the other combinations are prevented by clap _ => unreachable!(), @@ -128,7 +125,7 @@ fn handle_generate(generate: &Generate) -> Result<()> { // the other combinations are prevented by clap _ => unreachable!(), }, - generate.key_algorithm, + &generate.key_algorithm, ); let root = KeyPair::from(&private_key?); @@ -284,7 +281,7 @@ fn handle_generate_third_party_block( // the other combinations are prevented by clap _ => unreachable!(), }, - generate_third_party_block.key_algorithm, + &generate_third_party_block.key_algorithm, ); let request = read_request_from(&request_from)?;