feat: v1.7.4, add slient mod for exec-env
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1788,7 +1788,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiny-encrypt"
|
name = "tiny-encrypt"
|
||||||
version = "1.7.3"
|
version = "1.7.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes-gcm-stream",
|
"aes-gcm-stream",
|
||||||
"base64",
|
"base64",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tiny-encrypt"
|
name = "tiny-encrypt"
|
||||||
version = "1.7.3"
|
version = "1.7.4"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "A simple and tiny file encrypt tool"
|
description = "A simple and tiny file encrypt tool"
|
||||||
|
|||||||
@@ -176,9 +176,9 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
|
|||||||
let digest_algorithm = cmd_decrypt.digest_algorithm.as_deref().unwrap_or("sha256");
|
let digest_algorithm = cmd_decrypt.digest_algorithm.as_deref().unwrap_or("sha256");
|
||||||
if cmd_decrypt.digest_file { DigestWrite::from_algo(digest_algorithm)?; } // FAST CHECK
|
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 nonce = SecVec(opt_result!(util::decode_base64(&meta.nonce), "Decode nonce failed: {}"));
|
||||||
let key_nonce = KeyNonce { k: key.as_ref(), n: nonce.as_ref() };
|
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<TinyEncryptConfig>,
|
pub fn try_decrypt_key(config: &Option<TinyEncryptConfig>,
|
||||||
envelop: &TinyEncryptEnvelop,
|
envelop: &TinyEncryptEnvelop,
|
||||||
pin: &Option<String>,
|
pin: &Option<String>,
|
||||||
slot: &Option<String>) -> XResult<Vec<u8>> {
|
slot: &Option<String>,
|
||||||
|
silent: bool) -> XResult<Vec<u8>> {
|
||||||
match envelop.r#type {
|
match envelop.r#type {
|
||||||
TinyEncryptEnvelopType::PgpRsa => try_decrypt_key_pgp_rsa(envelop, pin),
|
TinyEncryptEnvelopType::PgpRsa => try_decrypt_key_pgp_rsa(envelop, pin),
|
||||||
TinyEncryptEnvelopType::PgpX25519 => try_decrypt_key_ecdh_pgp_x25519(envelop, pin),
|
TinyEncryptEnvelopType::PgpX25519 => try_decrypt_key_ecdh_pgp_x25519(envelop, pin),
|
||||||
TinyEncryptEnvelopType::Gpg => try_decrypt_key_gpg(envelop),
|
TinyEncryptEnvelopType::Gpg => try_decrypt_key_gpg(envelop),
|
||||||
#[cfg(feature = "macos")]
|
#[cfg(feature = "macos")]
|
||||||
TinyEncryptEnvelopType::StaticX25519 => try_decrypt_key_ecdh_static_x25519(config, envelop),
|
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")]
|
#[cfg(feature = "secure-enclave")]
|
||||||
TinyEncryptEnvelopType::KeyP256 => try_decrypt_se_key_ecdh(config, envelop),
|
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")]
|
#[cfg(feature = "macos")]
|
||||||
TinyEncryptEnvelopType::StaticKyber1024 => try_decrypt_key_ecdh_static_kyber1204(config, envelop),
|
TinyEncryptEnvelopType::StaticKyber1024 => try_decrypt_key_ecdh_static_kyber1204(config, envelop),
|
||||||
unknown_type => simple_error!("Unknown or unsupported type: {}", unknown_type.get_name()),
|
unknown_type => simple_error!("Unknown or unsupported type: {}", unknown_type.get_name()),
|
||||||
@@ -474,7 +475,8 @@ pub fn try_decrypt_key(config: &Option<TinyEncryptConfig>,
|
|||||||
fn try_decrypt_piv_key_ecdh(config: &Option<TinyEncryptConfig>,
|
fn try_decrypt_piv_key_ecdh(config: &Option<TinyEncryptConfig>,
|
||||||
envelop: &TinyEncryptEnvelop,
|
envelop: &TinyEncryptEnvelop,
|
||||||
pin: &Option<String>,
|
pin: &Option<String>,
|
||||||
slot: &Option<String>) -> XResult<Vec<u8>> {
|
slot: &Option<String>,
|
||||||
|
silent: bool) -> XResult<Vec<u8>> {
|
||||||
let wrap_key = WrapKey::parse(&envelop.encrypted_key)?;
|
let wrap_key = WrapKey::parse(&envelop.encrypted_key)?;
|
||||||
let (cryptor, algo_id) = match wrap_key.header.enc.as_str() {
|
let (cryptor, algo_id) = match wrap_key.header.enc.as_str() {
|
||||||
ENC_AES256_GCM_P256 => (Cryptor::Aes256Gcm, AlgorithmId::EccP256),
|
ENC_AES256_GCM_P256 => (Cryptor::Aes256Gcm, AlgorithmId::EccP256),
|
||||||
@@ -487,7 +489,7 @@ fn try_decrypt_piv_key_ecdh(config: &Option<TinyEncryptConfig>,
|
|||||||
let (_, subject_public_key_info) = opt_result!(
|
let (_, subject_public_key_info) = opt_result!(
|
||||||
SubjectPublicKeyInfo::from_der(&e_pub_key_bytes), "Invalid envelop: {}");
|
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 pin = util::read_pin(pin)?;
|
||||||
let epk_bytes = subject_public_key_info.subject_public_key.as_ref();
|
let epk_bytes = subject_public_key_info.subject_public_key.as_ref();
|
||||||
|
|
||||||
@@ -514,10 +516,11 @@ fn try_decrypt_piv_key_ecdh(config: &Option<TinyEncryptConfig>,
|
|||||||
fn try_decrypt_piv_key_rsa(config: &Option<TinyEncryptConfig>,
|
fn try_decrypt_piv_key_rsa(config: &Option<TinyEncryptConfig>,
|
||||||
envelop: &TinyEncryptEnvelop,
|
envelop: &TinyEncryptEnvelop,
|
||||||
pin: &Option<String>,
|
pin: &Option<String>,
|
||||||
slot: &Option<String>) -> XResult<Vec<u8>> {
|
slot: &Option<String>,
|
||||||
|
silent: bool) -> XResult<Vec<u8>> {
|
||||||
let encrypted_key_bytes = opt_result!(util::decode_base64(&envelop.encrypted_key), "Decode encrypt key failed: {}");
|
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 pin = util::read_pin(pin)?;
|
||||||
|
|
||||||
let mut yk = opt_result!(YubiKey::open(), "YubiKey not found: {}");
|
let mut yk = opt_result!(YubiKey::open(), "YubiKey not found: {}");
|
||||||
@@ -699,7 +702,7 @@ fn try_decrypt_key_pgp_rsa(envelop: &TinyEncryptEnvelop, pin: &Option<String>) -
|
|||||||
Ok(key)
|
Ok(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_envelop<'a>(meta: &'a TinyEncryptMeta, key_id: &Option<String>, config: &Option<TinyEncryptConfig>) -> XResult<&'a TinyEncryptEnvelop> {
|
pub fn select_envelop<'a>(meta: &'a TinyEncryptMeta, key_id: &Option<String>, config: &Option<TinyEncryptConfig>, silent: bool) -> XResult<&'a TinyEncryptEnvelop> {
|
||||||
let envelops = match &meta.envelops {
|
let envelops = match &meta.envelops {
|
||||||
None => return simple_error!("No envelops found"),
|
None => return simple_error!("No envelops found"),
|
||||||
Some(envelops) => if envelops.is_empty() {
|
Some(envelops) => if envelops.is_empty() {
|
||||||
@@ -709,14 +712,22 @@ pub fn select_envelop<'a>(meta: &'a TinyEncryptMeta, key_id: &Option<String>, co
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
success!("Found {} envelops:", envelops.len());
|
if silent {
|
||||||
if let Some(envelop) = match_envelop_by_key_id(envelops, key_id, config) {
|
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);
|
return Ok(envelop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if envelops.len() == 1 {
|
if envelops.len() == 1 {
|
||||||
let selected_envelop = &envelops[0];
|
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() {
|
if !selected_envelop.r#type.auto_select() {
|
||||||
util::read_line("Press enter to continue: ");
|
util::read_line("Press enter to continue: ");
|
||||||
}
|
}
|
||||||
@@ -726,7 +737,7 @@ pub fn select_envelop<'a>(meta: &'a TinyEncryptMeta, key_id: &Option<String>, co
|
|||||||
// auto select
|
// auto select
|
||||||
if let Some(auto_select_key_ids) = util_env::get_auto_select_key_ids() {
|
if let Some(auto_select_key_ids) = util_env::get_auto_select_key_ids() {
|
||||||
for auto_select_key_id in 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);
|
return Ok(envelop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -738,11 +749,15 @@ pub fn select_envelop<'a>(meta: &'a TinyEncryptMeta, key_id: &Option<String>, co
|
|||||||
|
|
||||||
let envelop_number = util::read_number("Please select an envelop:", 1, envelops.len());
|
let envelop_number = util::read_number("Please select an envelop:", 1, envelops.len());
|
||||||
let selected_envelop = &envelops[envelop_number - 1];
|
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)
|
Ok(selected_envelop)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_envelop_by_key_id<'a>(envelops: &'a Vec<TinyEncryptEnvelop>, key_id: &Option<String>, config: &Option<TinyEncryptConfig>) -> Option<&'a TinyEncryptEnvelop> {
|
fn match_envelop_by_key_id<'a>(envelops: &'a Vec<TinyEncryptEnvelop>, key_id: &Option<String>, config: &Option<TinyEncryptConfig>, silent: bool) -> Option<&'a TinyEncryptEnvelop> {
|
||||||
if let Some(key_id) = key_id {
|
if let Some(key_id) = key_id {
|
||||||
for envelop in envelops {
|
for envelop in envelops {
|
||||||
let is_sid_matched = config.as_ref().and_then(|config| {
|
let is_sid_matched = config.as_ref().and_then(|config| {
|
||||||
@@ -752,7 +767,11 @@ fn match_envelop_by_key_id<'a>(envelops: &'a Vec<TinyEncryptEnvelop>, key_id: &O
|
|||||||
}).unwrap_or(false);
|
}).unwrap_or(false);
|
||||||
|
|
||||||
if is_sid_matched || (&envelop.kid == key_id) {
|
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);
|
return Some(envelop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::process::Command;
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use clap::Args;
|
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 serde_json::Value;
|
||||||
use zeroize::Zeroize;
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
@@ -71,9 +71,9 @@ pub fn exec_env(cmd_exec_env: CmdExecEnv) -> XResult<()> {
|
|||||||
.unwrap_or(consts::TINY_ENC_AES_GCM);
|
.unwrap_or(consts::TINY_ENC_AES_GCM);
|
||||||
let cryptor = Cryptor::from(encryption_algorithm)?;
|
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 nonce = SecVec(opt_result!(util::decode_base64(&meta.nonce), "Decode nonce failed: {}"));
|
||||||
let key_nonce = KeyNonce { k: key.as_ref(), n: nonce.as_ref() };
|
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
|
-1
|
||||||
};
|
};
|
||||||
|
|
||||||
information!("Finished, cost: {}ms", start.elapsed().as_millis());
|
debugging!("Finished, cost: {}ms", start.elapsed().as_millis());
|
||||||
std::process::exit(exit_code);
|
std::process::exit(exit_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Write;
|
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 yubikey::piv::{RetiredSlotId, SlotId};
|
||||||
|
|
||||||
use crate::config::TinyEncryptConfig;
|
use crate::config::TinyEncryptConfig;
|
||||||
|
|
||||||
pub fn read_piv_slot(config: &Option<TinyEncryptConfig>, kid: &str, slot: &Option<String>) -> XResult<String> {
|
pub fn read_piv_slot(config: &Option<TinyEncryptConfig>, kid: &str, slot: &Option<String>, silent: bool) -> XResult<String> {
|
||||||
match slot {
|
match slot {
|
||||||
Some(slot) => Ok(slot.to_string()),
|
Some(slot) => Ok(slot.to_string()),
|
||||||
None => {
|
None => {
|
||||||
if let Some(config) = config {
|
if let Some(config) = config {
|
||||||
if let Some(first_arg) = config.find_first_arg_by_kid(kid) {
|
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());
|
return Ok(first_arg.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user