feat: supports -R

This commit is contained in:
2023-09-30 21:40:27 +08:00
parent b8ef9b5239
commit 71ebe68a86
2 changed files with 32 additions and 10 deletions

View File

@@ -1,5 +1,5 @@
use std::{fs, io};
use std::fs::File;
use std::io;
use std::io::{Read, Write};
use std::path::PathBuf;
use std::str::FromStr;
@@ -8,7 +8,7 @@ use std::time::Instant;
use clap::Args;
use openpgp_card::crypto_data::Cryptogram;
use openpgp_card::OpenPgp;
use rust_util::{debugging, failure, opt_result, simple_error, success, util_term, XResult};
use rust_util::{debugging, failure, information, opt_result, simple_error, success, util_term, warning, XResult};
use x509_parser::prelude::FromDer;
use x509_parser::x509::SubjectPublicKeyInfo;
use yubikey::piv::{AlgorithmId, decrypt_data, RetiredSlotId, SlotId};
@@ -32,12 +32,15 @@ pub struct CmdDecrypt {
/// Slot
#[arg(long, short = 's')]
pub slot: Option<String>,
/// Remove source file
#[arg(long, short = 'R')]
pub remove_source_file: bool,
}
pub fn decrypt(cmd_decrypt: CmdDecrypt) -> XResult<()> {
debugging!("Cmd decrypt: {:?}", cmd_decrypt);
for path in &cmd_decrypt.paths {
match decrypt_single(path, &cmd_decrypt.pin, &cmd_decrypt.slot) {
match decrypt_single(path, &cmd_decrypt.pin, &cmd_decrypt.slot, &cmd_decrypt) {
Ok(_) => success!("Decrypt {} succeed", path.to_str().unwrap_or("N/A")),
Err(e) => failure!("Decrypt {} failed: {}", path.to_str().unwrap_or("N/A"), e),
}
@@ -45,7 +48,7 @@ pub fn decrypt(cmd_decrypt: CmdDecrypt) -> XResult<()> {
Ok(())
}
pub fn decrypt_single(path: &PathBuf, pin: &Option<String>, slot: &Option<String>) -> XResult<()> {
pub fn decrypt_single(path: &PathBuf, pin: &Option<String>, slot: &Option<String>, cmd_decrypt: &CmdDecrypt) -> XResult<()> {
let path_display = format!("{}", path.display());
util::require_tiny_enc_file_and_exists(path)?;
@@ -73,6 +76,14 @@ pub fn decrypt_single(path: &PathBuf, pin: &Option<String>, slot: &Option<String
util::zeroize(key);
util::zeroize(nonce);
drop(file_in);
drop(file_out);
if cmd_decrypt.remove_source_file {
match fs::remove_file(path) {
Err(e) => warning!("Remove file: {} failed: {}", path_display, e),
Ok(_) => information!("Remove file: {} succeed", path_display),
}
}
Ok(())
}
@@ -141,7 +152,7 @@ fn try_decrypt_key_ecdh(envelop: &TinyEncryptEnvelop, pin: &Option<String>, slot
&epk_bytes,
AlgorithmId::EccP256,
slot_id,
), "Decrypt piv failed: {}");
), "Decrypt via PIV card failed: {}");
let key = simple_kdf(decrypted_shared_secret.as_slice());
let decrypted_key = aes_gcm_decrypt(&key, &wrap_key.nonce, &wrap_key.encrypted_data)?;
Ok(decrypted_key)
@@ -181,10 +192,10 @@ fn read_slot(slot: &Option<String>) -> XResult<String> {
io::stdout().flush().ok();
let mut buff = String::new();
let _ = io::stdin().read_line(&mut buff).expect("Read line from stdin");
if buff.is_empty() {
simple_error!("Slot is required, and not inputed")
if buff.trim().is_empty() {
simple_error!("Slot is required, and not inputted")
} else {
Ok(buff)
Ok(buff.trim().to_string())
}
}
}