v1.1.0, update openpgp-card versions

This commit is contained in:
2022-04-03 12:57:05 +08:00
parent e4c46f4c48
commit e34d02e622
7 changed files with 651 additions and 153 deletions

View File

@@ -1,5 +1,6 @@
use clap::{App, Arg, ArgMatches, SubCommand};
use openpgp_card::Sex;
use openpgp_card::{OpenPgp};
use openpgp_card::card_do::{Lang, Sex};
use rust_util::util_clap::{Command, CommandError};
pub struct CommandImpl;
@@ -22,25 +23,30 @@ impl Command for CommandImpl {
let pin = opt_value_result!(pin_opt, "Pass must be assigned");
if pin.len() < 8 { return simple_error!("Admin pin length:{}, must >= 8!", pin.len()); }
let card_admin = crate::pgpcardutil::get_card_admin(pin)?;
let mut card = crate::pgpcardutil::get_card()?;
let mut pgp = OpenPgp::new(&mut card);
let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}");
opt_result!(trans.verify_pw3(pin.as_ref()), "Admin pin verify failed: {}");
success!("Admin pin verify success!");
if let Some(name) = sub_arg_matches.value_of("name") {
information!("Set name to: {}", name);
let response = opt_result!(card_admin.set_name(name), "Set name failed: {}");
success!("Set name success: {:?}", response);
opt_result!(trans.set_name(name.as_bytes()), "Set name failed: {}");
success!("Set name success");
}
if let Some(url) = sub_arg_matches.value_of("url") {
information!("Set URL to: {}", url);
let response = opt_result!(card_admin.set_url(url), "Set URL failed: {}");
success!("Set URL success: {:?}", response);
opt_result!(trans.set_url(url.as_bytes()), "Set URL failed: {}");
success!("Set URL success");
}
if let Some(lang) = sub_arg_matches.value_of("lang") {
information!("Set lang to: {}", lang);
let response = opt_result!(card_admin.set_lang(lang), "Set lang failed: {}");
success!("Set lang success: {:?}", response);
let lang_bytes = lang.as_bytes();
opt_result!(trans.set_lang(&vec![Lang::Value([lang_bytes[0], lang_bytes[1]])]), "Set lang failed: {}");
success!("Set lang success");
}
if let Some(sex) = sub_arg_matches.value_of("sex") {
@@ -55,8 +61,8 @@ impl Command for CommandImpl {
};
if let Some(s) = s {
information!("Set sex to: {:?}", s);
let response = opt_result!(card_admin.set_sex(s), "Set sex failed: {}");
success!("Set sex success: {:?}", response);
opt_result!(trans.set_sex(s), "Set lang failed: {}");
success!("Set sex success");
}
}

View File

@@ -1,7 +1,8 @@
use std::collections::BTreeMap;
use clap::{App, Arg, ArgMatches, SubCommand};
use openpgp_card::DecryptMe;
use openpgp_card::OpenPgp;
use openpgp_card::crypto_data::Cryptogram;
use rust_util::util_clap::{Command, CommandError};
pub struct CommandImpl;
@@ -37,8 +38,14 @@ impl Command for CommandImpl {
return simple_error!("cipher or cipher-base64 must assign one");
};
let user = crate::pgpcardutil::get_card_user_sw1_82(pin)?;
let text = user.decrypt(DecryptMe::RSA(&cipher_bytes))?;
let mut card = crate::pgpcardutil::get_card()?;
let mut pgp = OpenPgp::new(&mut card);
let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}");
opt_result!(trans.verify_pw1_user(pin.as_ref()), "User pin verify failed: {}");
success!("User pin verify success!");
let text = trans.decipher(Cryptogram::RSA(&cipher_bytes))?;
success!("Clear text HEX: {}", hex::encode(&text));
success!("Clear text base64: {}", base64::encode(&text));
success!("Clear text UTF-8: {}", String::from_utf8_lossy(&text));

View File

