diff --git a/Cargo.lock b/Cargo.lock index a52aec0..20de577 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -384,7 +384,7 @@ dependencies = [ [[package]] name = "card-cli" -version = "1.1.3" +version = "1.1.4" dependencies = [ "authenticator", "base64 0.13.0", diff --git a/Cargo.toml b/Cargo.toml index c7a84b9..60848d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "card-cli" -version = "1.1.3" +version = "1.1.4" authors = ["Hatter Jiang "] edition = "2018" diff --git a/src/cmd_pgp.rs b/src/cmd_pgp.rs index 432f730..92b5c80 100644 --- a/src/cmd_pgp.rs +++ b/src/cmd_pgp.rs @@ -2,17 +2,15 @@ use std::ops::Deref; use chrono::{DateTime, Local}; use clap::{App, Arg, ArgMatches, SubCommand}; -use openssl::bn::BigNum; -use openssl::rsa::Rsa; -use pem::Pem; use rust_util::util_clap::{Command, CommandError}; -use sequoia_openpgp::crypto::mpi::PublicKey; use sequoia_openpgp::Packet; use sequoia_openpgp::packet::{Body, Key, PKESK, SEIP, Signature}; use sequoia_openpgp::packet::signature::subpacket::{SubpacketTag, SubpacketValue}; use sequoia_openpgp::parse::{PacketParser, PacketParserResult}; use sequoia_openpgp::parse::Parse; +use crate::pkiutil::sequoia_openpgp_public_key_pem as public_key_pem; + pub struct CommandImpl; impl Command for CommandImpl { @@ -91,7 +89,8 @@ impl Command for CommandImpl { public_key4.push_str(&format!("\n\tCreation time {}", creation_time_str)); public_key4.push_str(&format!("\n\tPublic algo: {:?}", key4.pk_algo())); if show_detail { - if let Some(pubkey_pem) = public_key_pem(key4.mpis()) { + if let Some((pubkey_sha256, pubkey_pem)) = public_key_pem(key4.mpis()) { + public_key4.push_str(&format!("\n\tPublic key sha256: {}", hex::encode(pubkey_sha256))); public_key4.push_str(&format!("\n\tPublic key PEM: {}", pubkey_pem)); } } @@ -114,7 +113,8 @@ impl Command for CommandImpl { public_key4.push_str(&format!("\n\tCreation time {}", creation_time_str)); public_key4.push_str(&format!("\n\tPublic algo: {:?}", key4.pk_algo())); if show_detail { - if let Some(pub_key_pem) = public_key_pem(key4.mpis()) { + if let Some((pubkey_sha256, pub_key_pem)) = public_key_pem(key4.mpis()) { + public_key4.push_str(&format!("\n\tPublic key sha256: {}", hex::encode(pubkey_sha256))); public_key4.push_str(&format!("\n\tPublic key PEM: {}", pub_key_pem)); } } @@ -200,23 +200,3 @@ impl Command for CommandImpl { Ok(None) } } - -fn public_key_pem(public_key: &PublicKey) -> Option { - match public_key { - PublicKey::RSA { e, n } => { - let rsa_pub_key = Rsa::from_public_components( - BigNum::from_slice(n.value()).unwrap(), - BigNum::from_slice(e.value()).unwrap(), - ); - let pub_key_pem_obj = Pem { - tag: String::from("PUBLIC KEY"), - contents: rsa_pub_key.unwrap().public_key_to_der().unwrap(), - }; - Some(pem::encode(&pub_key_pem_obj)) - } - _ => { - warning!("Not RSA public key: {:?}", public_key); - None - } - } -} diff --git a/src/cmd_pgpcardlist.rs b/src/cmd_pgpcardlist.rs index 202ef3a..90328ef 100644 --- a/src/cmd_pgpcardlist.rs +++ b/src/cmd_pgpcardlist.rs @@ -2,14 +2,10 @@ use std::collections::BTreeMap; use clap::{App, Arg, ArgMatches, SubCommand}; use openpgp_card::{KeyType, OpenPgp}; -use openpgp_card::crypto_data::PublicKeyMaterial; use openpgp_card_pcsc::PcscBackend; -use openssl::bn::BigNum; -use openssl::rsa::Rsa; -use pem::Pem; use rust_util::util_clap::{Command, CommandError}; -use crate::digest::sha256_bytes; +use crate::pkiutil::openpgp_card_public_key_pem as public_key_pem; pub struct CommandImpl; @@ -176,25 +172,3 @@ impl Command for CommandImpl { Ok(None) } } - -fn public_key_pem(public_key: &PublicKeyMaterial) -> Option<(Vec, String)> { - match public_key { - PublicKeyMaterial::R(rsa_pub) => { - let rsa_pub_key = Rsa::from_public_components( - BigNum::from_slice(rsa_pub.n()).unwrap(), - BigNum::from_slice(rsa_pub.v()).unwrap(), - ); - let rsa_pub_key_bytes = rsa_pub_key.unwrap().public_key_to_der().unwrap(); - let rsa_pub_key_bytes_sha256 = sha256_bytes(&rsa_pub_key_bytes); - let pub_key_pem_obj = Pem { - tag: String::from("PUBLIC KEY"), - contents: rsa_pub_key_bytes, - }; - Some((rsa_pub_key_bytes_sha256, pem::encode(&pub_key_pem_obj))) - } - _ => { - warning!("Not RSA public key: {:?}", public_key); - None - } - } -} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index a646211..85cf373 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,10 +6,11 @@ use rust_util::util_clap::{Command, CommandError}; mod fido; mod digest; +mod pkiutil; +mod pgpcardutil; mod cmd_u2fregister; mod cmd_u2fsign; mod cmd_pgp; -mod pgpcardutil; mod cmd_pgpcardadmin; mod cmd_pgpcardlist; mod cmd_pgpcardsign; diff --git a/src/pkiutil.rs b/src/pkiutil.rs new file mode 100644 index 0000000..57bf25f --- /dev/null +++ b/src/pkiutil.rs @@ -0,0 +1,51 @@ +use openssl::bn::BigNum; +use openssl::rsa::Rsa; +use pem::Pem; +use sequoia_openpgp::crypto::mpi::PublicKey; +use openpgp_card::crypto_data::PublicKeyMaterial; + +use crate::digest::sha256_bytes; + +pub fn sequoia_openpgp_public_key_pem(public_key: &PublicKey) -> Option<(Vec, String)> { + match public_key { + PublicKey::RSA { e, n } => { + let rsa_pub_key = Rsa::from_public_components( + BigNum::from_slice(n.value()).unwrap(), + BigNum::from_slice(e.value()).unwrap(), + ); + let rsa_pub_key_bytes = rsa_pub_key.unwrap().public_key_to_der().unwrap(); + let rsa_pub_key_bytes_sha256 = sha256_bytes(&rsa_pub_key_bytes); + let pub_key_pem_obj = Pem { + tag: String::from("PUBLIC KEY"), + contents: rsa_pub_key_bytes, + }; + Some((rsa_pub_key_bytes_sha256, pem::encode(&pub_key_pem_obj))) + } + _ => { + warning!("Not RSA public key: {:?}", public_key); + None + } + } +} + +pub fn openpgp_card_public_key_pem(public_key: &PublicKeyMaterial) -> Option<(Vec, String)> { + match public_key { + PublicKeyMaterial::R(rsa_pub) => { + let rsa_pub_key = Rsa::from_public_components( + BigNum::from_slice(rsa_pub.n()).unwrap(), + BigNum::from_slice(rsa_pub.v()).unwrap(), + ); + let rsa_pub_key_bytes = rsa_pub_key.unwrap().public_key_to_der().unwrap(); + let rsa_pub_key_bytes_sha256 = sha256_bytes(&rsa_pub_key_bytes); + let pub_key_pem_obj = Pem { + tag: String::from("PUBLIC KEY"), + contents: rsa_pub_key_bytes, + }; + Some((rsa_pub_key_bytes_sha256, pem::encode(&pub_key_pem_obj))) + } + _ => { + warning!("Not RSA public key: {:?}", public_key); + None + } + } +}