feat: v1.1.5, piv display public key pem
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -384,7 +384,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "card-cli"
|
name = "card-cli"
|
||||||
version = "1.1.4"
|
version = "1.1.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"authenticator",
|
"authenticator",
|
||||||
"base64 0.13.0",
|
"base64 0.13.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "card-cli"
|
name = "card-cli"
|
||||||
version = "1.1.4"
|
version = "1.1.5"
|
||||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ impl Command for CommandImpl {
|
|||||||
|
|
||||||
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
|
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
|
||||||
let detail_output = sub_arg_matches.is_present("detail");
|
let detail_output = sub_arg_matches.is_present("detail");
|
||||||
|
let show_config = sub_arg_matches.is_present("show-config");
|
||||||
|
|
||||||
let mut yk = opt_result!(YubiKey::open(), "YubiKey not found: {}");
|
let mut yk = opt_result!(YubiKey::open(), "YubiKey not found: {}");
|
||||||
success!("Name: {}", yk.name());
|
success!("Name: {}", yk.name());
|
||||||
information!("Version: {}", yk.version());
|
information!("Version: {}", yk.version());
|
||||||
@@ -42,7 +44,7 @@ impl Command for CommandImpl {
|
|||||||
Ok(pin_retries) => information!("PIN retries: {}",pin_retries),
|
Ok(pin_retries) => information!("PIN retries: {}",pin_retries),
|
||||||
Err(e) => warning!("PIN retries: <none> {}", e),
|
Err(e) => warning!("PIN retries: <none> {}", e),
|
||||||
}
|
}
|
||||||
if sub_arg_matches.is_present("show-config") {
|
if show_config {
|
||||||
let config = yk.config();
|
let config = yk.config();
|
||||||
information!("Config: {:#?}", config);
|
information!("Config: {:#?}", config);
|
||||||
}
|
}
|
||||||
@@ -51,7 +53,7 @@ impl Command for CommandImpl {
|
|||||||
Ok(keys) => {
|
Ok(keys) => {
|
||||||
information!("Found {} PIV keys", keys.len());
|
information!("Found {} PIV keys", keys.len());
|
||||||
if detail_output {
|
if detail_output {
|
||||||
keys.iter().for_each(|k| information!("Found key: {:?}", k));
|
keys.iter().for_each(|k| debugging!("Found key: {:?}", k));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => failure!("Get PIV keys failed: {}", e)
|
Err(e) => failure!("Get PIV keys failed: {}", e)
|
||||||
@@ -73,14 +75,14 @@ fn print_cert_info(yubikey: &mut YubiKey, slot: SlotId, detail_output: bool) ->
|
|||||||
return simple_error!("error reading certificate in slot {:?}: {}", slot, e);
|
return simple_error!("error reading certificate in slot {:?}: {}", slot, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let buf = cert.into_buffer();
|
let buf = cert.as_ref().clone();
|
||||||
|
|
||||||
if !buf.is_empty() {
|
if !buf.is_empty() {
|
||||||
information!("{}", "-".repeat(88));
|
information!("{}", "-".repeat(88));
|
||||||
let fingerprint_sha256 = Sha256::digest(&*buf);
|
let certificate_fingerprint_sha256 = Sha256::digest(buf);
|
||||||
|
|
||||||
let slot_id: u8 = slot.into();
|
let slot_id: u8 = slot.into();
|
||||||
success!("Slot: {:?}, id: {:x}", slot, slot_id);
|
success!("Slot: {:?}, id: {:x}, algorithm: {:?}", slot, slot_id, cert.subject_pki().algorithm());
|
||||||
|
|
||||||
let cert_pem_obj = Pem {
|
let cert_pem_obj = Pem {
|
||||||
tag: String::from("CERTIFICATE"),
|
tag: String::from("CERTIFICATE"),
|
||||||
@@ -96,12 +98,26 @@ fn print_cert_info(yubikey: &mut YubiKey, slot: SlotId, detail_output: bool) ->
|
|||||||
|
|
||||||
match parse_x509_certificate(&buf) {
|
match parse_x509_certificate(&buf) {
|
||||||
Ok((_rem, cert)) => {
|
Ok((_rem, cert)) => {
|
||||||
success!("Algorithm: {}", cert.tbs_certificate.subject_pki.algorithm.algorithm);
|
information!("Algorithm: {}", cert.tbs_certificate.subject_pki.algorithm.algorithm);
|
||||||
|
|
||||||
success!("Subject: {}", cert.tbs_certificate.subject);
|
let public_key_fingerprint_sha256 = Sha256::digest(cert.tbs_certificate.subject_pki.raw);
|
||||||
success!("Issuer: {}", cert.tbs_certificate.issuer);
|
let cert_public_key_pem_obj = Pem {
|
||||||
success!("Fingerprint(SHA256): {}", hex::encode(fingerprint_sha256));
|
tag: String::from("PUBLIC KEY"),
|
||||||
success!("Not Before: {}", cert.tbs_certificate.validity.not_before.to_rfc2822());
|
contents: cert.tbs_certificate.subject_pki.raw.to_vec(),
|
||||||
|
};
|
||||||
|
if detail_output {
|
||||||
|
information!("{}", pem::encode(&cert_public_key_pem_obj).trim());
|
||||||
|
} else {
|
||||||
|
rust_util::util_msg::when(MessageType::DEBUG, || {
|
||||||
|
debugging!("{}", pem::encode(&cert_pem_obj).trim());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
information!("Subject: {}", cert.tbs_certificate.subject);
|
||||||
|
information!("Issuer: {}", cert.tbs_certificate.issuer);
|
||||||
|
information!("Certificate fingerprint(SHA256): {}", hex::encode(certificate_fingerprint_sha256));
|
||||||
|
information!("Public key fingerprint(SHA256): {}", hex::encode(public_key_fingerprint_sha256));
|
||||||
|
information!("Not Before: {}", cert.tbs_certificate.validity.not_before.to_rfc2822());
|
||||||
|
|
||||||
let mut not_after_desc = String::new();
|
let mut not_after_desc = String::new();
|
||||||
let not_after_timestamp = cert.tbs_certificate.validity.not_after.timestamp();
|
let not_after_timestamp = cert.tbs_certificate.validity.not_after.timestamp();
|
||||||
@@ -113,7 +129,7 @@ fn print_cert_info(yubikey: &mut YubiKey, slot: SlotId, detail_output: bool) ->
|
|||||||
let valid_time = simpledateformat::format_human(Duration::from_secs((not_after_timestamp - now_timestamp) as u64));
|
let valid_time = simpledateformat::format_human(Duration::from_secs((not_after_timestamp - now_timestamp) as u64));
|
||||||
not_after_desc.push_str(&format!("(left {})", valid_time));
|
not_after_desc.push_str(&format!("(left {})", valid_time));
|
||||||
}
|
}
|
||||||
success!("Not After: {} {}", cert.tbs_certificate.validity.not_after.to_rfc2822(), not_after_desc);
|
information!("Not After: {} {}", cert.tbs_certificate.validity.not_after.to_rfc2822(), not_after_desc);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
warning!("Failed to parse certificate");
|
warning!("Failed to parse certificate");
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ impl Command for CommandImpl {
|
|||||||
|
|
||||||
let mut yk = opt_result!(YubiKey::open(), "YubiKey not found: {}");
|
let mut yk = opt_result!(YubiKey::open(), "YubiKey not found: {}");
|
||||||
opt_result!(yk.verify_pin(pin.as_bytes()), "YubiKey verify pin failed: {}");
|
opt_result!(yk.verify_pin(pin.as_bytes()), "YubiKey verify pin failed: {}");
|
||||||
|
// TODO make PKCS#1_5 padding signature
|
||||||
let raw_in = [1_u8; 256];
|
let raw_in = [1_u8; 256];
|
||||||
let sign_result = yubikey::piv::sign_data(&mut yk, &raw_in, AlgorithmId::Rsa2048, SlotId::Signature);
|
let sign_result = yubikey::piv::sign_data(&mut yk, &raw_in, AlgorithmId::Rsa2048, SlotId::Signature);
|
||||||
let sign = opt_result!(sign_result, "Sign data failed: {}");
|
let sign = opt_result!(sign_result, "Sign data failed: {}");
|
||||||
|
|||||||
Reference in New Issue
Block a user