diff --git a/src/cmd_pivecdh.rs b/src/cmd_pivecdh.rs index 140cc55..641de2d 100644 --- a/src/cmd_pivecdh.rs +++ b/src/cmd_pivecdh.rs @@ -27,6 +27,7 @@ impl Command for CommandImpl { .arg(Arg::with_name("epk").long("epk").takes_value(true).help("E-Public key")) .arg(Arg::with_name("public-key").long("public-key").takes_value(true).help("Public key")) .arg(Arg::with_name("public-key-file").long("public-key-file").takes_value(true).help("Public key")) + .arg(Arg::with_name("public-key-point-hex").long("public-key-point-hex").takes_value(true).help("Public key point hex")) .arg(Arg::with_name("json").long("json").help("JSON output")) } @@ -44,18 +45,29 @@ impl Command for CommandImpl { let mut json = BTreeMap::<&'_ str, String>::new(); if public { - let public_key_pem = sub_arg_matches.value_of("public-key").map(ToString::to_string) - .unwrap_or_else(|| match sub_arg_matches.value_of("public-key-file") { - None => failure_and_exit!("--public-key or --public-key-file must require one"), + let public_key_pem_opt = sub_arg_matches.value_of("public-key").map(ToString::to_string) + .or_else(|| match sub_arg_matches.value_of("public-key-file") { + None => None, Some(file) => match fs::read_to_string(file) { Err(e) => failure_and_exit!("Read from file: {}, failed: {}", file, e), - Ok(key) => key, + Ok(key) => Some(key), } }); - debugging!("Public key: {}", &public_key_pem); + if let Some(public_key_pem) = &public_key_pem_opt { + debugging!("Public key: {}", public_key_pem); + } - let public_key = opt_result!(public_key_pem.parse::(), "Parse public key failed: {}"); + let public_key; + if let Some(public_key_pem) = public_key_pem_opt { + public_key = opt_result!(public_key_pem.parse::(), "Parse public key failed: {}"); + } else { + let public_key_point_hex = sub_arg_matches.value_of("public-key-point-hex").unwrap_or_else(|| + failure_and_exit!("--public-key, --public-key-file or --public-key-point-hex must require one")); + let public_key_point_bytes = opt_result!(hex::decode(public_key_point_hex), "Parse public key point hex failed: {}"); + let encoded_point = opt_result!(EncodedPoint::from_bytes(&public_key_point_bytes), "Parse public key point failed: {}"); + public_key = PublicKey::from_encoded_point(&encoded_point).unwrap(); + }; let esk = EphemeralSecret::random(&mut OsRng); let epk = esk.public_key();