diff --git a/Cargo.lock b/Cargo.lock index 99790fb..1c4be6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1788,7 +1788,7 @@ dependencies = [ [[package]] name = "tiny-encrypt" -version = "1.7.3" +version = "1.7.4" dependencies = [ "aes-gcm-stream", "base64", diff --git a/Cargo.toml b/Cargo.toml index 206ef8a..d486bb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tiny-encrypt" -version = "1.7.3" +version = "1.7.4" edition = "2021" license = "MIT" description = "A simple and tiny file encrypt tool" diff --git a/src/cmd_decrypt.rs b/src/cmd_decrypt.rs index 8d399be..0bbc62e 100644 --- a/src/cmd_decrypt.rs +++ b/src/cmd_decrypt.rs @@ -176,9 +176,9 @@ pub fn decrypt_single(config: &Option, let digest_algorithm = cmd_decrypt.digest_algorithm.as_deref().unwrap_or("sha256"); if cmd_decrypt.digest_file { DigestWrite::from_algo(digest_algorithm)?; } // FAST CHECK - let selected_envelop = select_envelop(&meta, key_id, config)?; + let selected_envelop = select_envelop(&meta, key_id, config, false)?; - let key = SecVec(try_decrypt_key(config, selected_envelop, pin, slot)?); + let key = SecVec(try_decrypt_key(config, selected_envelop, pin, slot, false)?); let nonce = SecVec(opt_result!(util::decode_base64(&meta.nonce), "Decode nonce failed: {}")); let key_nonce = KeyNonce { k: key.as_ref(), n: nonce.as_ref() }; @@ -454,17 +454,18 @@ fn parse_encrypted_meta(meta: &TinyEncryptMeta, cryptor: Cryptor, key_nonce: &Ke pub fn try_decrypt_key(config: &Option, envelop: &TinyEncryptEnvelop, pin: &Option, - slot: &Option) -> XResult> { + slot: &Option, + silent: bool) -> XResult> { match envelop.r#type { TinyEncryptEnvelopType::PgpRsa => try_decrypt_key_pgp_rsa(envelop, pin), TinyEncryptEnvelopType::PgpX25519 => try_decrypt_key_ecdh_pgp_x25519(envelop, pin), TinyEncryptEnvelopType::Gpg => try_decrypt_key_gpg(envelop), #[cfg(feature = "macos")] TinyEncryptEnvelopType::StaticX25519 => try_decrypt_key_ecdh_static_x25519(config, envelop), - TinyEncryptEnvelopType::PivP256 | TinyEncryptEnvelopType::PivP384 => try_decrypt_piv_key_ecdh(config, envelop, pin, slot), + TinyEncryptEnvelopType::PivP256 | TinyEncryptEnvelopType::PivP384 => try_decrypt_piv_key_ecdh(config, envelop, pin, slot, silent), #[cfg(feature = "secure-enclave")] TinyEncryptEnvelopType::KeyP256 => try_decrypt_se_key_ecdh(config, envelop), - TinyEncryptEnvelopType::PivRsa => try_decrypt_piv_key_rsa(config, envelop, pin, slot), + TinyEncryptEnvelopType::PivRsa => try_decrypt_piv_key_rsa(config, envelop, pin, slot, silent), #[cfg(feature = "macos")] TinyEncryptEnvelopType::StaticKyber1024 => try_decrypt_key_ecdh_static_kyber1204(config, envelop), unknown_type => simple_error!("Unknown or unsupported type: {}", unknown_type.get_name()), @@ -474,7 +475,8 @@ pub fn try_decrypt_key(config: &Option, fn try_decrypt_piv_key_ecdh(config: &Option, envelop: &TinyEncryptEnvelop, pin: &Option, - slot: &Option) -> XResult> { + slot: &Option, + silent: bool) -> XResult> { let wrap_key = WrapKey::parse(&envelop.encrypted_key)?; let (cryptor, algo_id) = match wrap_key.header.enc.as_str() { ENC_AES256_GCM_P256 => (Cryptor::Aes256Gcm, AlgorithmId::EccP256), @@ -487,7 +489,7 @@ fn try_decrypt_piv_key_ecdh(config: &Option, let (_, subject_public_key_info) = opt_result!( SubjectPublicKeyInfo::from_der(&e_pub_key_bytes), "Invalid envelop: {}"); - let slot = util_piv::read_piv_slot(config, &envelop.kid, slot)?; + let slot = util_piv::read_piv_slot(config, &envelop.kid, slot, silent)?; let pin = util::read_pin(pin)?; let epk_bytes = subject_public_key_info.subject_public_key.as_ref(); @@ -514,10 +516,11 @@ fn try_decrypt_piv_key_ecdh(config: &Option, fn try_decrypt_piv_key_rsa(config: &Option, envelop: &TinyEncryptEnvelop, pin: &Option, - slot: &Option) -> XResult> { + slot: &Option, + silent: bool) -> XResult> { let encrypted_key_bytes = opt_result!(util::decode_base64(&envelop.encrypted_key), "Decode encrypt key failed: {}"); - let slot = util_piv::read_piv_slot(config, &envelop.kid, slot)?; + let slot = util_piv::read_piv_slot(config, &envelop.kid, slot, silent)?; let pin = util::read_pin(pin)?; let mut yk = opt_result!(YubiKey::open(), "YubiKey not found: {}"); @@ -699,7 +702,7 @@ fn try_decrypt_key_pgp_rsa(envelop: &TinyEncryptEnvelop, pin: &Option) - Ok(key) } -pub fn select_envelop<'a>(meta: &'a TinyEncryptMeta, key_id: &Option, config: &Option) -> XResult<&'a TinyEncryptEnvelop> { +pub fn select_envelop<'a>(meta: &'a TinyEncryptMeta, key_id: &Option, config: &Option, silent: bool) -> XResult<&'a TinyEncryptEnvelop> { let envelops = match &meta.envelops { None => return simple_error!("No envelops found"), Some(envelops) => if envelops.is_empty() { @@ -709,14 +712,22 @@ pub fn select_envelop<'a>(meta: &'a TinyEncryptMeta, key_id: &Option, co }, }; - success!("Found {} envelops:", envelops.len()); - if let Some(envelop) = match_envelop_by_key_id(envelops, key_id, config) { + if silent { + debugging!("Found {} envelops:", envelops.len()); + } else { + success!("Found {} envelops:", envelops.len()); + } + if let Some(envelop) = match_envelop_by_key_id(envelops, key_id, config, silent) { return Ok(envelop); } if envelops.len() == 1 { let selected_envelop = &envelops[0]; - success!("Auto selected envelop: #{} {}", 1, util_envelop::format_envelop(selected_envelop, config)); + if silent { + debugging!("Auto selected envelop: #{} {}", 1, util_envelop::format_envelop(selected_envelop, config)); + } else { + success!("Auto selected envelop: #{} {}", 1, util_envelop::format_envelop(selected_envelop, config)); + } if !selected_envelop.r#type.auto_select() { util::read_line("Press enter to continue: "); } @@ -726,7 +737,7 @@ pub fn select_envelop<'a>(meta: &'a TinyEncryptMeta, key_id: &Option, co // auto select if let Some(auto_select_key_ids) = util_env::get_auto_select_key_ids() { for auto_select_key_id in auto_select_key_ids { - if let Some(envelop) = match_envelop_by_key_id(envelops, &Some(auto_select_key_id), config) { + if let Some(envelop) = match_envelop_by_key_id(envelops, &Some(auto_select_key_id), config, silent) { return Ok(envelop); } } @@ -738,11 +749,15 @@ pub fn select_envelop<'a>(meta: &'a TinyEncryptMeta, key_id: &Option, co let envelop_number = util::read_number("Please select an envelop:", 1, envelops.len()); let selected_envelop = &envelops[envelop_number - 1]; - success!("Selected envelop: #{} {}", envelop_number, selected_envelop.r#type.get_upper_name()); + if silent { + debugging!("Selected envelop: #{} {}", envelop_number, selected_envelop.r#type.get_upper_name()); + } else { + success!("Selected envelop: #{} {}", envelop_number, selected_envelop.r#type.get_upper_name()); + } Ok(selected_envelop) } -fn match_envelop_by_key_id<'a>(envelops: &'a Vec, key_id: &Option, config: &Option) -> Option<&'a TinyEncryptEnvelop> { +fn match_envelop_by_key_id<'a>(envelops: &'a Vec, key_id: &Option, config: &Option, silent: bool) -> Option<&'a TinyEncryptEnvelop> { if let Some(key_id) = key_id { for envelop in envelops { let is_sid_matched = config.as_ref().and_then(|config| { @@ -752,7 +767,11 @@ fn match_envelop_by_key_id<'a>(envelops: &'a Vec, key_id: &O }).unwrap_or(false); if is_sid_matched || (&envelop.kid == key_id) { - information!("Matched envelop: {}", util_envelop::format_envelop(envelop, config)); + if silent { + debugging!("Matched envelop: {}", util_envelop::format_envelop(envelop, config)); + } else { + information!("Matched envelop: {}", util_envelop::format_envelop(envelop, config)); + } return Some(envelop); } } diff --git a/src/cmd_execenv.rs b/src/cmd_execenv.rs index 15c64c1..3c1bf04 100644 --- a/src/cmd_execenv.rs +++ b/src/cmd_execenv.rs @@ -4,7 +4,7 @@ use std::process::Command; use std::time::Instant; use clap::Args; -use rust_util::{debugging, iff, information, opt_result, simple_error, util_cmd, util_msg, warning, XResult}; +use rust_util::{debugging, iff, opt_result, simple_error, util_cmd, util_msg, warning, XResult}; use serde_json::Value; use zeroize::Zeroize; @@ -71,9 +71,9 @@ pub fn exec_env(cmd_exec_env: CmdExecEnv) -> XResult<()> { .unwrap_or(consts::TINY_ENC_AES_GCM); let cryptor = Cryptor::from(encryption_algorithm)?; - let selected_envelop = select_envelop(&meta, &key_id, &config)?; + let selected_envelop = select_envelop(&meta, &key_id, &config, true)?; - let key = SecVec(try_decrypt_key(&config, selected_envelop, &pin, &cmd_exec_env.slot)?); + let key = SecVec(try_decrypt_key(&config, selected_envelop, &pin, &cmd_exec_env.slot, true)?); let nonce = SecVec(opt_result!(util::decode_base64(&meta.nonce), "Decode nonce failed: {}")); let key_nonce = KeyNonce { k: key.as_ref(), n: nonce.as_ref() }; @@ -95,7 +95,7 @@ pub fn exec_env(cmd_exec_env: CmdExecEnv) -> XResult<()> { -1 }; - information!("Finished, cost: {}ms", start.elapsed().as_millis()); + debugging!("Finished, cost: {}ms", start.elapsed().as_millis()); std::process::exit(exit_code); } diff --git a/src/util_piv.rs b/src/util_piv.rs index 5a04e10..2f256a4 100644 --- a/src/util_piv.rs +++ b/src/util_piv.rs @@ -1,18 +1,22 @@ use std::io; use std::io::Write; -use rust_util::{information, print_ex, simple_error, XResult}; +use rust_util::{debugging, information, print_ex, simple_error, XResult}; use yubikey::piv::{RetiredSlotId, SlotId}; use crate::config::TinyEncryptConfig; -pub fn read_piv_slot(config: &Option, kid: &str, slot: &Option) -> XResult { +pub fn read_piv_slot(config: &Option, kid: &str, slot: &Option, silent: bool) -> XResult { match slot { Some(slot) => Ok(slot.to_string()), None => { if let Some(config) = config { if let Some(first_arg) = config.find_first_arg_by_kid(kid) { - information!("Found kid: {}'s slot: {}", kid, first_arg); + if silent { + debugging!("Found kid: {}'s slot: {}", kid, first_arg); + } else { + information!("Found kid: {}'s slot: {}", kid, first_arg); + } return Ok(first_arg.to_string()); } }