♻️ Refactor smartcard backend and update PGP decryption dependencies

This commit is contained in:
2026-05-21 23:56:38 +08:00
parent a7615228cc
commit 6a17e6c770
4 changed files with 43 additions and 43 deletions
Generated
+28 -29
View File
@@ -172,17 +172,6 @@ version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
[[package]]
name = "blanket"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0b121a9fe0df916e362fb3271088d071159cdf11db0e4182d02152850756eff"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
@@ -213,6 +202,27 @@ version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e"
[[package]]
name = "card-backend"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd3ee3a298842065dc489180c34a4fe4bbbb8643bb422009d79558a099fb42e5"
dependencies = [
"thiserror 1.0.69",
]
[[package]]
name = "card-backend-pcsc"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9abd829326b7cbf5e71dc81485f4bc839ac938813f6e5e02c9033b6dee71f1e"
dependencies = [
"card-backend",
"iso7816-tlv",
"log",
"pcsc",
]
[[package]]
name = "cc"
version = "1.2.62"
@@ -1266,28 +1276,17 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "openpgp-card"
version = "0.3.7"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb1e95b6b2691f6604146cddc9f57e94cdd21c3be7d3629a058f8863ee9c92d"
checksum = "c5a3953947ab2bc105fd007670101c13a61e4fc41f04cd1b537f6fabbbc16a7b"
dependencies = [
"blanket",
"chrono",
"card-backend",
"hex-slice",
"log",
"nom",
"thiserror 1.0.69",
]
[[package]]
name = "openpgp-card-pcsc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb6ccdfe0c0b8535e83310178b725e8ee0ff676d73b649cf3e56369185da6a6b"
dependencies = [
"iso7816-tlv",
"log",
"openpgp-card",
"pcsc",
"secrecy 0.10.3",
"sha2",
"thiserror 2.0.18",
]
[[package]]
@@ -2221,6 +2220,7 @@ version = "1.9.20"
dependencies = [
"aes-gcm-stream",
"base64 0.22.1",
"card-backend-pcsc",
"chacha20-poly1305-stream",
"chrono",
"clap",
@@ -2234,7 +2234,6 @@ dependencies = [
"json5",
"ml-kem",
"openpgp-card",
"openpgp-card-pcsc",
"p256",
"p384",
"percent-encoding",
+3 -3
View File
@@ -12,7 +12,7 @@ repository = "https://git.hatter.ink/hatter/tiny-encrypt-rs"
default = ["decrypt", "macos", "smartcard"]
full-features = ["decrypt", "macos", "smartcard"]
decrypt = ["smartcard"]
smartcard = ["openpgp-card", "openpgp-card-pcsc", "yubikey"]
smartcard = ["openpgp-card", "card-backend-pcsc", "yubikey"]
macos = ["security-framework"]
[dependencies]
@@ -25,8 +25,7 @@ flate2 = "1.0"
fs-set-times = "0.20"
hex = "0.4"
indicatif = "0.18"
openpgp-card = { version = "0.3", optional = true }
openpgp-card-pcsc = { version = "0.3", optional = true }
openpgp-card = { version = "0.6", optional = true }
p256 = { version = "0.13", features = ["pem", "ecdh", "pkcs8"] }
p384 = { version = "0.13", features = ["pem", "ecdh", "pkcs8"] }
rand = "0.8"
@@ -57,6 +56,7 @@ external-command-rs = "0.1"
percent-encoding = "2.3"
ml-kem = { version = "0.2.1", features = ["zeroize"] }
zeroizing-alloc = "0.1.0"
card-backend-pcsc = { version = "0.5.1", optional = true }
[profile.release]
codegen-units = 1
+3 -3
View File
@@ -11,7 +11,7 @@ use dialoguer::console::Term;
use dialoguer::Select;
use dialoguer::theme::ColorfulTheme;
use flate2::Compression;
use openpgp_card::crypto_data::Cryptogram;
use openpgp_card::ocard::crypto::Cryptogram;
use rust_util::{
debugging, failure, iff, information, opt_result, opt_value_result, println_ex, simple_error, success,
util_cmd, util_msg, util_size, util_time, warning, XResult,
@@ -664,7 +664,7 @@ fn try_decrypt_key_ecdh_pgp_x25519(envelop: &TinyEncryptEnvelop, pin: &Option<St
util_pgp::read_and_verify_openpgp_pin(&mut trans, pin)?;
let shared_secret = trans.decipher(Cryptogram::ECDH(&e_pub_key_bytes))?;
let shared_secret = trans.card().decipher(Cryptogram::ECDH(&e_pub_key_bytes))?;
let key = util::simple_kdf(shared_secret.as_slice());
let key_nonce = KeyNonce { k: &key, n: &wrap_key.nonce };
@@ -759,7 +759,7 @@ fn try_decrypt_key_pgp_rsa(envelop: &TinyEncryptEnvelop, pin: &Option<String>) -
debugging!("PGP envelop: {}", pgp_envelop);
let pgp_envelop_bytes = opt_result!(util::decode_base64(pgp_envelop), "Decode PGP envelop failed: {}");
let key = trans.decipher(Cryptogram::RSA(&pgp_envelop_bytes))?;
let key = trans.card().decipher(Cryptogram::RSA(&pgp_envelop_bytes))?;
Ok(key)
}
+9 -8
View File
@@ -1,12 +1,12 @@
use openpgp_card::{OpenPgp, OpenPgpTransaction};
use openpgp_card_pcsc::PcscBackend;
use card_backend_pcsc::PcscBackend;
use openpgp_card::Card;
use rust_util::{failure, opt_result, opt_value_result, simple_error, success, warning, XResult};
use crate::util;
pub fn read_and_verify_openpgp_pin(trans: &mut OpenPgpTransaction, pin: &Option<String>) -> XResult<()> {
pub fn read_and_verify_openpgp_pin(trans: &mut Card<openpgp_card::state::Transaction<'_>>, pin: &Option<String>) -> XResult<()> {
let pin = util::read_pin(pin)?;
if let Err(e) = trans.verify_pw1_user(pin.as_ref()) {
if let Err(e) = trans.verify_user_pin(pin.as_str().into()) {
failure!("Verify user pin failed: {}", e);
return simple_error!("User pin verify failed: {}", e);
}
@@ -15,20 +15,21 @@ pub fn read_and_verify_openpgp_pin(trans: &mut OpenPgpTransaction, pin: &Option<
Ok(())
}
pub fn get_openpgp() -> XResult<OpenPgp> {
pub fn get_openpgp() -> XResult<Card<openpgp_card::state::Open>> {
let card = match get_card() {
Err(e) => {
return simple_error!("Get card failed: {}", e);
}
Ok(card) => card
};
Ok(OpenPgp::new(card))
Ok(Card::new(card)?)
}
pub fn get_card() -> XResult<PcscBackend> {
let card_list = opt_result!(
let card_list: Vec<_> = opt_result!(
PcscBackend::cards(None), "Read OpenPGP card list failed: {}"
);
).collect();
let card_list: Vec<_> = card_list.into_iter().filter_map(|r| r.ok()).collect();
if card_list.is_empty() {
return simple_error!("Cannot find any card");
}