diff --git a/Cargo.lock b/Cargo.lock index 3741e9e..4409ae1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2198,6 +2198,7 @@ dependencies = [ "x509-parser", "yubico_manager", "yubikey", + "zeroize", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index ae320ff..bcb1ac8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ simpledateformat = "0.1.4" x509-parser = "0.15.1" yubico_manager = "0.9.0" yubikey = { version = "0.8.0", features = ["untested"] } +zeroize = "1.6.0" [profile.release] codegen-units = 1 diff --git a/src/cmd_decrypt.rs b/src/cmd_decrypt.rs index 68eb4f5..8c7f685 100644 --- a/src/cmd_decrypt.rs +++ b/src/cmd_decrypt.rs @@ -1,4 +1,3 @@ -use std::fs; use std::fs::File; use std::io::{Read, Write}; use std::path::PathBuf; @@ -46,22 +45,19 @@ pub fn decrypt(cmd_decrypt: CmdDecrypt) -> XResult<()> { pub fn decrypt_single(path: &PathBuf, pin: &Option, slot: &Option) -> XResult<()> { let path_display = format!("{}", path.display()); - if !path_display.ends_with(TINY_ENC_FILE_EXT) { - return simple_error!("File is not tiny encrypt file: {}", &path_display); - } + util::require_tiny_enc_file_and_exists(path)?; + let mut file_in = opt_result!(File::open(path), "Open file: {} failed: {}", &path_display); let meta = opt_result!(file::read_tiny_encrypt_meta_and_normalize(&mut file_in), "Read file: {}, failed: {}", &path_display); let path_out = &path_display[0..path_display.len() - TINY_ENC_FILE_EXT.len()]; - if let Ok(_) = fs::metadata(path_out) { - return simple_error!("Output file: {} exists", path_out); - } + util::require_file_not_exists(path_out)?; debugging!("Found meta: {}", serde_json::to_string_pretty(&meta).unwrap()); let selected_envelop = select_envelop(&meta)?; let key = try_decrypt_key(selected_envelop, pin, slot)?; - let nonce = opt_result!( decode_base64(&meta.nonce), "Decode nonce failed: {}"); + let nonce = opt_result!(decode_base64(&meta.nonce), "Decode nonce failed: {}"); debugging!("Decrypt key: {}", hex::encode(&key)); debugging!("Decrypt nonce: {}", hex::encode(&nonce)); @@ -69,6 +65,8 @@ pub fn decrypt_single(path: &PathBuf, pin: &Option, slot: &Option) -> XResult<()> { + let path = path.as_ref(); + let path_display = format!("{}", path.display()); + if !path_display.ends_with(TINY_ENC_FILE_EXT) { + return simple_error!("File is not tiny encrypt file: {}", &path_display); + } + require_file_exists(path)?; + Ok(()) +} + +pub fn require_file_exists(path: impl AsRef) -> XResult<()> { + let path = path.as_ref(); + match fs::metadata(path) { + Ok(_) => Ok(()), + Err(e) => simple_error!("File: {} not exists", path.display()), + } +} + +pub fn require_file_not_exists(path: impl AsRef) -> XResult<()> { + let path = path.as_ref(); + match fs::metadata(path) { + Ok(_) => simple_error!("File: {} exists", path.display()), + Err(_) => Ok(()), + } +} + pub fn simple_kdf(input: &[u8]) -> Vec { let input = hex::decode(sha256::digest(input)).unwrap(); let input = hex::decode(sha256::digest(input)).unwrap(); @@ -79,4 +107,9 @@ pub fn get_user_agent() -> String { panic!("Unsupported OS!"); } ) -} \ No newline at end of file +} + +pub fn zeroize(object: impl Zeroize) { + let mut object = object; + object.zeroize(); +}