diff --git a/Cargo.lock b/Cargo.lock index 5dc5af3..4f226a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,7 +91,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -101,7 +101,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -275,7 +275,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -334,6 +334,19 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "console" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.45.0", +] + [[package]] name = "const-oid" version = "0.9.5" @@ -564,6 +577,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -580,7 +599,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -659,7 +678,7 @@ checksum = "dd738b84894214045e8414eaded76359b4a5773f0a0a56b16575110739cdcf39" dependencies = [ "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -966,6 +985,19 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "indicatif" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + [[package]] name = "inout" version = "0.1.3" @@ -975,6 +1007,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + [[package]] name = "io-lifetimes" version = "2.0.2" @@ -1079,7 +1120,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1180,6 +1221,12 @@ dependencies = [ "libc", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "object" version = "0.32.1" @@ -1416,6 +1463,12 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "portable-atomic" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" + [[package]] name = "powerfmt" version = "0.2.0" @@ -1702,7 +1755,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1754,7 +1807,7 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1949,7 +2002,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2069,7 +2122,7 @@ dependencies = [ "fastrand", "redox_syscall 0.3.5", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2144,7 +2197,7 @@ dependencies = [ [[package]] name = "tiny-encrypt" -version = "0.3.4" +version = "0.4.0" dependencies = [ "aes-gcm-stream", "base64", @@ -2153,6 +2206,7 @@ dependencies = [ "flate2", "fs-set-times", "hex", + "indicatif", "openpgp-card", "openpgp-card-pcsc", "p256", @@ -2201,7 +2255,7 @@ dependencies = [ "num_cpus", "pin-project-lite", "socket2 0.5.4", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2493,7 +2547,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", ] [[package]] @@ -2502,7 +2565,22 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -2511,51 +2589,93 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -2569,7 +2689,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index edf6f94..ddf9fcf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tiny-encrypt" -version = "0.3.4" +version = "0.4.0" edition = "2021" license = "MIT" description = "A simple and tiny file encrypt tool" @@ -15,6 +15,7 @@ clap = { version = "4.4", features = ["derive"] } flate2 = "1.0" fs-set-times = "0.20" hex = "0.4" +indicatif = "0.17" openpgp-card = "0.3" openpgp-card-pcsc = "0.3" p256 = { version = "0.13", features = ["pem", "ecdh", "pkcs8"] } diff --git a/src/cmd_decrypt.rs b/src/cmd_decrypt.rs index 87cf514..70e9716 100644 --- a/src/cmd_decrypt.rs +++ b/src/cmd_decrypt.rs @@ -7,7 +7,7 @@ use clap::Args; use openpgp_card::crypto_data::Cryptogram; use rust_util::{ debugging, failure, iff, information, opt_result, simple_error, success, - util_msg, warning, XResult, + warning, XResult, }; use rust_util::util_time::UnixEpochTime; use x509_parser::prelude::FromDer; @@ -25,6 +25,7 @@ use crate::consts::{ }; use crate::crypto_aes::{aes_gcm_decrypt, try_aes_gcm_decrypt_with_salt}; use crate::spec::{EncEncryptedMeta, TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta}; +use crate::util_process::Progress; use crate::wrap_key::WrapKey; #[derive(Debug, Args)] @@ -115,14 +116,13 @@ pub fn decrypt_single(config: &Option, } else { let compressed_desc = iff!(meta.compress, " [compressed]", ""); let start = Instant::now(); - util_msg::print_lastline( - &format!("Decrypting file: {}{} ...", path_display, compressed_desc) - ); let mut file_out = File::create(path_out)?; - let _ = decrypt_file(&mut file_in, &mut file_out, &key, &nonce, meta.compress)?; + let _ = decrypt_file( + &mut file_in, meta.file_length, &mut file_out, + &key, &nonce, meta.compress, + )?; drop(file_out); - util_msg::clear_lastline(); util_file::update_out_file_time(enc_meta, path_out); let encrypt_duration = start.elapsed(); @@ -136,10 +136,11 @@ pub fn decrypt_single(config: &Option, Ok(meta.file_length) } -fn decrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8], compress: bool) -> XResult { - let mut total_len = 0; +fn decrypt_file(file_in: &mut File, file_len: u64, file_out: &mut File, key: &[u8], nonce: &[u8], compress: bool) -> XResult { + let mut total_len = 0_u64; let mut buffer = [0u8; 1024 * 8]; let key = opt_result!(key.try_into(), "Key is not 32 bytes: {}"); + let progress = Progress::new(file_len); let mut decryptor = aes_gcm_stream::Aes256GcmStreamDecryptor::new(key, nonce); let mut gz_decoder = GzStreamDecoder::new(); loop { @@ -156,9 +157,10 @@ fn decrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8 }; opt_result!(file_out.write_all(&last_block), "Write file failed: {}"); debugging!("Decrypt finished, total bytes: {}", total_len); + progress.finish(); break; } else { - total_len += len; + total_len += len as u64; let decrypted = decryptor.update(&buffer[0..len]); let decrypted = if compress { opt_result!(gz_decoder.update(&decrypted), "Decompress file failed: {}") @@ -166,6 +168,7 @@ fn decrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8 decrypted }; opt_result!(file_out.write_all(&decrypted), "Write file failed: {}"); + progress.position(total_len); } } let mut key = key; diff --git a/src/cmd_encrypt.rs b/src/cmd_encrypt.rs index c399b3e..cf0d369 100644 --- a/src/cmd_encrypt.rs +++ b/src/cmd_encrypt.rs @@ -7,7 +7,7 @@ use std::time::Instant; use clap::Args; use flate2::Compression; use rsa::Pkcs1v15Encrypt; -use rust_util::{debugging, failure, iff, information, opt_result, simple_error, success, util_msg, XResult}; +use rust_util::{debugging, failure, iff, information, opt_result, simple_error, success, XResult}; use rust_util::util_time::UnixEpochTime; use zeroize::Zeroize; @@ -18,6 +18,7 @@ use crate::consts::{ENC_AES256_GCM_P256, ENC_AES256_GCM_P384, ENC_AES256_GCM_X25 use crate::crypto_aes::{aes_gcm_encrypt, aes_gcm_encrypt_with_salt}; use crate::crypto_rsa::parse_spki; use crate::spec::{EncEncryptedMeta, EncMetadata, TINY_ENCRYPT_VERSION_10, TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta}; +use crate::util_process::Progress; use crate::wrap_key::{WrapKey, WrapKeyHeader}; #[derive(Debug, Args)] @@ -153,11 +154,10 @@ fn encrypt_single(path: &PathBuf, envelops: &[&TinyEncryptConfigEnvelop], cmd_en let compress_desc = iff!(cmd_encrypt.compress, " [with compress]", ""); let start = Instant::now(); - util_msg::print_lastline( - &format!("Encrypting file: {}{} ...", path_display, compress_desc) - ); - encrypt_file(&mut file_in, &mut file_out, &key, &nonce, cmd_encrypt.compress, &cmd_encrypt.compress_level)?; - util_msg::clear_lastline(); + encrypt_file( + &mut file_in, file_metadata.len(), &mut file_out, + &key, &nonce, cmd_encrypt.compress, &cmd_encrypt.compress_level, + )?; let encrypt_duration = start.elapsed(); debugging!("Inner encrypt file{}: {} elapsed: {} ms", compress_desc, path_display, encrypt_duration.as_millis()); @@ -194,8 +194,8 @@ fn process_compatible_with_1_0(cmd_encrypt: &CmdEncrypt, mut encrypt_meta: TinyE Ok(encrypt_meta) } -fn encrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8], compress: bool, compress_level: &Option) -> XResult { - let mut total_len = 0; +fn encrypt_file(file_in: &mut File, file_len: u64, file_out: &mut File, key: &[u8], nonce: &[u8], compress: bool, compress_level: &Option) -> XResult { + let mut total_len = 0_u64; let mut buffer = [0u8; 1024 * 8]; let key = opt_result!(key.try_into(), "Key is not 32 bytes: {}"); let mut gz_encoder = match compress_level { @@ -207,6 +207,7 @@ fn encrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8 GzStreamEncoder::new(Compression::new(*compress_level)) } }; + let progress = Progress::new(file_len); let mut encryptor = aes_gcm_stream::Aes256GcmStreamEncryptor::new(key, nonce); loop { let len = opt_result!(file_in.read(&mut buffer), "Read file failed: {}"); @@ -225,9 +226,10 @@ fn encrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8 }; opt_result!(file_out.write_all(&last_block), "Write file failed: {}"); debugging!("Encrypt finished, total bytes: {}", total_len); + progress.finish(); break; } else { - total_len += len; + total_len += len as u64; let encrypted = if compress { let compressed = opt_result!(gz_encoder.update(&buffer[0..len]), "Decompress file failed: {}"); encryptor.update(&compressed) @@ -235,6 +237,7 @@ fn encrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8 encryptor.update(&buffer[0..len]) }; opt_result!(file_out.write_all(&encrypted), "Write file failed: {}"); + progress.position(total_len); } } let mut key = key; diff --git a/src/main.rs b/src/main.rs index bbfe86c..6ccdca7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ use crate::cmd_version::CmdVersion; mod consts; mod util; +mod util_process; mod util_piv; mod util_pgp; mod util_ecdh; diff --git a/src/util_process.rs b/src/util_process.rs new file mode 100644 index 0000000..d0af3c1 --- /dev/null +++ b/src/util_process.rs @@ -0,0 +1,28 @@ +use indicatif::{ProgressBar, ProgressStyle}; + +const PB_PROGRESS: &str = "#-"; +const PB_TEMPLATE: &str = "{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} ({eta})"; + + +pub struct Progress { + progress_bar: ProgressBar, +} + +impl Progress { + pub fn new(total: u64) -> Self { + let progress_bar = ProgressBar::new(total); + progress_bar.set_style(ProgressStyle::default_bar() + .template(PB_TEMPLATE).expect("SHOULD NOT FAIL") + .progress_chars(PB_PROGRESS) + ); + Self { progress_bar } + } + + pub fn position(&self, position: u64) { + self.progress_bar.set_position(position) + } + + pub fn finish(&self) { + self.progress_bar.finish_and_clear() + } +} \ No newline at end of file