Merge branch 'update-to-rust' into 'main'
Update to newer Rust See merge request openpgp-card/openpgp-card!33
This commit is contained in:
commit
bb5f495a5c
27 changed files with 136 additions and 185 deletions
|
@ -29,7 +29,7 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
print!("Set user data");
|
print!("Set user data");
|
||||||
let userdata_out = run_test(&mut card, test_set_user_data, &[])?;
|
let userdata_out = run_test(&mut card, test_set_user_data, &[])?;
|
||||||
println!(" {:x?}", userdata_out);
|
println!(" {userdata_out:x?}");
|
||||||
|
|
||||||
let key_files = {
|
let key_files = {
|
||||||
let config = card.get_config();
|
let config = card.get_config();
|
||||||
|
@ -42,20 +42,20 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
for key_file in &key_files {
|
for key_file in &key_files {
|
||||||
// upload keys
|
// upload keys
|
||||||
print!("Upload key '{}'", key_file);
|
print!("Upload key '{key_file}'");
|
||||||
let upload_res = run_test(&mut card, test_upload_keys, &[key_file]);
|
let upload_res = run_test(&mut card, test_upload_keys, &[key_file]);
|
||||||
|
|
||||||
if let Err(TestError::KeyUploadError(_file, err)) = &upload_res {
|
if let Err(TestError::KeyUploadError(_file, err)) = &upload_res {
|
||||||
// The card doesn't support this key type, so skip to the
|
// The card doesn't support this key type, so skip to the
|
||||||
// next key - don't try to decrypt/sign for this key.
|
// next key - don't try to decrypt/sign for this key.
|
||||||
|
|
||||||
println!(" => Upload failed ({:?}), skip tests", err);
|
println!(" => Upload failed ({err:?}), skip tests");
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let upload_out = upload_res?;
|
let upload_out = upload_res?;
|
||||||
println!(" {:x?}", upload_out);
|
println!(" {upload_out:x?}");
|
||||||
|
|
||||||
let key = std::fs::read_to_string(key_file).expect("Unable to read ciphertext");
|
let key = std::fs::read_to_string(key_file).expect("Unable to read ciphertext");
|
||||||
|
|
||||||
|
@ -66,13 +66,13 @@ fn main() -> Result<()> {
|
||||||
let ciphertext = util::encrypt_to("Hello world!\n", &c)?;
|
let ciphertext = util::encrypt_to("Hello world!\n", &c)?;
|
||||||
|
|
||||||
let dec_out = run_test(&mut card, test_decrypt, &[&key, &ciphertext])?;
|
let dec_out = run_test(&mut card, test_decrypt, &[&key, &ciphertext])?;
|
||||||
println!(" {:x?}", dec_out);
|
println!(" {dec_out:x?}");
|
||||||
|
|
||||||
// sign
|
// sign
|
||||||
print!(" Sign");
|
print!(" Sign");
|
||||||
|
|
||||||
let sign_out = run_test(&mut card, test_sign, &[&key])?;
|
let sign_out = run_test(&mut card, test_sign, &[&key])?;
|
||||||
println!(" {:x?}", sign_out);
|
println!(" {sign_out:x?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: import key with password
|
// FIXME: import key with password
|
||||||
|
|
|
@ -53,7 +53,7 @@ fn main() -> Result<()> {
|
||||||
};
|
};
|
||||||
|
|
||||||
for algo in algos {
|
for algo in algos {
|
||||||
println!("Generate key [{}]", algo);
|
println!("Generate key [{algo}]");
|
||||||
|
|
||||||
let res = run_test(&mut card, test_keygen, &[&algo])?;
|
let res = run_test(&mut card, test_keygen, &[&algo])?;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ fn main() -> Result<()> {
|
||||||
// sign
|
// sign
|
||||||
print!(" Sign");
|
print!(" Sign");
|
||||||
let sign_out = run_test(&mut card, test_sign, &[cert])?;
|
let sign_out = run_test(&mut card, test_sign, &[cert])?;
|
||||||
println!(" {:x?}", sign_out);
|
println!(" {sign_out:x?}");
|
||||||
|
|
||||||
// decrypt
|
// decrypt
|
||||||
let c = Cert::from_str(cert)?;
|
let c = Cert::from_str(cert)?;
|
||||||
|
@ -69,7 +69,7 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
print!(" Decrypt");
|
print!(" Decrypt");
|
||||||
let dec_out = run_test(&mut card, test_decrypt, &[cert, &ciphertext])?;
|
let dec_out = run_test(&mut card, test_decrypt, &[cert, &ciphertext])?;
|
||||||
println!(" {:x?}", dec_out);
|
println!(" {dec_out:x?}");
|
||||||
} else {
|
} else {
|
||||||
panic!("Didn't get back a Cert from test_keygen");
|
panic!("Didn't get back a Cert from test_keygen");
|
||||||
};
|
};
|
||||||
|
|
|
@ -114,15 +114,15 @@ fn check_key_upload_metadata(
|
||||||
let card_fp = ard.fingerprints()?;
|
let card_fp = ard.fingerprints()?;
|
||||||
|
|
||||||
let sig = card_fp.signature().expect("signature fingerprint");
|
let sig = card_fp.signature().expect("signature fingerprint");
|
||||||
assert_eq!(format!("{:X}", sig), meta[0].0);
|
assert_eq!(format!("{sig:X}"), meta[0].0);
|
||||||
|
|
||||||
let dec = card_fp.decryption().expect("decryption fingerprint");
|
let dec = card_fp.decryption().expect("decryption fingerprint");
|
||||||
assert_eq!(format!("{:X}", dec), meta[1].0);
|
assert_eq!(format!("{dec:X}"), meta[1].0);
|
||||||
|
|
||||||
let auth = card_fp
|
let auth = card_fp
|
||||||
.authentication()
|
.authentication()
|
||||||
.expect("authentication fingerprint");
|
.expect("authentication fingerprint");
|
||||||
assert_eq!(format!("{:X}", auth), meta[2].0);
|
assert_eq!(format!("{auth:X}"), meta[2].0);
|
||||||
|
|
||||||
// get_key_generation_times
|
// get_key_generation_times
|
||||||
let card_kg = ard.key_generation_times()?;
|
let card_kg = ard.key_generation_times()?;
|
||||||
|
@ -154,16 +154,16 @@ pub fn test_print_caps(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOutput,
|
||||||
let ard = pgpt.application_related_data()?;
|
let ard = pgpt.application_related_data()?;
|
||||||
|
|
||||||
let aid = ard.application_id()?;
|
let aid = ard.application_id()?;
|
||||||
println!("aid: {:#x?}", aid);
|
println!("aid: {aid:#x?}");
|
||||||
|
|
||||||
let hist = ard.historical_bytes()?;
|
let hist = ard.historical_bytes()?;
|
||||||
println!("hist: {:#?}", hist);
|
println!("hist: {hist:#?}");
|
||||||
|
|
||||||
let ecap = ard.extended_capabilities()?;
|
let ecap = ard.extended_capabilities()?;
|
||||||
println!("ecap: {:#?}", ecap);
|
println!("ecap: {ecap:#?}");
|
||||||
|
|
||||||
let eli = ard.extended_length_information()?;
|
let eli = ard.extended_length_information()?;
|
||||||
println!("eli: {:#?}", eli);
|
println!("eli: {eli:#?}");
|
||||||
|
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
}
|
}
|
||||||
|
@ -174,13 +174,13 @@ pub fn test_print_algo_info(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOu
|
||||||
let ard = pgpt.application_related_data()?;
|
let ard = pgpt.application_related_data()?;
|
||||||
|
|
||||||
let dec = ard.algorithm_attributes(KeyType::Decryption)?;
|
let dec = ard.algorithm_attributes(KeyType::Decryption)?;
|
||||||
println!("Current algorithm for the decrypt slot: {}", dec);
|
println!("Current algorithm for the decrypt slot: {dec}");
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
let algo = pgpt.algorithm_information();
|
let algo = pgpt.algorithm_information();
|
||||||
if let Ok(Some(algo)) = algo {
|
if let Ok(Some(algo)) = algo {
|
||||||
println!("Card algorithm list:\n{}", algo);
|
println!("Card algorithm list:\n{algo}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
|
@ -276,7 +276,7 @@ pub fn test_get_pub(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOutput, Te
|
||||||
let key =
|
let key =
|
||||||
public_key_material_and_fp_to_key(&sig, KeyType::Signing, &ts, fps.signature().unwrap())?;
|
public_key_material_and_fp_to_key(&sig, KeyType::Signing, &ts, fps.signature().unwrap())?;
|
||||||
|
|
||||||
println!(" sig key data from card -> {:x?}", key);
|
println!(" sig key data from card -> {key:x?}");
|
||||||
|
|
||||||
// --
|
// --
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ pub fn test_get_pub(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOutput, Te
|
||||||
fps.decryption().unwrap(),
|
fps.decryption().unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
println!(" dec key data from card -> {:x?}", key);
|
println!(" dec key data from card -> {key:x?}");
|
||||||
|
|
||||||
// --
|
// --
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ pub fn test_get_pub(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOutput, Te
|
||||||
fps.authentication().unwrap(),
|
fps.authentication().unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
println!(" auth key data from card -> {:x?}", key);
|
println!(" auth key data from card -> {key:x?}");
|
||||||
|
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,7 @@ pub fn test_private_data(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOutpu
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
let d = pgpt.private_use_do(1)?;
|
let d = pgpt.private_use_do(1)?;
|
||||||
println!("data 1 {:?}", d);
|
println!("data 1 {d:?}");
|
||||||
|
|
||||||
pgpt.verify_pw1_user(b"123456")?;
|
pgpt.verify_pw1_user(b"123456")?;
|
||||||
|
|
||||||
|
@ -373,13 +373,13 @@ pub fn test_private_data(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOutpu
|
||||||
pgpt.set_private_use_do(4, "Foo bar4!".as_bytes().to_vec())?;
|
pgpt.set_private_use_do(4, "Foo bar4!".as_bytes().to_vec())?;
|
||||||
|
|
||||||
let d = pgpt.private_use_do(1)?;
|
let d = pgpt.private_use_do(1)?;
|
||||||
println!("data 1 {:?}", d);
|
println!("data 1 {d:?}");
|
||||||
let d = pgpt.private_use_do(2)?;
|
let d = pgpt.private_use_do(2)?;
|
||||||
println!("data 2 {:?}", d);
|
println!("data 2 {d:?}");
|
||||||
let d = pgpt.private_use_do(3)?;
|
let d = pgpt.private_use_do(3)?;
|
||||||
println!("data 3 {:?}", d);
|
println!("data 3 {d:?}");
|
||||||
let d = pgpt.private_use_do(4)?;
|
let d = pgpt.private_use_do(4)?;
|
||||||
println!("data 4 {:?}", d);
|
println!("data 4 {d:?}");
|
||||||
|
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
@ -452,7 +452,7 @@ pub fn test_pw_status(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOutput,
|
||||||
let ard = pgpt.application_related_data()?;
|
let ard = pgpt.application_related_data()?;
|
||||||
let mut pws = ard.pw_status_bytes()?;
|
let mut pws = ard.pw_status_bytes()?;
|
||||||
|
|
||||||
println!("pws {:?}", pws);
|
println!("pws {pws:?}");
|
||||||
|
|
||||||
pgpt.verify_pw3(b"12345678")?;
|
pgpt.verify_pw3(b"12345678")?;
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ pub fn test_pw_status(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOutput,
|
||||||
|
|
||||||
let ard = pgpt.application_related_data()?;
|
let ard = pgpt.application_related_data()?;
|
||||||
let pws = ard.pw_status_bytes()?;
|
let pws = ard.pw_status_bytes()?;
|
||||||
println!("pws {:?}", pws);
|
println!("pws {pws:?}");
|
||||||
|
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,41 +41,41 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
// card metadata
|
// card metadata
|
||||||
|
|
||||||
let app_id = transaction.application_identifier()?;
|
let app_id = transaction.application_identifier()?;
|
||||||
println!("{:x?}\n", app_id);
|
println!("{app_id:x?}\n");
|
||||||
|
|
||||||
let eli = transaction.extended_length_information()?;
|
let eli = transaction.extended_length_information()?;
|
||||||
println!("extended_length_info: {:?}\n", eli);
|
println!("extended_length_info: {eli:?}\n");
|
||||||
|
|
||||||
let hist = transaction.historical_bytes()?;
|
let hist = transaction.historical_bytes()?;
|
||||||
println!("{:#x?}\n", hist);
|
println!("{hist:#x?}\n");
|
||||||
|
|
||||||
let ext = transaction.extended_capabilities()?;
|
let ext = transaction.extended_capabilities()?;
|
||||||
println!("{:#x?}\n", ext);
|
println!("{ext:#x?}\n");
|
||||||
|
|
||||||
let pws = transaction.pw_status_bytes()?;
|
let pws = transaction.pw_status_bytes()?;
|
||||||
println!("{:#x?}\n", pws);
|
println!("{pws:#x?}\n");
|
||||||
|
|
||||||
// cardholder
|
// cardholder
|
||||||
let ch = transaction.cardholder_related_data()?;
|
let ch = transaction.cardholder_related_data()?;
|
||||||
println!("{:#x?}\n", ch);
|
println!("{ch:#x?}\n");
|
||||||
|
|
||||||
// crypto-ish metadata
|
// crypto-ish metadata
|
||||||
let fp = transaction.fingerprints()?;
|
let fp = transaction.fingerprints()?;
|
||||||
println!("Fingerprint {:#x?}\n", fp);
|
println!("Fingerprint {fp:#x?}\n");
|
||||||
|
|
||||||
match transaction.algorithm_information() {
|
match transaction.algorithm_information() {
|
||||||
Ok(Some(ai)) => println!("Algorithm information:\n{}", ai),
|
Ok(Some(ai)) => println!("Algorithm information:\n{ai}"),
|
||||||
Ok(None) => println!("No Algorithm information found"),
|
Ok(None) => println!("No Algorithm information found"),
|
||||||
Err(e) => println!("Error getting Algorithm information: {:?}", e),
|
Err(e) => println!("Error getting Algorithm information: {e:?}"),
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Current algorithm attributes on card:");
|
println!("Current algorithm attributes on card:");
|
||||||
let algo = transaction.algorithm_attributes(KeyType::Signing)?;
|
let algo = transaction.algorithm_attributes(KeyType::Signing)?;
|
||||||
println!("Sig: {}", algo);
|
println!("Sig: {algo}");
|
||||||
let algo = transaction.algorithm_attributes(KeyType::Decryption)?;
|
let algo = transaction.algorithm_attributes(KeyType::Decryption)?;
|
||||||
println!("Dec: {}", algo);
|
println!("Dec: {algo}");
|
||||||
let algo = transaction.algorithm_attributes(KeyType::Authentication)?;
|
let algo = transaction.algorithm_attributes(KeyType::Authentication)?;
|
||||||
println!("Aut: {}", algo);
|
println!("Aut: {algo}");
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
assert_eq!(app_id.ident(), test_card_ident.to_ascii_uppercase());
|
assert_eq!(app_id.ident(), test_card_ident.to_ascii_uppercase());
|
||||||
|
|
||||||
let check = transaction.check_admin_verified();
|
let check = transaction.check_admin_verified();
|
||||||
println!("has admin (pw3) been verified yet?\n{:x?}\n", check);
|
println!("has admin (pw3) been verified yet?\n{check:x?}\n");
|
||||||
|
|
||||||
println!("factory reset\n");
|
println!("factory reset\n");
|
||||||
transaction.factory_reset()?;
|
transaction.factory_reset()?;
|
||||||
|
@ -96,7 +96,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
println!("verify for admin ok");
|
println!("verify for admin ok");
|
||||||
|
|
||||||
let check = transaction.check_user_verified();
|
let check = transaction.check_user_verified();
|
||||||
println!("has user (pw1/82) been verified yet? {:x?}", check);
|
println!("has user (pw1/82) been verified yet? {check:x?}");
|
||||||
|
|
||||||
// Use Admin access to card
|
// Use Admin access to card
|
||||||
let mut admin = transaction.admin_card().expect("just verified");
|
let mut admin = transaction.admin_card().expect("just verified");
|
||||||
|
@ -148,13 +148,13 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
assert_eq!(app_id.ident(), test_card_ident.to_ascii_uppercase());
|
assert_eq!(app_id.ident(), test_card_ident.to_ascii_uppercase());
|
||||||
|
|
||||||
let check = transaction.check_user_verified();
|
let check = transaction.check_user_verified();
|
||||||
println!("has user (pw1/82) been verified yet?\n{:x?}\n", check);
|
println!("has user (pw1/82) been verified yet?\n{check:x?}\n");
|
||||||
|
|
||||||
transaction.verify_user(b"123456")?;
|
transaction.verify_user(b"123456")?;
|
||||||
println!("verify for user (pw1/82) ok");
|
println!("verify for user (pw1/82) ok");
|
||||||
|
|
||||||
let check = transaction.check_user_verified();
|
let check = transaction.check_user_verified();
|
||||||
println!("has user (pw1/82) been verified yet?\n{:x?}\n", check);
|
println!("has user (pw1/82) been verified yet?\n{check:x?}\n");
|
||||||
|
|
||||||
// Use User access to card
|
// Use User access to card
|
||||||
let mut user = transaction
|
let mut user = transaction
|
||||||
|
@ -164,14 +164,14 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let _cert = Cert::from_file(TEST_KEY_PATH)?;
|
let _cert = Cert::from_file(TEST_KEY_PATH)?;
|
||||||
let msg = std::fs::read_to_string(TEST_ENC_MSG).expect("Unable to read file");
|
let msg = std::fs::read_to_string(TEST_ENC_MSG).expect("Unable to read file");
|
||||||
|
|
||||||
println!("Encrypted message:\n{}", msg);
|
println!("Encrypted message:\n{msg}");
|
||||||
|
|
||||||
let sp = StandardPolicy::new();
|
let sp = StandardPolicy::new();
|
||||||
let d = user.decryptor(&|| println!("Touch confirmation needed for decryption"))?;
|
let d = user.decryptor(&|| println!("Touch confirmation needed for decryption"))?;
|
||||||
let res = sq_util::decryption_helper(d, msg.into_bytes(), &sp)?;
|
let res = sq_util::decryption_helper(d, msg.into_bytes(), &sp)?;
|
||||||
|
|
||||||
let plain = String::from_utf8_lossy(&res);
|
let plain = String::from_utf8_lossy(&res);
|
||||||
println!("Decrypted plaintext: {}", plain);
|
println!("Decrypted plaintext: {plain}");
|
||||||
|
|
||||||
assert_eq!(plain, "Hello world!\n");
|
assert_eq!(plain, "Hello world!\n");
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let signer = sign.signer(&|| {})?;
|
let signer = sign.signer(&|| {})?;
|
||||||
let sig = sq_util::sign_helper(signer, &mut text.as_bytes())?;
|
let sig = sq_util::sign_helper(signer, &mut text.as_bytes())?;
|
||||||
|
|
||||||
println!("Signature from card:\n{}", sig)
|
println!("Signature from card:\n{sig}")
|
||||||
|
|
||||||
// FIXME: validate sig
|
// FIXME: validate sig
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -53,7 +53,7 @@ impl CardUploadableKey for SequoiaKey {
|
||||||
.key
|
.key
|
||||||
.clone()
|
.clone()
|
||||||
.decrypt_secret(&sequoia_openpgp::crypto::Password::from(pw.as_str()))
|
.decrypt_secret(&sequoia_openpgp::crypto::Password::from(pw.as_str()))
|
||||||
.map_err(|e| Error::InternalError(format!("sequoia decrypt failed {:?}", e)))?,
|
.map_err(|e| Error::InternalError(format!("sequoia decrypt failed {e:?}")))?,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get private cryptographic material
|
// Get private cryptographic material
|
||||||
|
@ -129,7 +129,7 @@ impl SqRSA {
|
||||||
q: ProtectedMPI,
|
q: ProtectedMPI,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let nettle = nettle::rsa::PrivateKey::new(d.value(), p.value(), q.value(), None)
|
let nettle = nettle::rsa::PrivateKey::new(d.value(), p.value(), q.value(), None)
|
||||||
.map_err(|e| Error::InternalError(format!("nettle error {:?}", e)))?;
|
.map_err(|e| Error::InternalError(format!("nettle error {e:?}")))?;
|
||||||
|
|
||||||
Ok(Self { e, n, p, q, nettle })
|
Ok(Self { e, n, p, q, nettle })
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,8 @@ use crate::{Card, PublicKey};
|
||||||
///
|
///
|
||||||
/// FIXME: accept optional metadata for user_id(s)?
|
/// FIXME: accept optional metadata for user_id(s)?
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn make_cert<'app>(
|
pub fn make_cert(
|
||||||
open: &mut Card<Transaction<'app>>,
|
open: &mut Card<Transaction<'_>>,
|
||||||
key_sig: PublicKey,
|
key_sig: PublicKey,
|
||||||
key_dec: Option<PublicKey>,
|
key_dec: Option<PublicKey>,
|
||||||
key_aut: Option<PublicKey>,
|
key_aut: Option<PublicKey>,
|
||||||
|
@ -230,7 +230,7 @@ pub fn public_key_material_to_key(
|
||||||
match pkm {
|
match pkm {
|
||||||
PublicKeyMaterial::R(rsa) => {
|
PublicKeyMaterial::R(rsa) => {
|
||||||
let k4 = Key4::import_public_rsa(rsa.v(), rsa.n(), Some(time)).map_err(|e| {
|
let k4 = Key4::import_public_rsa(rsa.v(), rsa.n(), Some(time)).map_err(|e| {
|
||||||
Error::InternalError(format!("sequoia Key4::import_public_rsa failed: {:?}", e))
|
Error::InternalError(format!("sequoia Key4::import_public_rsa failed: {e:?}"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(k4.into())
|
Ok(k4.into())
|
||||||
|
@ -254,8 +254,7 @@ pub fn public_key_material_to_key(
|
||||||
let k4 =
|
let k4 =
|
||||||
Key4::import_public_ed25519(ecc.data(), time).map_err(|e| {
|
Key4::import_public_ed25519(ecc.data(), time).map_err(|e| {
|
||||||
Error::InternalError(format!(
|
Error::InternalError(format!(
|
||||||
"sequoia Key4::import_public_ed25519 failed: {:?}",
|
"sequoia Key4::import_public_ed25519 failed: {e:?}"
|
||||||
e
|
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -272,8 +271,7 @@ pub fn public_key_material_to_key(
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Error::InternalError(format!(
|
Error::InternalError(format!(
|
||||||
"sequoia Key4::new for ECDSA failed: {:?}",
|
"sequoia Key4::new for ECDSA failed: {e:?}"
|
||||||
e
|
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -286,8 +284,7 @@ pub fn public_key_material_to_key(
|
||||||
let k4 = Key4::import_public_cv25519(ecc.data(), hash, sym, time)
|
let k4 = Key4::import_public_cv25519(ecc.data(), hash, sym, time)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Error::InternalError(format!(
|
Error::InternalError(format!(
|
||||||
"sequoia Key4::import_public_cv25519 failed: {:?}",
|
"sequoia Key4::import_public_cv25519 failed: {e:?}"
|
||||||
e
|
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -306,8 +303,7 @@ pub fn public_key_material_to_key(
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Error::InternalError(format!(
|
Error::InternalError(format!(
|
||||||
"sequoia Key4::new for ECDH failed: {:?}",
|
"sequoia Key4::new for ECDH failed: {e:?}"
|
||||||
e
|
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl TryFrom<&str> for AlgoSimple {
|
||||||
"NIST384" => NIST384,
|
"NIST384" => NIST384,
|
||||||
"NIST521" => NIST521,
|
"NIST521" => NIST521,
|
||||||
"Curve25519" => Curve25519,
|
"Curve25519" => Curve25519,
|
||||||
_ => return Err(Error::UnsupportedAlgo(format!("unexpected algo {}", algo))),
|
_ => return Err(Error::UnsupportedAlgo(format!("unexpected algo {algo}"))),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ impl fmt::Display for Algo {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Self::Unknown(u) => {
|
Self::Unknown(u) => {
|
||||||
write!(f, "Unknown: {:?}", u)
|
write!(f, "Unknown: {u:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,10 +188,7 @@ impl Algo {
|
||||||
match self {
|
match self {
|
||||||
Algo::Rsa(rsa) => Self::rsa_algo_attrs(rsa),
|
Algo::Rsa(rsa) => Self::rsa_algo_attrs(rsa),
|
||||||
Algo::Ecc(ecc) => Self::ecc_algo_attrs(ecc.oid(), ecc.ecc_type()),
|
Algo::Ecc(ecc) => Self::ecc_algo_attrs(ecc.oid(), ecc.ecc_type()),
|
||||||
_ => Err(Error::UnsupportedAlgo(format!(
|
_ => Err(Error::UnsupportedAlgo(format!("Unexpected Algo {self:?}"))),
|
||||||
"Unexpected Algo {:?}",
|
|
||||||
self
|
|
||||||
))),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +348,7 @@ impl TryFrom<&[u8]> for Curve {
|
||||||
oid::ED448 => Ed448,
|
oid::ED448 => Ed448,
|
||||||
oid::X448 => X448,
|
oid::X448 => X448,
|
||||||
|
|
||||||
_ => return Err(Error::ParseError(format!("Unknown curve OID {:?}", oid))),
|
_ => return Err(Error::ParseError(format!("Unknown curve OID {oid:?}"))),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(curve)
|
Ok(curve)
|
||||||
|
|
|
@ -93,8 +93,8 @@ impl Command {
|
||||||
if !ext_len {
|
if !ext_len {
|
||||||
assert!(
|
assert!(
|
||||||
len <= 0xff,
|
len <= 0xff,
|
||||||
"unexpected: len = {:x?}, but ext says Short",
|
"{}",
|
||||||
len
|
"unexpected: len = {len:x?}, but ext says Short"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,8 +112,7 @@ impl ApplicationRelatedData {
|
||||||
Algo::try_from(&aa.serialize()[..])
|
Algo::try_from(&aa.serialize()[..])
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NotFound(format!(
|
Err(Error::NotFound(format!(
|
||||||
"Failed to get algorithm attributes for {:?}.",
|
"Failed to get algorithm attributes for {key_type:?}."
|
||||||
key_type
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,7 +316,7 @@ impl TryFrom<Vec<u8>> for UIF {
|
||||||
if v.len() == 2 {
|
if v.len() == 2 {
|
||||||
Ok(UIF(v.try_into().unwrap()))
|
Ok(UIF(v.try_into().unwrap()))
|
||||||
} else {
|
} else {
|
||||||
Err(Error::ParseError(format!("Can't get UID from {:x?}", v)))
|
Err(Error::ParseError(format!("Can't get UID from {v:x?}")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -388,7 +387,7 @@ impl Display for TouchPolicy {
|
||||||
TouchPolicy::Fixed => write!(f, "Fixed"),
|
TouchPolicy::Fixed => write!(f, "Fixed"),
|
||||||
TouchPolicy::Cached => write!(f, "Cached"),
|
TouchPolicy::Cached => write!(f, "Cached"),
|
||||||
TouchPolicy::CachedFixed => write!(f, "CachedFixed"),
|
TouchPolicy::CachedFixed => write!(f, "CachedFixed"),
|
||||||
TouchPolicy::Unknown(i) => write!(f, "Unknown({})", i),
|
TouchPolicy::Unknown(i) => write!(f, "Unknown({i})"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -575,7 +574,7 @@ impl Display for KeyStatus {
|
||||||
KeyStatus::NotPresent => write!(f, "not present"),
|
KeyStatus::NotPresent => write!(f, "not present"),
|
||||||
KeyStatus::Generated => write!(f, "generated"),
|
KeyStatus::Generated => write!(f, "generated"),
|
||||||
KeyStatus::Imported => write!(f, "imported"),
|
KeyStatus::Imported => write!(f, "imported"),
|
||||||
KeyStatus::Unknown(i) => write!(f, "unknown status ({})", i),
|
KeyStatus::Unknown(i) => write!(f, "unknown status ({i})"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -755,19 +754,15 @@ impl Display for ExtendedCapabilities {
|
||||||
|
|
||||||
// v2
|
// v2
|
||||||
if let Some(max_cmd_len) = self.max_cmd_len {
|
if let Some(max_cmd_len) = self.max_cmd_len {
|
||||||
writeln!(f, "- maximum command length: {}", max_cmd_len)?;
|
writeln!(f, "- maximum command length: {max_cmd_len}")?;
|
||||||
}
|
}
|
||||||
if let Some(max_resp_len) = self.max_resp_len {
|
if let Some(max_resp_len) = self.max_resp_len {
|
||||||
writeln!(f, "- maximum response length: {}", max_resp_len)?;
|
writeln!(f, "- maximum response length: {max_resp_len}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// v3
|
// v3
|
||||||
if let Some(max_len_special_do) = self.max_len_special_do {
|
if let Some(max_len_special_do) = self.max_len_special_do {
|
||||||
writeln!(
|
writeln!(f, "- maximum length for special DOs: {max_len_special_do}")?;
|
||||||
f,
|
|
||||||
"- maximum length for special DOs: {}",
|
|
||||||
max_len_special_do
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
if self.pin_block_2_format_support == Some(true) {
|
if self.pin_block_2_format_support == Some(true) {
|
||||||
writeln!(f, "- PIN block 2 format supported")?;
|
writeln!(f, "- PIN block 2 format supported")?;
|
||||||
|
@ -809,7 +804,7 @@ impl Display for CardholderRelatedData {
|
||||||
writeln!(f, "Name: {}", Self::latin1_to_string(name))?;
|
writeln!(f, "Name: {}", Self::latin1_to_string(name))?;
|
||||||
}
|
}
|
||||||
if let Some(sex) = self.sex {
|
if let Some(sex) = self.sex {
|
||||||
writeln!(f, "Sex: {}", sex)?;
|
writeln!(f, "Sex: {sex}")?;
|
||||||
}
|
}
|
||||||
if let Some(lang) = &self.lang {
|
if let Some(lang) = &self.lang {
|
||||||
for (n, l) in lang.iter().enumerate() {
|
for (n, l) in lang.iter().enumerate() {
|
||||||
|
@ -839,7 +834,7 @@ impl Display for Sex {
|
||||||
Self::Male => write!(f, "Male"),
|
Self::Male => write!(f, "Male"),
|
||||||
Self::Female => write!(f, "Female"),
|
Self::Female => write!(f, "Female"),
|
||||||
Self::NotApplicable => write!(f, "Not applicable"),
|
Self::NotApplicable => write!(f, "Not applicable"),
|
||||||
Self::UndefinedValue(v) => write!(f, "Undefined value {:x?}", v),
|
Self::UndefinedValue(v) => write!(f, "Undefined value {v:x?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -884,7 +879,7 @@ impl Display for Lang {
|
||||||
write!(f, "{}{}", v[0] as char, v[1] as char)
|
write!(f, "{}{}", v[0] as char, v[1] as char)
|
||||||
}
|
}
|
||||||
Self::Invalid(v) => {
|
Self::Invalid(v) => {
|
||||||
write!(f, "{:x?}", v)
|
write!(f, "{v:x?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1023,8 +1018,7 @@ pub(crate) fn complete<O>(result: nom::IResult<&[u8], O>) -> Result<O, Error> {
|
||||||
Ok(output)
|
Ok(output)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::ParseError(format!(
|
Err(Error::ParseError(format!(
|
||||||
"Parsing incomplete, trailing data: {:x?}",
|
"Parsing incomplete, trailing data: {rem:x?}"
|
||||||
rem
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ impl fmt::Display for AlgoInfo {
|
||||||
KeyType::Authentication => "AUT",
|
KeyType::Authentication => "AUT",
|
||||||
KeyType::Attestation => "ATT",
|
KeyType::Attestation => "ATT",
|
||||||
};
|
};
|
||||||
writeln!(f, "{}: {} ", kt, a)?;
|
writeln!(f, "{kt}: {a} ")?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,8 +80,7 @@ impl TryFrom<(&[u8], u16)> for ExtendedCapabilities {
|
||||||
|
|
||||||
if i8 > 1 {
|
if i8 > 1 {
|
||||||
return Err(Error::ParseError(format!(
|
return Err(Error::ParseError(format!(
|
||||||
"Illegal value '{}' for pin_block_2_format_support",
|
"Illegal value '{i8}' for pin_block_2_format_support"
|
||||||
i8
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +88,7 @@ impl TryFrom<(&[u8], u16)> for ExtendedCapabilities {
|
||||||
|
|
||||||
if i9 > 1 {
|
if i9 > 1 {
|
||||||
return Err(Error::ParseError(format!(
|
return Err(Error::ParseError(format!(
|
||||||
"Illegal value '{}' for mse_command_support",
|
"Illegal value '{i9}' for mse_command_support"
|
||||||
i9
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
mse_command_support = Some(i9 != 0);
|
mse_command_support = Some(i9 != 0);
|
||||||
|
|
|
@ -44,14 +44,14 @@ impl Fingerprint {
|
||||||
|
|
||||||
impl fmt::Display for Fingerprint {
|
impl fmt::Display for Fingerprint {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{:X}", self)
|
write!(f, "{self:X}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::UpperHex for Fingerprint {
|
impl fmt::UpperHex for Fingerprint {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
for b in &self.0 {
|
for b in &self.0 {
|
||||||
write!(f, "{:02X}", b)?;
|
write!(f, "{b:02X}")?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -133,9 +133,6 @@ mod test {
|
||||||
|
|
||||||
let fp = Fingerprint::try_from(&data1[..]).expect("failed to parse fingerprint");
|
let fp = Fingerprint::try_from(&data1[..]).expect("failed to parse fingerprint");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(format!("{fp}"), "B7CD9F76371E077F761C826555543E6D656D1D80");
|
||||||
format!("{}", fp),
|
|
||||||
"B7CD9F76371E077F761C826555543E6D656D1D80"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,8 +100,7 @@ impl TryFrom<&[u8]> for HistoricalBytes {
|
||||||
// historical bytes cannot be this short
|
// historical bytes cannot be this short
|
||||||
|
|
||||||
return Err(Error::ParseError(format!(
|
return Err(Error::ParseError(format!(
|
||||||
"Historical bytes too short ({} bytes), must be >= 4",
|
"Historical bytes too short ({len} bytes), must be >= 4"
|
||||||
len
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ pub(crate) fn gen_key_with_metadata(
|
||||||
// Store creation timestamp (unix time format, limited to u32)
|
// Store creation timestamp (unix time format, limited to u32)
|
||||||
let ts = time
|
let ts = time
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
.map_err(|e| Error::InternalError(format!("This should never happen {}", e)))?
|
.map_err(|e| Error::InternalError(format!("This should never happen {e}")))?
|
||||||
.as_secs() as u32;
|
.as_secs() as u32;
|
||||||
|
|
||||||
let ts = ts.into();
|
let ts = ts.into();
|
||||||
|
@ -111,8 +111,7 @@ fn tlv_to_pubkey(tlv: &Tlv, algo: &Algo) -> Result<PublicKeyMaterial, crate::Err
|
||||||
}
|
}
|
||||||
|
|
||||||
(_, _, _) => Err(Error::UnsupportedAlgo(format!(
|
(_, _, _) => Err(Error::UnsupportedAlgo(format!(
|
||||||
"Unexpected public key material from card {:?}",
|
"Unexpected public key material from card {tlv:?}"
|
||||||
tlv
|
|
||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,8 +284,7 @@ pub(crate) fn determine_ecc_attrs(
|
||||||
if algos.is_empty() {
|
if algos.is_empty() {
|
||||||
// If oid is not in algo_info, return error.
|
// If oid is not in algo_info, return error.
|
||||||
return Err(Error::UnsupportedAlgo(format!(
|
return Err(Error::UnsupportedAlgo(format!(
|
||||||
"Oid {:?} unsupported according to algo_info",
|
"Oid {oid:?} unsupported according to algo_info"
|
||||||
oid
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,8 +338,7 @@ fn card_algo_rsa(algo_info: AlgoInfo, key_type: KeyType, rsa_bits: u16) -> Resul
|
||||||
} else {
|
} else {
|
||||||
// RSA with this bit length is not in algo_info
|
// RSA with this bit length is not in algo_info
|
||||||
Err(Error::UnsupportedAlgo(format!(
|
Err(Error::UnsupportedAlgo(format!(
|
||||||
"RSA {} unsupported according to algo_info",
|
"RSA {rsa_bits} unsupported according to algo_info"
|
||||||
rsa_bits
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ mod openpgp;
|
||||||
mod tlv;
|
mod tlv;
|
||||||
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ops::{Deref, DerefMut};
|
|
||||||
|
|
||||||
use crate::apdu::commands;
|
use crate::apdu::commands;
|
||||||
use crate::card_do::ApplicationRelatedData;
|
use crate::card_do::ApplicationRelatedData;
|
||||||
|
@ -186,19 +185,6 @@ pub trait CardTransaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Deref for dyn CardTransaction + Send + Sync + 'a {
|
|
||||||
type Target = dyn CardTransaction + 'a;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> DerefMut for dyn CardTransaction + Send + Sync + 'a {
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Information about the capabilities of a card.
|
/// Information about the capabilities of a card.
|
||||||
///
|
///
|
||||||
/// CardCaps is used to signal capabilities (chaining, extended length support, max
|
/// CardCaps is used to signal capabilities (chaining, extended length support, max
|
||||||
|
|
|
@ -126,8 +126,7 @@ impl<'b> PcscTransaction<'b> {
|
||||||
c.reconnect(mode, pcsc::Protocols::ANY, Disposition::ResetCard)
|
c.reconnect(mode, pcsc::Protocols::ANY, Disposition::ResetCard)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Error::Smartcard(SmartcardError::Error(format!(
|
Error::Smartcard(SmartcardError::Error(format!(
|
||||||
"Reconnect failed: {:?}",
|
"Reconnect failed: {e:?}"
|
||||||
e
|
|
||||||
)))
|
)))
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
@ -139,8 +138,7 @@ impl<'b> PcscTransaction<'b> {
|
||||||
Err((_, e)) => {
|
Err((_, e)) => {
|
||||||
log::trace!("start_tx: error {:?}", e);
|
log::trace!("start_tx: error {:?}", e);
|
||||||
break Err(Error::Smartcard(SmartcardError::Error(format!(
|
break Err(Error::Smartcard(SmartcardError::Error(format!(
|
||||||
"Error: {:?}",
|
"Error: {e:?}"
|
||||||
e
|
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -162,8 +160,7 @@ impl<'b> PcscTransaction<'b> {
|
||||||
) -> Result<ApplicationRelatedData, Error> {
|
) -> Result<ApplicationRelatedData, Error> {
|
||||||
<dyn CardTransaction>::application_related_data(card_tx).map_err(|e| {
|
<dyn CardTransaction>::application_related_data(card_tx).map_err(|e| {
|
||||||
Error::Smartcard(SmartcardError::Error(format!(
|
Error::Smartcard(SmartcardError::Error(format!(
|
||||||
"TxClient: failed to get application_related_data {:x?}",
|
"TxClient: failed to get application_related_data {e:x?}"
|
||||||
e
|
|
||||||
)))
|
)))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -179,8 +176,7 @@ impl<'b> PcscTransaction<'b> {
|
||||||
.control(cm_ioctl_get_feature_request, &[], &mut recv)
|
.control(cm_ioctl_get_feature_request, &[], &mut recv)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Error::Smartcard(SmartcardError::Error(format!(
|
Error::Smartcard(SmartcardError::Error(format!(
|
||||||
"GET_FEATURE_REQUEST control call failed: {:?}",
|
"GET_FEATURE_REQUEST control call failed: {e:?}"
|
||||||
e
|
|
||||||
)))
|
)))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -216,7 +212,7 @@ impl CardTransaction for PcscTransaction<'_> {
|
||||||
.transmit(cmd, &mut resp_buffer)
|
.transmit(cmd, &mut resp_buffer)
|
||||||
.map_err(|e| match e {
|
.map_err(|e| match e {
|
||||||
pcsc::Error::NotTransacted => Error::Smartcard(SmartcardError::NotTransacted),
|
pcsc::Error::NotTransacted => Error::Smartcard(SmartcardError::NotTransacted),
|
||||||
_ => Error::Smartcard(SmartcardError::Error(format!("Transmit failed: {:?}", e))),
|
_ => Error::Smartcard(SmartcardError::Error(format!("Transmit failed: {e:?}"))),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(resp.to_vec())
|
Ok(resp.to_vec())
|
||||||
|
@ -317,13 +313,13 @@ impl CardTransaction for PcscTransaction<'_> {
|
||||||
.ok_or_else(|| Error::Smartcard(SmartcardError::Error("no reader_capability".into())))?
|
.ok_or_else(|| Error::Smartcard(SmartcardError::Error("no reader_capability".into())))?
|
||||||
.value()
|
.value()
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|e| Error::ParseError(format!("unexpected feature data: {:?}", e)))?;
|
.map_err(|e| Error::ParseError(format!("unexpected feature data: {e:?}")))?;
|
||||||
|
|
||||||
let res = self
|
let res = self
|
||||||
.tx
|
.tx
|
||||||
.control(u32::from_be_bytes(verify_ioctl).into(), &send, &mut recv)
|
.control(u32::from_be_bytes(verify_ioctl).into(), &send, &mut recv)
|
||||||
.map_err(|e: pcsc::Error| {
|
.map_err(|e: pcsc::Error| {
|
||||||
Error::Smartcard(SmartcardError::Error(format!("pcsc Error: {:?}", e)))
|
Error::Smartcard(SmartcardError::Error(format!("pcsc Error: {e:?}")))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
log::trace!(" <- pcsc pinpad_verify result: {:x?}", res);
|
log::trace!(" <- pcsc pinpad_verify result: {:x?}", res);
|
||||||
|
@ -420,13 +416,13 @@ impl CardTransaction for PcscTransaction<'_> {
|
||||||
.ok_or_else(|| Error::Smartcard(SmartcardError::Error("no reader_capability".into())))?
|
.ok_or_else(|| Error::Smartcard(SmartcardError::Error("no reader_capability".into())))?
|
||||||
.value()
|
.value()
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|e| Error::ParseError(format!("unexpected feature data: {:?}", e)))?;
|
.map_err(|e| Error::ParseError(format!("unexpected feature data: {e:?}")))?;
|
||||||
|
|
||||||
let res = self
|
let res = self
|
||||||
.tx
|
.tx
|
||||||
.control(u32::from_be_bytes(modify_ioctl).into(), &send, &mut recv)
|
.control(u32::from_be_bytes(modify_ioctl).into(), &send, &mut recv)
|
||||||
.map_err(|e: pcsc::Error| {
|
.map_err(|e: pcsc::Error| {
|
||||||
Error::Smartcard(SmartcardError::Error(format!("pcsc Error: {:?}", e)))
|
Error::Smartcard(SmartcardError::Error(format!("pcsc Error: {e:?}")))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
log::trace!(" <- pcsc pinpad_modify result: {:x?}", res);
|
log::trace!(" <- pcsc pinpad_modify result: {:x?}", res);
|
||||||
|
|
|
@ -103,16 +103,13 @@ impl ScdBackend {
|
||||||
} else {
|
} else {
|
||||||
// Create and use a new Agent based on a default Context
|
// Create and use a new Agent based on a default Context
|
||||||
let ctx = Context::new().map_err(|e| {
|
let ctx = Context::new().map_err(|e| {
|
||||||
Error::Smartcard(SmartcardError::Error(format!("Context::new failed {}", e)))
|
Error::Smartcard(SmartcardError::Error(format!("Context::new failed {e}")))
|
||||||
})?;
|
})?;
|
||||||
RT.lock()
|
RT.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.block_on(Agent::connect(&ctx))
|
.block_on(Agent::connect(&ctx))
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Error::Smartcard(SmartcardError::Error(format!(
|
Error::Smartcard(SmartcardError::Error(format!("Agent::connect failed {e}")))
|
||||||
"Agent::connect failed {}",
|
|
||||||
e
|
|
||||||
)))
|
|
||||||
})?
|
})?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -131,8 +128,7 @@ impl ScdBackend {
|
||||||
fn send2(&mut self, cmd: &str) -> Result<(), Error> {
|
fn send2(&mut self, cmd: &str) -> Result<(), Error> {
|
||||||
self.agent.send(cmd).map_err(|e| {
|
self.agent.send(cmd).map_err(|e| {
|
||||||
Error::Smartcard(SmartcardError::Error(format!(
|
Error::Smartcard(SmartcardError::Error(format!(
|
||||||
"scdc agent send failed: {}",
|
"scdc agent send failed: {e}"
|
||||||
e
|
|
||||||
)))
|
)))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -166,7 +162,7 @@ impl ScdBackend {
|
||||||
/// Ask scdameon to switch to using a specific OpenPGP card, based on
|
/// Ask scdameon to switch to using a specific OpenPGP card, based on
|
||||||
/// its `serial`.
|
/// its `serial`.
|
||||||
fn select_card(&mut self, serial: &str) -> Result<(), Error> {
|
fn select_card(&mut self, serial: &str) -> Result<(), Error> {
|
||||||
let send = format!("SCD SERIALNO --demand={}", serial);
|
let send = format!("SCD SERIALNO --demand={serial}");
|
||||||
self.send2(&send)?;
|
self.send2(&send)?;
|
||||||
|
|
||||||
let rt = RT.lock().unwrap();
|
let rt = RT.lock().unwrap();
|
||||||
|
@ -204,7 +200,7 @@ impl ScdBackend {
|
||||||
log::trace!("select res: {:x?}", response);
|
log::trace!("select res: {:x?}", response);
|
||||||
|
|
||||||
if let Err(e) = response {
|
if let Err(e) = response {
|
||||||
return Err(Error::Smartcard(SmartcardError::Error(format!("{:?}", e))));
|
return Err(Error::Smartcard(SmartcardError::Error(format!("{e:?}"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(..) = response {
|
if let Ok(..) = response {
|
||||||
|
@ -218,8 +214,7 @@ impl ScdBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(Error::Smartcard(SmartcardError::Error(format!(
|
Err(Error::Smartcard(SmartcardError::Error(format!(
|
||||||
"Error sending command {}",
|
"Error sending command {cmd}"
|
||||||
cmd
|
|
||||||
))))
|
))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +245,7 @@ impl CardTransaction for ScdTransaction<'_> {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
let send = format!("SCD APDU {}{}\n", ext, hex);
|
let send = format!("SCD APDU {ext}{hex}\n");
|
||||||
log::trace!("SCDC command: '{}'", send);
|
log::trace!("SCDC command: '{}'", send);
|
||||||
|
|
||||||
if send.len() > ASSUAN_LINELENGTH {
|
if send.len() > ASSUAN_LINELENGTH {
|
||||||
|
@ -268,8 +263,7 @@ impl CardTransaction for ScdTransaction<'_> {
|
||||||
log::trace!("res: {:x?}", response);
|
log::trace!("res: {:x?}", response);
|
||||||
if response.is_err() {
|
if response.is_err() {
|
||||||
return Err(Error::Smartcard(SmartcardError::Error(format!(
|
return Err(Error::Smartcard(SmartcardError::Error(format!(
|
||||||
"Unexpected error response from SCD {:?}",
|
"Unexpected error response from SCD {response:?}"
|
||||||
response
|
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -515,7 +515,7 @@ fn generate_command(
|
||||||
|
|
||||||
let algo = cmd.algo.map(AlgoSimple::from);
|
let algo = cmd.algo.map(AlgoSimple::from);
|
||||||
log::info!(" Key generation will be attempted with algo: {:?}", algo);
|
log::info!(" Key generation will be attempted with algo: {:?}", algo);
|
||||||
output.algorithm(format!("{:?}", algo));
|
output.algorithm(format!("{algo:?}"));
|
||||||
|
|
||||||
// 2) Then, generate keys on the card.
|
// 2) Then, generate keys on the card.
|
||||||
// We need "admin" access to the card for this).
|
// We need "admin" access to the card for this).
|
||||||
|
|
|
@ -187,7 +187,7 @@ fn statement(ident: Option<String>, key: BaseKeySlot) -> Result<(), Box<dyn std:
|
||||||
|
|
||||||
if !cert.is_empty() {
|
if !cert.is_empty() {
|
||||||
let pem = util::pem_encode(cert);
|
let pem = util::pem_encode(cert);
|
||||||
println!("{}", pem);
|
println!("{pem}");
|
||||||
} else {
|
} else {
|
||||||
println!("Cardholder certificate slot is empty");
|
println!("Cardholder certificate slot is empty");
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,7 +205,7 @@ fn set_user(
|
||||||
match res {
|
match res {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!("\nFailed to change the User PIN!");
|
println!("\nFailed to change the User PIN!");
|
||||||
println!("{:?}", err);
|
println!("{err:?}");
|
||||||
print_gnuk_note(err, &card)?;
|
print_gnuk_note(err, &card)?;
|
||||||
}
|
}
|
||||||
Ok(_) => println!("\nUser PIN has been set."),
|
Ok(_) => println!("\nUser PIN has been set."),
|
||||||
|
|
|
@ -70,7 +70,7 @@ pub fn print_status(
|
||||||
// Language Preference
|
// Language Preference
|
||||||
if let Some(lang) = card.cardholder_related_data()?.lang() {
|
if let Some(lang) = card.cardholder_related_data()?.lang() {
|
||||||
for lang in lang {
|
for lang in lang {
|
||||||
output.language_preference(format!("{}", lang));
|
output.language_preference(format!("{lang}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ pub fn print_status(
|
||||||
signature_key.touch_features(format!("{}", uif.features()));
|
signature_key.touch_features(format!("{}", uif.features()));
|
||||||
}
|
}
|
||||||
if let Some(ks) = ki.as_ref().map(|ki| ki.sig_status()) {
|
if let Some(ks) = ki.as_ref().map(|ki| ki.sig_status()) {
|
||||||
signature_key.status(format!("{}", ks));
|
signature_key.status(format!("{ks}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(pkm) = card.public_key_material(KeyType::Signing) {
|
if let Ok(pkm) = card.public_key_material(KeyType::Signing) {
|
||||||
|
@ -125,7 +125,7 @@ pub fn print_status(
|
||||||
decryption_key.touch_features(format!("{}", uif.features()));
|
decryption_key.touch_features(format!("{}", uif.features()));
|
||||||
}
|
}
|
||||||
if let Some(ks) = ki.as_ref().map(|ki| ki.dec_status()) {
|
if let Some(ks) = ki.as_ref().map(|ki| ki.dec_status()) {
|
||||||
decryption_key.status(format!("{}", ks));
|
decryption_key.status(format!("{ks}"));
|
||||||
}
|
}
|
||||||
if let Ok(pkm) = card.public_key_material(KeyType::Decryption) {
|
if let Ok(pkm) = card.public_key_material(KeyType::Decryption) {
|
||||||
decryption_key.public_key_material(pkm.to_string());
|
decryption_key.public_key_material(pkm.to_string());
|
||||||
|
@ -148,7 +148,7 @@ pub fn print_status(
|
||||||
authentication_key.touch_features(format!("{}", uif.features()));
|
authentication_key.touch_features(format!("{}", uif.features()));
|
||||||
}
|
}
|
||||||
if let Some(ks) = ki.as_ref().map(|ki| ki.aut_status()) {
|
if let Some(ks) = ki.as_ref().map(|ki| ki.aut_status()) {
|
||||||
authentication_key.status(format!("{}", ks));
|
authentication_key.status(format!("{ks}"));
|
||||||
}
|
}
|
||||||
if let Ok(pkm) = card.public_key_material(KeyType::Authentication) {
|
if let Ok(pkm) = card.public_key_material(KeyType::Authentication) {
|
||||||
authentication_key.public_key_material(pkm.to_string());
|
authentication_key.public_key_material(pkm.to_string());
|
||||||
|
@ -160,7 +160,7 @@ pub fn print_status(
|
||||||
attestation_key.fingerprint(fp.to_spaced_hex());
|
attestation_key.fingerprint(fp.to_spaced_hex());
|
||||||
}
|
}
|
||||||
if let Ok(Some(algo)) = card.attestation_key_algorithm_attributes() {
|
if let Ok(Some(algo)) = card.attestation_key_algorithm_attributes() {
|
||||||
attestation_key.algorithm(format!("{}", algo));
|
attestation_key.algorithm(format!("{algo}"));
|
||||||
}
|
}
|
||||||
if let Ok(Some(kgt)) = card.attestation_key_generation_time() {
|
if let Ok(Some(kgt)) = card.attestation_key_generation_time() {
|
||||||
attestation_key.creation_time(format!("{}", kgt.to_datetime()));
|
attestation_key.creation_time(format!("{}", kgt.to_datetime()));
|
||||||
|
@ -180,7 +180,7 @@ pub fn print_status(
|
||||||
if let Some(ki) = ki.as_ref() {
|
if let Some(ki) = ki.as_ref() {
|
||||||
if let Some(n) = (0..ki.num_additional()).find(|&n| ki.additional_ref(n) == 0x81) {
|
if let Some(n) = (0..ki.num_additional()).find(|&n| ki.additional_ref(n) == 0x81) {
|
||||||
let ks = ki.additional_status(n);
|
let ks = ki.additional_status(n);
|
||||||
attestation_key.status(format!("{}", ks));
|
attestation_key.status(format!("{ks}"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -76,9 +76,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
fn output_versions(chosen: OutputVersion) {
|
fn output_versions(chosen: OutputVersion) {
|
||||||
for v in OUTPUT_VERSIONS.iter() {
|
for v in OUTPUT_VERSIONS.iter() {
|
||||||
if v == &chosen {
|
if v == &chosen {
|
||||||
println!("* {}", v);
|
println!("* {v}");
|
||||||
} else {
|
} else {
|
||||||
println!(" {}", v);
|
println!(" {v}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ impl Info {
|
||||||
if !self.card_capabilities.is_empty() {
|
if !self.card_capabilities.is_empty() {
|
||||||
s.push_str("Card Capabilities:\n");
|
s.push_str("Card Capabilities:\n");
|
||||||
for c in self.card_capabilities.iter() {
|
for c in self.card_capabilities.iter() {
|
||||||
s.push_str(&format!("- {}\n", c));
|
s.push_str(&format!("- {c}\n"));
|
||||||
}
|
}
|
||||||
s.push('\n');
|
s.push('\n');
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ impl Info {
|
||||||
if !self.card_service_data.is_empty() {
|
if !self.card_service_data.is_empty() {
|
||||||
s.push_str("Card service data:\n");
|
s.push_str("Card service data:\n");
|
||||||
for c in self.card_service_data.iter() {
|
for c in self.card_service_data.iter() {
|
||||||
s.push_str(&format!("- {}\n", c));
|
s.push_str(&format!("- {c}\n"));
|
||||||
}
|
}
|
||||||
s.push('\n');
|
s.push('\n');
|
||||||
}
|
}
|
||||||
|
@ -101,27 +101,27 @@ impl Info {
|
||||||
if !self.extended_length_info.is_empty() {
|
if !self.extended_length_info.is_empty() {
|
||||||
s.push_str("Extended Length Info:\n");
|
s.push_str("Extended Length Info:\n");
|
||||||
for c in self.extended_length_info.iter() {
|
for c in self.extended_length_info.iter() {
|
||||||
s.push_str(&format!("- {}\n", c));
|
s.push_str(&format!("- {c}\n"));
|
||||||
}
|
}
|
||||||
s.push('\n');
|
s.push('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
s.push_str("Extended Capabilities:\n");
|
s.push_str("Extended Capabilities:\n");
|
||||||
for c in self.extended_capabilities.iter() {
|
for c in self.extended_capabilities.iter() {
|
||||||
s.push_str(&format!("- {}\n", c));
|
s.push_str(&format!("- {c}\n"));
|
||||||
}
|
}
|
||||||
s.push('\n');
|
s.push('\n');
|
||||||
|
|
||||||
if let Some(algos) = &self.algorithms {
|
if let Some(algos) = &self.algorithms {
|
||||||
s.push_str("Supported algorithms:\n");
|
s.push_str("Supported algorithms:\n");
|
||||||
for c in algos.iter() {
|
for c in algos.iter() {
|
||||||
s.push_str(&format!("- {}\n", c));
|
s.push_str(&format!("- {c}\n"));
|
||||||
}
|
}
|
||||||
s.push('\n');
|
s.push('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(v) = &self.firmware_version {
|
if let Some(v) = &self.firmware_version {
|
||||||
s.push_str(&format!("Firmware Version: {}\n", v));
|
s.push_str(&format!("Firmware Version: {v}\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(s)
|
Ok(s)
|
||||||
|
|
|
@ -22,7 +22,7 @@ impl List {
|
||||||
} else {
|
} else {
|
||||||
let mut s = "Available OpenPGP cards:\n".to_string();
|
let mut s = "Available OpenPGP cards:\n".to_string();
|
||||||
for id in self.idents.iter() {
|
for id in self.idents.iter() {
|
||||||
s.push_str(&format!(" {}\n", id));
|
s.push_str(&format!(" {id}\n"));
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,10 +30,10 @@ impl Ssh {
|
||||||
let mut s = format!("OpenPGP card {}\n\n", self.ident);
|
let mut s = format!("OpenPGP card {}\n\n", self.ident);
|
||||||
|
|
||||||
if let Some(fp) = &self.authentication_key_fingerprint {
|
if let Some(fp) = &self.authentication_key_fingerprint {
|
||||||
s.push_str(&format!("Authentication key fingerprint:\n{}\n\n", fp));
|
s.push_str(&format!("Authentication key fingerprint:\n{fp}\n\n"));
|
||||||
}
|
}
|
||||||
if let Some(key) = &self.ssh_public_key {
|
if let Some(key) = &self.ssh_public_key {
|
||||||
s.push_str(&format!("SSH public key:\n{}\n", key));
|
s.push_str(&format!("SSH public key:\n{key}\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(s)
|
Ok(s)
|
||||||
|
|
|
@ -112,14 +112,14 @@ impl Status {
|
||||||
let mut nl = false;
|
let mut nl = false;
|
||||||
if let Some(name) = &self.cardholder_name {
|
if let Some(name) = &self.cardholder_name {
|
||||||
if !name.is_empty() {
|
if !name.is_empty() {
|
||||||
s.push_str(&format!("Cardholder: {}\n", name));
|
s.push_str(&format!("Cardholder: {name}\n"));
|
||||||
nl = true;
|
nl = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(url) = &self.certificate_url {
|
if let Some(url) = &self.certificate_url {
|
||||||
if !url.is_empty() {
|
if !url.is_empty() {
|
||||||
s.push_str(&format!("Certificate URL: {}\n", url));
|
s.push_str(&format!("Certificate URL: {url}\n"));
|
||||||
nl = true;
|
nl = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ impl Status {
|
||||||
if !self.language_preferences.is_empty() {
|
if !self.language_preferences.is_empty() {
|
||||||
let prefs = self.language_preferences.to_vec().join(", ");
|
let prefs = self.language_preferences.to_vec().join(", ");
|
||||||
if !prefs.is_empty() {
|
if !prefs.is_empty() {
|
||||||
s.push_str(&format!("Language preferences: '{}'\n", prefs));
|
s.push_str(&format!("Language preferences: '{prefs}'\n"));
|
||||||
nl = true;
|
nl = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ impl Status {
|
||||||
|
|
||||||
s.push_str("Signature key:\n");
|
s.push_str("Signature key:\n");
|
||||||
for line in self.signature_key.format(self.verbose, self.pkm) {
|
for line in self.signature_key.format(self.verbose, self.pkm) {
|
||||||
s.push_str(&format!(" {}\n", line));
|
s.push_str(&format!(" {line}\n"));
|
||||||
}
|
}
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
if self.user_pin_valid_for_only_one_signature {
|
if self.user_pin_valid_for_only_one_signature {
|
||||||
|
@ -152,13 +152,13 @@ impl Status {
|
||||||
|
|
||||||
s.push_str("Decryption key:\n");
|
s.push_str("Decryption key:\n");
|
||||||
for line in self.decryption_key.format(self.verbose, self.pkm) {
|
for line in self.decryption_key.format(self.verbose, self.pkm) {
|
||||||
s.push_str(&format!(" {}\n", line));
|
s.push_str(&format!(" {line}\n"));
|
||||||
}
|
}
|
||||||
s.push('\n');
|
s.push('\n');
|
||||||
|
|
||||||
s.push_str("Authentication key:\n");
|
s.push_str("Authentication key:\n");
|
||||||
for line in self.authentication_key.format(self.verbose, self.pkm) {
|
for line in self.authentication_key.format(self.verbose, self.pkm) {
|
||||||
s.push_str(&format!(" {}\n", line));
|
s.push_str(&format!(" {line}\n"));
|
||||||
}
|
}
|
||||||
s.push('\n');
|
s.push('\n');
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ impl Status {
|
||||||
if attestation_key.touch_policy.is_some() || attestation_key.algorithm.is_some() {
|
if attestation_key.touch_policy.is_some() || attestation_key.algorithm.is_some() {
|
||||||
s.push_str("Attestation key:\n");
|
s.push_str("Attestation key:\n");
|
||||||
for line in attestation_key.format(self.verbose, self.pkm) {
|
for line in attestation_key.format(self.verbose, self.pkm) {
|
||||||
s.push_str(&format!(" {}\n", line));
|
s.push_str(&format!(" {line}\n"));
|
||||||
}
|
}
|
||||||
s.push('\n');
|
s.push('\n');
|
||||||
}
|
}
|
||||||
|
@ -183,10 +183,7 @@ impl Status {
|
||||||
|
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
for (keyref, status) in self.additional_key_statuses.iter() {
|
for (keyref, status) in self.additional_key_statuses.iter() {
|
||||||
s.push_str(&format!(
|
s.push_str(&format!("Additional key status (#{keyref}): {status}\n"));
|
||||||
"Additional key status (#{}): {}\n",
|
|
||||||
keyref, status
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,30 +308,30 @@ impl KeySlotInfo {
|
||||||
let mut lines = vec![];
|
let mut lines = vec![];
|
||||||
|
|
||||||
if let Some(fp) = &self.fingerprint {
|
if let Some(fp) = &self.fingerprint {
|
||||||
lines.push(format!("Fingerprint: {}", fp));
|
lines.push(format!("Fingerprint: {fp}"));
|
||||||
} else {
|
} else {
|
||||||
lines.push("Fingerprint: [unset]".to_string());
|
lines.push("Fingerprint: [unset]".to_string());
|
||||||
}
|
}
|
||||||
if let Some(ts) = &self.creation_time {
|
if let Some(ts) = &self.creation_time {
|
||||||
lines.push(format!("Creation Time: {}", ts));
|
lines.push(format!("Creation Time: {ts}"));
|
||||||
}
|
}
|
||||||
if let Some(a) = &self.algorithm {
|
if let Some(a) = &self.algorithm {
|
||||||
lines.push(format!("Algorithm: {}", a));
|
lines.push(format!("Algorithm: {a}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if verbose {
|
if verbose {
|
||||||
if let Some(policy) = &self.touch_policy {
|
if let Some(policy) = &self.touch_policy {
|
||||||
if let Some(features) = &self.touch_features {
|
if let Some(features) = &self.touch_features {
|
||||||
lines.push(format!("Touch policy: {} (features: {})", policy, features));
|
lines.push(format!("Touch policy: {policy} (features: {features})"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(status) = &self.status {
|
if let Some(status) = &self.status {
|
||||||
lines.push(format!("Key Status: {}", status));
|
lines.push(format!("Key Status: {status}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if pkm {
|
if pkm {
|
||||||
if let Some(material) = &self.public_key_material {
|
if let Some(material) = &self.public_key_material {
|
||||||
lines.push(format!("Public key material: {}", material));
|
lines.push(format!("Public key material: {material}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@ pub(crate) fn open_or_stdout(f: Option<&Path>) -> Result<Box<dyn std::io::Write
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_ssh_pubkey(pkm: &PublicKeyMaterial, ident: String) -> Result<sshkeys::PublicKey> {
|
fn get_ssh_pubkey(pkm: &PublicKeyMaterial, ident: String) -> Result<sshkeys::PublicKey> {
|
||||||
let cardname = format!("opgpcard:{}", ident);
|
let cardname = format!("opgpcard:{ident}");
|
||||||
|
|
||||||
let (key_type, kind) = match pkm {
|
let (key_type, kind) = match pkm {
|
||||||
PublicKeyMaterial::R(rsa) => {
|
PublicKeyMaterial::R(rsa) => {
|
||||||
|
|
Loading…
Reference in a new issue