@@ -1,7 +1,8 @@
use std::collections::BTreeMap;
use clap::{App, Arg, ArgMatches, SubCommand};
use openpgp_card::{KeyType, OpenPGPCard};
use openpgp_card::{KeyType, OpenPgp};
use openpgp_card_pcsc::PcscBackend;
use rust_util::util_clap::{Command, CommandError};
pub struct CommandImpl;
@@ -19,50 +20,102 @@ impl Command for CommandImpl {
if json_output { rust_util::util_msg::set_logger_std_out(false); }
let mut json = BTreeMap::new();
let cards = opt_result!(OpenPGPCard::list_cards(), "Failed to list OpenPGP cards: {}");
let cards = opt_result!(PcscBackend::cards(None), "Failed to list OpenPGP cards: {}");
information!("Found {} card(s)", cards.len());
for (i, card) in cards.iter().enumerate() {
success!("Found card #{}: {:?}", i, card.get_aid());
debugging!("Historical: {:?}", card.get_historical());
debugging!("Extended length information{:?}", card.get_extended_length_information());
debugging!("Extended capabilities{:?}", card.get_extended_capabilities());
debugging!("Security support template{:?}", card.get_security_support_template());
if let Ok(url) = card.get_url() {
information!("URL: {}", iff!(url.is_empty(), "<empty>", &url));
}
if let Ok(card_holder) = card.get_cardholder_related_data() {
information!("Card holder: {:?}", card_holder);
}
if let Ok(supported_algo) = card.list_supported_algo() {
information!("Supported algo: {:?}", supported_algo);
}
if let Ok(fingerprints) = card.get_fingerprints() {
if let Some(a) = fingerprints.authentication() {
if let Ok(algo) = card.get_algorithm_attributes(KeyType::Authentication) {
information!("Authentication algo: {:?}", algo);
}
information!("Authentication fingerprint: {}", a);
if json_output {
json.insert("authentication_fingerprint", a.to_string());
for (i, mut card) in cards.into_iter().enumerate() {
let mut pgp = OpenPgp::new(&mut card);
let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}");
if let Ok(application_related_data) = trans.application_related_data() {
success!("Found card #{}: {:?}", i, application_related_data.application_id());
debugging!("Historical: {:?}", application_related_data.historical_bytes());
debugging!("Extended length information: {:?}", application_related_data.extended_length_information());
debugging!("Extended capabilities: {:?}", application_related_data.extended_capabilities());
debugging!("Key generation times: {:?}", application_related_data.key_generation_times());
debugging!("PW status bytes: {:?}", application_related_data.pw_status_bytes());
debugging!(r#"Algorithm attributes:
- Signing: {:?}
- Decryption: {:?}
- Authentication: {:?}
- Attestation: {:?}"#,
application_related_data.algorithm_attributes(KeyType::Signing),
application_related_data.algorithm_attributes(KeyType::Decryption),
application_related_data.algorithm_attributes(KeyType::Authentication),
application_related_data.algorithm_attributes(KeyType::Attestation));
debugging!("Fingerprints: {:?}", application_related_data.fingerprints());
if json_output {
if let Ok(application_identifier) = application_related_data.application_id() {
json.insert("application", format!("{}", application_identifier.application()));
json.insert("version", format!("{}", application_identifier.version()));
json.insert("serial", format!("{}", application_identifier.serial()));
json.insert("manufacturer", format!("{}", application_identifier.manufacturer()));
json.insert("ident", application_identifier.ident());
}
}
if let Some(d) = fingerprints.decryption() {
if let Ok(algo) = card.get_algorithm_attributes(KeyType::Decryption) {
information!("Encryption algo: {:?}", algo);
}
information!("Encryption fingerprint: {}", d);
if json_output {
json.insert("encryption_fingerprint", d.to_string());
}
}
information!("Feature pin pad, verify: {}, modify: {}",
trans.feature_pinpad_verify(), trans.feature_pinpad_modify());
if json_output {
json.insert("feature_pinpad_verify", format!("{}", trans.feature_pinpad_verify()));
json.insert("feature_pinpad_modify", format!("{}", trans.feature_pinpad_modify()));
}
if let Ok(security_supported_template) = trans.security_support_template() {
debugging!("Security support template: {:?}", security_supported_template);
}
if let Ok(cardholder_certificate) = trans.cardholder_certificate() {
debugging!("Cardholder certificate: {:?}", cardholder_certificate);
}
// debugging!("Security support template: {:?}", trans.security_support_template());
// debugging!("Security support template: {:?}", trans.cardholder_certificate());
if let Ok(url) = trans.url() {
information!("URL: {}", iff!(url.is_empty(), "<empty>".to_string(), String::from_utf8_lossy(&url).to_string()));
}
if let Ok(card_holder) = trans.cardholder_related_data() {
debugging!("Card holder: {:?}", card_holder);
let mut card_holder_outputs = vec![];
if let Some(name) = card_holder.name() {
card_holder_outputs.push(format!("name: {}", String::from_utf8_lossy(name)));
}
if let Some(s) = fingerprints.signature() {
if let Ok(algo) = card.get_algorithm_attributes(KeyType::Signing) {
information!("Signature algo: {:?}", algo);
if let Some(lang) = card_holder.lang() {
card_holder_outputs.push(format!(
"lang: {}",
lang.iter().map(|l| l.to_string()).collect::<Vec<String>>().join(" ")));
}
if let Some(sex) = card_holder.sex() {
card_holder_outputs.push(format!("sex: {:?}", sex));
}
information!("Card holder, {}",
iff!(card_holder_outputs.is_empty(), "".to_string(), card_holder_outputs.join(", ")));
}
if let Ok(application_related_data) = trans.application_related_data() {
if let Ok(fingerprints) = application_related_data.fingerprints() {
if let Some(a) = fingerprints.authentication() {
if let Ok(algo) = application_related_data.algorithm_attributes(KeyType::Authentication) {
information!("Authentication algo: {:?}", algo);
}
information!("Authentication fingerprint: {}", a);
if json_output {
json.insert("authentication_fingerprint", a.to_string());
}
}
information!("Signature fingerprint: {}", s);
if json_output {
json.insert("signature_fingerprint", s.to_string());
if let Some(d) = fingerprints.decryption() {
if let Ok(algo) = application_related_data.algorithm_attributes(KeyType::Decryption) {
information!("Encryption algo: {:?}", algo);
}
information!("Encryption fingerprint: {}", d);
if json_output {
json.insert("encryption_fingerprint", d.to_string());
}
}
if let Some(s) = fingerprints.signature() {
if let Ok(algo) = application_related_data.algorithm_attributes(KeyType::Signing) {
information!("Signature algo: {:?}", algo);
}
information!("Signature fingerprint: {}", s);
if json_output {
json.insert("signature_fingerprint", s.to_string());
}
}
}
}

View File

@@ -1,12 +1,11 @@
use std::collections::BTreeMap;
use clap::{App, Arg, ArgMatches, SubCommand};
use openpgp_card::Hash;
use openpgp_card::crypto_data::Hash;
use openpgp_card::OpenPgp;
use rust_util::util_clap::{Command, CommandError};
use rust_util::XResult;
use crate::pgpcardutil;
pub struct CommandImpl;
impl Command for CommandImpl {
@@ -37,13 +36,19 @@ impl Command for CommandImpl {
if sha256.is_none() && sha384.is_none() && sha512.is_none() {
return simple_error!("SHA256, SHA384 or SHA512 must assign at least one");
}
let user = opt_result!(pgpcardutil::get_card_user_sw1_81(pin), "Verify user pin failed: {}");
let mut card = crate::pgpcardutil::get_card()?;
let mut pgp = OpenPgp::new(&mut card);
let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}");
opt_result!(trans.verify_pw1_sign(pin.as_ref()), "User sign pin verify failed: {}");
success!("User sign pin verify success!");
let mut json = BTreeMap::new();
if let Some(sha256) = sha256 {
let sha256_hex = opt_result!(hex::decode(sha256.trim()), "Decode sha256 failed: {}");
let sha256_hex = copy_sha256(&sha256_hex)?;
let sig = user.signature_for_hash(Hash::SHA256(sha256_hex))?;
let sig = trans.signature_for_hash(Hash::SHA256(sha256_hex))?;
success!("SHA256 signature HEX: {}", hex::encode(&sig));
success!("SHA256 signature base64: {}", base64::encode(&sig));
if json_output {
@@ -56,7 +61,7 @@ impl Command for CommandImpl {
if let Some(sha384) = sha384 {
let sha384_hex = opt_result!(hex::decode(sha384.trim()), "Decode sha384 failed: {}");
let sha384_hex = copy_sha384(&sha384_hex)?;
let sig = user.signature_for_hash(Hash::SHA384(sha384_hex))?;
let sig = trans.signature_for_hash(Hash::SHA384(sha384_hex))?;
success!("SHA384 signature HEX: {}", hex::encode(&sig));
success!("SHA384 signature base64: {}", base64::encode(&sig));
if json_output {
@@ -69,7 +74,7 @@ impl Command for CommandImpl {
if let Some(sha512) = sha512 {
let sha512_hex = opt_result!(hex::decode(sha512.trim()), "Decode sha512 failed: {}");
let sha512_hex = copy_sha512(&sha512_hex)?;
let sig = user.signature_for_hash(Hash::SHA512(sha512_hex))?;
let sig = trans.signature_for_hash(Hash::SHA512(sha512_hex))?;
success!("SHA512 signature HEX: {}", hex::encode(&sig));
success!("SHA512 signature base64: {}", base64::encode(&sig));
if json_output {

View File

@@ -1,47 +1,13 @@
use openpgp_card::{OpenPGPCard, OpenPGPCardAdmin, OpenPGPCardUser};
use openpgp_card_pcsc::PcscBackend;
use rust_util::XResult;
pub fn get_card_user_sw1_81(pin: &str) -> XResult<OpenPGPCardUser> {
// pw1_81 for signature
// openssl dgst -sha256 -verify aa -signature sig LICENSE
get_card_user(|open_pgp_card: OpenPGPCard| open_pgp_card.verify_pw1_81(pin), "pw1_81")
}
pub fn get_card_user_sw1_82(pin: &str) -> XResult<OpenPGPCardUser> {
// pw1_82 for decrypt
// PKCSv1.5
get_card_user(|open_pgp_card: OpenPGPCard| open_pgp_card.verify_pw1_82(pin), "pw1_82")
}
pub fn get_card_admin(pin: &str) -> XResult<OpenPGPCardAdmin> {
let card = get_card()?;
match card.verify_pw3(pin) {
Result::Ok(admin) => Ok(admin),
Result::Err(_) => simple_error!("Verify pw3 OpenPGP card failed"),
}
}
fn get_card_user(process_fn: impl Fn(OpenPGPCard) -> Result<OpenPGPCardUser, OpenPGPCard>, tag: &str) -> XResult<OpenPGPCardUser> {
let card = get_card()?;
match process_fn(card) {
Result::Ok(user) => Ok(user),
Result::Err(_) => simple_error!("Verify {} OpenPGP card failed", tag),
}
}
fn get_card() -> XResult<OpenPGPCard> {
let card_list = opt_result!(OpenPGPCard::list_cards(),
"Read OpenPGP card list failed: {}");
pub fn get_card() -> XResult<PcscBackend> {
let card_list = opt_result!(PcscBackend::cards(None), "Read OpenPGP card list failed: {}");
if card_list.is_empty() {
return simple_error!("Cannot find any card");
}
if card_list.len() > 1 {
warning!("Find {} OpenPGP cards, will use first card", card_list.len());
}
let card = card_list.into_iter().next();
card.as_ref().map(|card|
card.get_aid().map(|card|
success!("Found card: {:?}", card)));
Ok(opt_value_result!(card, "Get first card failed"))
Ok(opt_value_result!(card_list.into_iter().next(), "SHOULD NOT HAPPEN, CANNOT FIND ANY CARD"))
}