diff --git a/Cargo.lock b/Cargo.lock index c8cbc45..88b380a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -508,7 +508,7 @@ dependencies = [ [[package]] name = "card-cli" -version = "1.11.8" +version = "1.11.9" dependencies = [ "aes-gcm-stream", "authenticator 0.3.1", diff --git a/Cargo.toml b/Cargo.toml index 07db150..fd4084d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "card-cli" -version = "1.11.8" +version = "1.11.9" authors = ["Hatter Jiang "] edition = "2018" diff --git a/src/cmd_se_generate.rs b/src/cmd_se_generate.rs index 70209cb..3d7091c 100644 --- a/src/cmd_se_generate.rs +++ b/src/cmd_se_generate.rs @@ -2,8 +2,10 @@ use crate::pkiutil::bytes_to_pem; use crate::seutil; use crate::util::base64_encode; use clap::{App, Arg, ArgMatches, SubCommand}; +use p256::PublicKey; use rust_util::util_clap::{Command, CommandError}; use rust_util::util_msg; +use spki::DecodePublicKey; use std::collections::BTreeMap; pub struct CommandImpl; @@ -58,28 +60,44 @@ impl Command for CommandImpl { let (public_key_point, public_key_der, private_key) = seutil::generate_secure_enclave_p256_keypair(sign, require_bio)?; - - let public_key_point_hex = hex::encode(&public_key_point); - let public_key_pem = bytes_to_pem("PUBLIC KEY", &*public_key_der); - let key = format!( + let key_uri = format!( "key://{}:se/p256:{}:{}", host, iff!(sign, "signing", "key_agreement"), private_key, ); - if json_output { - let mut json = BTreeMap::<&'_ str, String>::new(); - json.insert("public_key_point", public_key_point_hex); - json.insert("public_key_pem", base64_encode(&*public_key_der)); - json.insert("key", key); - - println!("{}", serde_json::to_string_pretty(&json).unwrap()); - } else { - success!("Public key(point): {}", public_key_point_hex); - success!("Public key PEM: \n{}", public_key_pem); - success!("Key: {}", key); - } + print_se_key(json_output, &public_key_point, &public_key_der, &key_uri); Ok(None) } } + +pub fn print_se_key( + json_output: bool, + public_key_point: &[u8], + public_key_der: &[u8], + key_uri: &str, +) { + let public_key_point_hex = hex::encode(&public_key_point); + let public_key_pem = bytes_to_pem("PUBLIC KEY", &*public_key_der); + let public_key = PublicKey::from_public_key_pem(&public_key_pem).ok(); + let public_key_jwk = public_key.map(|key| key.to_jwk_string()); + if json_output { + let mut json = BTreeMap::<&'_ str, String>::new(); + json.insert("public_key_point", public_key_point_hex); + json.insert("public_key_pem", base64_encode(&*public_key_der)); + if let Some(public_key_jwk) = public_key_jwk { + json.insert("public_key_jwk", base64_encode(public_key_jwk)); + } + json.insert("key", key_uri.to_string()); + + println!("{}", serde_json::to_string_pretty(&json).unwrap()); + } else { + success!("Public key(point): {}", public_key_point_hex); + success!("Public key PEM: \n{}", public_key_pem); + if let Some(public_key_jwk) = public_key_jwk { + success!("Public key JWK: \n{}", &public_key_jwk); + } + success!("Key: {}", key_uri); + } +} diff --git a/src/cmd_se_recover.rs b/src/cmd_se_recover.rs index 9672f4f..12dbe2d 100644 --- a/src/cmd_se_recover.rs +++ b/src/cmd_se_recover.rs @@ -1,11 +1,9 @@ +use crate::cmd_se_generate::print_se_key; use crate::keyutil::{parse_key_uri, KeyUri, KeyUsage}; -use crate::pkiutil::bytes_to_pem; use crate::seutil; -use crate::util::base64_encode; use clap::{App, Arg, ArgMatches, SubCommand}; use rust_util::util_clap::{Command, CommandError}; use rust_util::util_msg; -use std::collections::BTreeMap; pub struct CommandImpl; @@ -31,14 +29,14 @@ impl Command for CommandImpl { if !seutil::is_support_se() { return simple_error!("Secure Enclave is NOT supported."); } - let key = sub_arg_matches.value_of("key").unwrap(); + let key_uri = sub_arg_matches.value_of("key").unwrap(); let json_output = sub_arg_matches.is_present("json"); if json_output { util_msg::set_logger_std_out(false); } - let KeyUri::SecureEnclaveKey(se_key_uri) = parse_key_uri(key)?; + let KeyUri::SecureEnclaveKey(se_key_uri) = parse_key_uri(key_uri)?; debugging!("Secure enclave key URI: {:?}", se_key_uri); let (public_key_point, public_key_der, _private_key) = @@ -47,20 +45,7 @@ impl Command for CommandImpl { se_key_uri.usage == KeyUsage::Singing, )?; - let public_key_point_hex = hex::encode(&public_key_point); - let public_key_pem = bytes_to_pem("PUBLIC KEY", &*public_key_der); - if json_output { - let mut json = BTreeMap::<&'_ str, String>::new(); - json.insert("public_key_point", public_key_point_hex); - json.insert("public_key_pem", base64_encode(&*public_key_der)); - json.insert("key", key.to_string()); - - println!("{}", serde_json::to_string_pretty(&json).unwrap()); - } else { - success!("Public key(point): {}", public_key_point_hex); - success!("Public key PEM: \n{}", public_key_pem); - success!("Key: {}", key); - } + print_se_key(json_output, &public_key_point, &public_key_der, &key_uri); Ok(None) }