feat: update dependencies, optimize
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -611,9 +611,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fiat-crypto"
|
name = "fiat-crypto"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d"
|
checksum = "a481586acf778f1b1455424c343f71124b048ffa5f4fc3f8f6ae9dc432dcb3c7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flagset"
|
name = "flagset"
|
||||||
@@ -1378,9 +1378,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust_util"
|
name = "rust_util"
|
||||||
version = "0.6.45"
|
version = "0.6.46"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "45c3036388284b69995eb2864a943b0de55de76ad5b56fc2d3c60fecd7b9ad82"
|
checksum = "cffc8cab4e18f1320f13ac0c357b4bef1c120723885a187799440440e563f7a4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
|
|||||||
@@ -5,11 +5,7 @@ use std::time::{Instant, SystemTime};
|
|||||||
|
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use openpgp_card::crypto_data::Cryptogram;
|
use openpgp_card::crypto_data::Cryptogram;
|
||||||
use rust_util::{
|
use rust_util::{debugging, failure, iff, information, opt_result, println_ex, simple_error, success, util_msg, util_size, warning, XResult};
|
||||||
debugging, failure, iff, information, opt_result,
|
|
||||||
println_ex, simple_error, success, util_msg,
|
|
||||||
warning, XResult,
|
|
||||||
};
|
|
||||||
use rust_util::util_time::UnixEpochTime;
|
use rust_util::util_time::UnixEpochTime;
|
||||||
use x509_parser::prelude::FromDer;
|
use x509_parser::prelude::FromDer;
|
||||||
use x509_parser::x509::SubjectPublicKeyInfo;
|
use x509_parser::x509::SubjectPublicKeyInfo;
|
||||||
@@ -85,10 +81,10 @@ pub fn decrypt(cmd_decrypt: CmdDecrypt) -> XResult<()> {
|
|||||||
succeed_count += 1;
|
succeed_count += 1;
|
||||||
total_len += len;
|
total_len += len;
|
||||||
success!(
|
success!(
|
||||||
"Decrypt {} succeed, cost {} ms, file size {} byte(s)",
|
"Decrypt {} succeed, cost {} ms, file size {}",
|
||||||
path.to_str().unwrap_or("N/A"),
|
path.to_str().unwrap_or("N/A"),
|
||||||
start_decrypt_single.elapsed().as_millis(),
|
start_decrypt_single.elapsed().as_millis(),
|
||||||
len
|
util_size::get_display_size(len as i64)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -99,9 +95,9 @@ pub fn decrypt(cmd_decrypt: CmdDecrypt) -> XResult<()> {
|
|||||||
}
|
}
|
||||||
if (succeed_count + failed_count) > 1 {
|
if (succeed_count + failed_count) > 1 {
|
||||||
success!(
|
success!(
|
||||||
"Decrypt succeed {} file(s) {} byte(s), failed {} file(s), total cost {} ms",
|
"Decrypt succeed {} file(s) {}, failed {} file(s), total cost {} ms",
|
||||||
succeed_count,
|
succeed_count,
|
||||||
total_len,
|
util_size::get_display_size(total_len as i64),
|
||||||
failed_count,
|
failed_count,
|
||||||
start.elapsed().as_millis(),
|
start.elapsed().as_millis(),
|
||||||
);
|
);
|
||||||
@@ -120,7 +116,9 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
|
|||||||
let mut file_in = opt_result!(File::open(path), "Open file: {} failed: {}", &path_display);
|
let mut file_in = opt_result!(File::open(path), "Open file: {} failed: {}", &path_display);
|
||||||
let (_, meta) = opt_result!(
|
let (_, meta) = opt_result!(
|
||||||
util_enc_file::read_tiny_encrypt_meta_and_normalize(&mut file_in), "Read file: {}, failed: {}", &path_display);
|
util_enc_file::read_tiny_encrypt_meta_and_normalize(&mut file_in), "Read file: {}, failed: {}", &path_display);
|
||||||
debugging!("Found meta: {}", serde_json::to_string_pretty(&meta).unwrap());
|
util_msg::when_debug(|| {
|
||||||
|
debugging!("Found meta: {}", serde_json::to_string_pretty(&meta).unwrap());
|
||||||
|
});
|
||||||
|
|
||||||
let encryption_algorithm = meta.encryption_algorithm.as_deref()
|
let encryption_algorithm = meta.encryption_algorithm.as_deref()
|
||||||
.unwrap_or(consts::TINY_ENC_AES_GCM);
|
.unwrap_or(consts::TINY_ENC_AES_GCM);
|
||||||
@@ -143,12 +141,12 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
|
|||||||
let key_nonce = KeyNonce { k: &key.0, n: &nonce.0 };
|
let key_nonce = KeyNonce { k: &key.0, n: &nonce.0 };
|
||||||
|
|
||||||
// debugging!("Decrypt key: {}", hex::encode(&key.0));
|
// debugging!("Decrypt key: {}", hex::encode(&key.0));
|
||||||
debugging!("Decrypt nonce: {}", hex::encode(&nonce.0));
|
util_msg::when_debug(|| debugging!("Decrypt nonce: {}", hex::encode(&nonce.0)));
|
||||||
|
|
||||||
let enc_meta = parse_encrypted_meta(&meta, cryptor, &key_nonce)?;
|
let enc_meta = parse_encrypted_meta(&meta, cryptor, &key_nonce)?;
|
||||||
parse_encrypted_comment(&meta, cryptor, &key_nonce)?;
|
parse_encrypted_comment(&meta, cryptor, &key_nonce)?;
|
||||||
|
|
||||||
// Decrypt to output
|
// Decrypt to output
|
||||||
if cmd_decrypt.direct_print {
|
if cmd_decrypt.direct_print {
|
||||||
if meta.file_length > 10 * 1024 {
|
if meta.file_length > 10 * 1024 {
|
||||||
warning!("File too large(more than 10K) cannot direct print on console.");
|
warning!("File too large(more than 10K) cannot direct print on console.");
|
||||||
@@ -170,7 +168,7 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
|
|||||||
return Ok(meta.file_length);
|
return Ok(meta.file_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Digest file
|
// Digest file
|
||||||
if cmd_decrypt.digest_file {
|
if cmd_decrypt.digest_file {
|
||||||
let mut digest_write = DigestWrite::from_algo(digest_algorithm)?;
|
let mut digest_write = DigestWrite::from_algo(digest_algorithm)?;
|
||||||
let _ = decrypt_file(
|
let _ = decrypt_file(
|
||||||
@@ -186,7 +184,7 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
|
|||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt to file
|
// Decrypt to file
|
||||||
let compressed_desc = iff!(meta.compress, " [compressed]", "");
|
let compressed_desc = iff!(meta.compress, " [compressed]", "");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
@@ -195,12 +193,12 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
|
|||||||
&mut file_in, meta.file_length, &mut file_out, cryptor, &key_nonce, meta.compress,
|
&mut file_in, meta.file_length, &mut file_out, cryptor, &key_nonce, meta.compress,
|
||||||
)?;
|
)?;
|
||||||
drop(file_out);
|
drop(file_out);
|
||||||
util_file::update_out_file_time(enc_meta, path_out);
|
util_file::update_file_time(enc_meta, path_out);
|
||||||
|
|
||||||
let encrypt_duration = start.elapsed();
|
let encrypt_duration = start.elapsed();
|
||||||
debugging!("Inner decrypt file{}: {} elapsed: {} ms", compressed_desc, path_display, encrypt_duration.as_millis());
|
debugging!("Inner decrypt file{}: {} elapsed: {} ms", compressed_desc, path_display, encrypt_duration.as_millis());
|
||||||
|
|
||||||
if do_skip_file_out && cmd_decrypt.remove_file { util::remove_file_with_msg(path); }
|
if do_skip_file_out & &cmd_decrypt.remove_file { util::remove_file_with_msg(path); }
|
||||||
Ok(meta.file_length)
|
Ok(meta.file_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +222,7 @@ fn decrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write,
|
|||||||
last_block
|
last_block
|
||||||
};
|
};
|
||||||
opt_result!(file_out.write_all(&last_block), "Write file failed: {}");
|
opt_result!(file_out.write_all(&last_block), "Write file failed: {}");
|
||||||
debugging!("Decrypt finished, total bytes: {}", total_len);
|
debugging!("Decrypt finished, total: {} byte(s)", total_len);
|
||||||
progress.finish();
|
progress.finish();
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@@ -305,8 +303,7 @@ fn try_decrypt_key_ecdh(config: &Option<TinyEncryptConfig>,
|
|||||||
ENC_CHACHA20_POLY1305_P384 => (Cryptor::ChaCha20Poly1305, AlgorithmId::EccP384),
|
ENC_CHACHA20_POLY1305_P384 => (Cryptor::ChaCha20Poly1305, AlgorithmId::EccP384),
|
||||||
_ => return simple_error!("Unsupported header enc: {}", &wrap_key.header.enc),
|
_ => return simple_error!("Unsupported header enc: {}", &wrap_key.header.enc),
|
||||||
};
|
};
|
||||||
let e_pub_key = &wrap_key.header.e_pub_key;
|
let e_pub_key_bytes = wrap_key.header.get_e_pub_key_bytes()?;
|
||||||
let e_pub_key_bytes = opt_result!(util::decode_base64_url_no_pad(e_pub_key), "Invalid envelop: {}");
|
|
||||||
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: {}");
|
||||||
|
|
||||||
@@ -341,15 +338,14 @@ fn try_decrypt_key_ecdh_pgp_x25519(envelop: &TinyEncryptEnvelop, pin: &Option<St
|
|||||||
ENC_CHACHA20_POLY1305_X25519 => Cryptor::ChaCha20Poly1305,
|
ENC_CHACHA20_POLY1305_X25519 => Cryptor::ChaCha20Poly1305,
|
||||||
_ => return simple_error!("Unsupported header enc: {}", &wrap_key.header.enc),
|
_ => return simple_error!("Unsupported header enc: {}", &wrap_key.header.enc),
|
||||||
};
|
};
|
||||||
let e_pub_key = &wrap_key.header.e_pub_key;
|
let e_pub_key_bytes = wrap_key.header.get_e_pub_key_bytes()?;
|
||||||
let epk_bytes = opt_result!(util::decode_base64_url_no_pad(e_pub_key), "Invalid envelop: {}");
|
|
||||||
|
|
||||||
let mut pgp = util_pgp::get_openpgp()?;
|
let mut pgp = util_pgp::get_openpgp()?;
|
||||||
let mut trans = opt_result!(pgp.transaction(), "Connect PIV card failed: {}");
|
let mut trans = opt_result!(pgp.transaction(), "Connect PIV card failed: {}");
|
||||||
|
|
||||||
util_pgp::read_and_verify_openpgp_pin(&mut trans, pin)?;
|
util_pgp::read_and_verify_openpgp_pin(&mut trans, pin)?;
|
||||||
|
|
||||||
let shared_secret = trans.decipher(Cryptogram::ECDH(&epk_bytes))?;
|
let shared_secret = trans.decipher(Cryptogram::ECDH(&e_pub_key_bytes))?;
|
||||||
|
|
||||||
let key = util::simple_kdf(shared_secret.as_slice());
|
let key = util::simple_kdf(shared_secret.as_slice());
|
||||||
let key_nonce = KeyNonce { k: &key, n: &wrap_key.nonce };
|
let key_nonce = KeyNonce { k: &key, n: &wrap_key.nonce };
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::time::Instant;
|
|||||||
use clap::Args;
|
use clap::Args;
|
||||||
use flate2::Compression;
|
use flate2::Compression;
|
||||||
use rsa::Pkcs1v15Encrypt;
|
use rsa::Pkcs1v15Encrypt;
|
||||||
use rust_util::{debugging, failure, iff, information, opt_result, simple_error, success, XResult};
|
use rust_util::{debugging, failure, iff, information, opt_result, simple_error, success, util_size, XResult};
|
||||||
use rust_util::util_time::UnixEpochTime;
|
use rust_util::util_time::UnixEpochTime;
|
||||||
|
|
||||||
use crate::{crypto_cryptor, crypto_simple, util, util_enc_file, util_env, util_p256, util_p384, util_x25519};
|
use crate::{crypto_cryptor, crypto_simple, util, util_enc_file, util_env, util_p256, util_p384, util_x25519};
|
||||||
@@ -194,7 +194,7 @@ fn encrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write, cr
|
|||||||
None => GzStreamEncoder::new_default(),
|
None => GzStreamEncoder::new_default(),
|
||||||
Some(compress_level) => {
|
Some(compress_level) => {
|
||||||
if *compress_level > 9 {
|
if *compress_level > 9 {
|
||||||
return simple_error!("Compress level must in range [0, 9]");
|
return simple_error!("Compress level must be in range [0, 9]");
|
||||||
}
|
}
|
||||||
GzStreamEncoder::new(Compression::new(*compress_level))
|
GzStreamEncoder::new(Compression::new(*compress_level))
|
||||||
}
|
}
|
||||||
@@ -221,10 +221,12 @@ fn encrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write, cr
|
|||||||
};
|
};
|
||||||
opt_result!(file_out.write_all(&last_block_and_tag), "Write file failed: {}");
|
opt_result!(file_out.write_all(&last_block_and_tag), "Write file failed: {}");
|
||||||
progress.finish();
|
progress.finish();
|
||||||
debugging!("Encrypt finished, total bytes: {}", total_len);
|
debugging!("Encrypt finished, total bytes: {} byte(s)", total_len);
|
||||||
if compress {
|
if compress {
|
||||||
information!("File is compressed: {} byte(s) -> {} byte(s), ratio: {}%",
|
information!("File is compressed: {} -> {}, ratio: {}%",
|
||||||
total_len, write_len, util::ratio(write_len, total_len));
|
util_size::get_display_size(total_len as i64),
|
||||||
|
util_size::get_display_size(write_len as i64),
|
||||||
|
util::ratio(write_len, total_len));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@@ -309,11 +311,7 @@ fn encrypt_envelop_shared_secret(cryptor: Cryptor,
|
|||||||
cryptor, &key_nonce, key)?;
|
cryptor, &key_nonce, key)?;
|
||||||
|
|
||||||
let wrap_key = WrapKey {
|
let wrap_key = WrapKey {
|
||||||
header: WrapKeyHeader {
|
header: WrapKeyHeader::from(enc_type, ephemeral_spki),
|
||||||
kid: None,
|
|
||||||
enc: enc_type.to_string(),
|
|
||||||
e_pub_key: util::encode_base64_url_no_pad(ephemeral_spki),
|
|
||||||
},
|
|
||||||
nonce: nonce.0.clone(),
|
nonce: nonce.0.clone(),
|
||||||
encrypted_data: encrypted_key,
|
encrypted_data: encrypted_key,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ use rust_util::{
|
|||||||
debugging, failure, iff, opt_result, simple_error, success,
|
debugging, failure, iff, opt_result, simple_error, success,
|
||||||
util_msg, util_size, util_time, XResult,
|
util_msg, util_size, util_time, XResult,
|
||||||
};
|
};
|
||||||
use rust_util::util_msg::MessageType;
|
|
||||||
use rust_util::util_time::UnixEpochTime;
|
use rust_util::util_time::UnixEpochTime;
|
||||||
use simpledateformat::format_human2;
|
use simpledateformat::format_human2;
|
||||||
|
|
||||||
@@ -97,7 +96,7 @@ pub fn info_single(path: &PathBuf, cmd_info: &CmdInfo) -> XResult<()> {
|
|||||||
header(&format!("Envelop #{}", i + 1)),
|
header(&format!("Envelop #{}", i + 1)),
|
||||||
util_envelop::format_envelop(envelop, &config)
|
util_envelop::format_envelop(envelop, &config)
|
||||||
));
|
));
|
||||||
util_msg::when(MessageType::DEBUG, || {
|
util_msg::when_debug(|| {
|
||||||
if let Ok(wrap_key) = WrapKey::parse(&envelop.encrypted_key) {
|
if let Ok(wrap_key) = WrapKey::parse(&envelop.encrypted_key) {
|
||||||
debugging!("Wrap key: {}", serde_json::to_string(&wrap_key).expect("SHOULD NOT HAPPEN"));
|
debugging!("Wrap key: {}", serde_json::to_string(&wrap_key).expect("SHOULD NOT HAPPEN"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,14 +74,16 @@ fn get_encryptor(crypto: Cryptor, key_nonce: &KeyNonce) -> XResult<Box<dyn Encry
|
|||||||
match crypto {
|
match crypto {
|
||||||
Cryptor::Aes256Gcm => {
|
Cryptor::Aes256Gcm => {
|
||||||
let mut key: [u8; 32] = opt_result!(key_nonce.k.try_into(), "Bad AES 256 key: {}");
|
let mut key: [u8; 32] = opt_result!(key_nonce.k.try_into(), "Bad AES 256 key: {}");
|
||||||
let aes256_gcm_stream_encryptor = Aes256GcmStreamEncryptor::new(key, key_nonce.n);
|
let aes256_gcm_stream_encryptor = Aes256GcmStreamEncryptor::new(
|
||||||
|
key, key_nonce.n);
|
||||||
key.zeroize();
|
key.zeroize();
|
||||||
Ok(Box::new(Aes256GcmEncryptor {
|
Ok(Box::new(Aes256GcmEncryptor {
|
||||||
aes256_gcm_stream_encryptor,
|
aes256_gcm_stream_encryptor,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Cryptor::ChaCha20Poly1305 => Ok(Box::new(ChaCha20Poly1305Encryptor {
|
Cryptor::ChaCha20Poly1305 => Ok(Box::new(ChaCha20Poly1305Encryptor {
|
||||||
chacha20_poly1305_stream_encryptor: ChaCha20Poly1305StreamEncryptor::new(key_nonce.k, key_nonce.n)?,
|
chacha20_poly1305_stream_encryptor: ChaCha20Poly1305StreamEncryptor::new(
|
||||||
|
key_nonce.k, key_nonce.n)?,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,14 +92,16 @@ fn get_decryptor(crypto: Cryptor, key_nonce: &KeyNonce) -> XResult<Box<dyn Decry
|
|||||||
match crypto {
|
match crypto {
|
||||||
Cryptor::Aes256Gcm => {
|
Cryptor::Aes256Gcm => {
|
||||||
let mut key: [u8; 32] = opt_result!(key_nonce.k.try_into(), "Bad AES 256 key: {}");
|
let mut key: [u8; 32] = opt_result!(key_nonce.k.try_into(), "Bad AES 256 key: {}");
|
||||||
let aes256_gcm_stream_decryptor = Aes256GcmStreamDecryptor::new(key, key_nonce.n);
|
let aes256_gcm_stream_decryptor = Aes256GcmStreamDecryptor::new(
|
||||||
|
key, key_nonce.n);
|
||||||
key.zeroize();
|
key.zeroize();
|
||||||
Ok(Box::new(Aes256GcmDecryptor {
|
Ok(Box::new(Aes256GcmDecryptor {
|
||||||
aes256_gcm_stream_decryptor,
|
aes256_gcm_stream_decryptor,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Cryptor::ChaCha20Poly1305 => Ok(Box::new(ChaCha20Poly1305Decryptor {
|
Cryptor::ChaCha20Poly1305 => Ok(Box::new(ChaCha20Poly1305Decryptor {
|
||||||
chacha20_poly1305_stream_decryptor: ChaCha20Poly1305StreamDecryptor::new(key_nonce.k, key_nonce.n)?,
|
chacha20_poly1305_stream_decryptor: ChaCha20Poly1305StreamDecryptor::new(
|
||||||
|
key_nonce.k, key_nonce.n)?,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ pub fn make_key256_and_nonce() -> (SecVec, SecVec) {
|
|||||||
pub fn simple_kdf(input: &[u8]) -> Vec<u8> {
|
pub fn simple_kdf(input: &[u8]) -> Vec<u8> {
|
||||||
let mut input = input.to_vec();
|
let mut input = input.to_vec();
|
||||||
for _ in 0..8 {
|
for _ in 0..8 {
|
||||||
let mut sha256 = DigestWrite::sha256().expect("SHOULD NOT HAPPEN");
|
let mut sha256 = DigestWrite::sha256();
|
||||||
sha256.write_all(&input).expect("SHOULD NOT HAPPEN");
|
sha256.write_all(&input).expect("SHOULD NOT HAPPEN");
|
||||||
input = sha256.digest();
|
input = sha256.digest();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ impl DigestWrite {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sha256() -> XResult<Self> {
|
pub fn sha256() -> Self {
|
||||||
Ok(Self { digest: Box::new(Sha256::new()) })
|
Self { digest: Box::new(Sha256::new()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn digest(self) -> Vec<u8> {
|
pub fn digest(self) -> Vec<u8> {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ pub fn read_tiny_encrypt_meta(r: &mut impl Read) -> XResult<(u32, TinyEncryptMet
|
|||||||
return simple_error!("Meta too large: {}", length);
|
return simple_error!("Meta too large: {}", length);
|
||||||
}
|
}
|
||||||
|
|
||||||
debugging!("Encrypted meta len: {}", length);
|
debugging!("Encrypted meta length: {}", length);
|
||||||
let mut meta_buff = vec![0; length as usize];
|
let mut meta_buff = vec![0; length as usize];
|
||||||
opt_result!(r.read_exact(meta_buff.as_mut_slice()), "Read meta failed: {}");
|
opt_result!(r.read_exact(meta_buff.as_mut_slice()), "Read meta failed: {}");
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use crate::consts;
|
|||||||
|
|
||||||
pub const TINY_ENCRYPT_ENV_DEFAULT_ALGORITHM: &str = "TINY_ENCRYPT_DEFAULT_ALGORITHM";
|
pub const TINY_ENCRYPT_ENV_DEFAULT_ALGORITHM: &str = "TINY_ENCRYPT_DEFAULT_ALGORITHM";
|
||||||
pub const TINY_ENCRYPT_ENV_DEFAULT_COMPRESS: &str = "TINY_ENCRYPT_DEFAULT_COMPRESS";
|
pub const TINY_ENCRYPT_ENV_DEFAULT_COMPRESS: &str = "TINY_ENCRYPT_DEFAULT_COMPRESS";
|
||||||
|
pub const TINY_ENCRYPT_ENV_NO_PROGRESS: &str = "TINY_ENCRYPT_NO_PROGRESS";
|
||||||
|
|
||||||
pub fn get_default_encryption_algorithm() -> Option<&'static str> {
|
pub fn get_default_encryption_algorithm() -> Option<&'static str> {
|
||||||
let env_default_algorithm = env::var(TINY_ENCRYPT_ENV_DEFAULT_ALGORITHM).ok();
|
let env_default_algorithm = env::var(TINY_ENCRYPT_ENV_DEFAULT_ALGORITHM).ok();
|
||||||
@@ -24,4 +25,8 @@ pub fn get_default_encryption_algorithm() -> Option<&'static str> {
|
|||||||
|
|
||||||
pub fn get_default_compress() -> Option<bool> {
|
pub fn get_default_compress() -> Option<bool> {
|
||||||
iff!(rust_util_env::is_env_off(TINY_ENCRYPT_ENV_DEFAULT_COMPRESS), Some(true), None)
|
iff!(rust_util_env::is_env_off(TINY_ENCRYPT_ENV_DEFAULT_COMPRESS), Some(true), None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_no_progress() -> bool {
|
||||||
|
rust_util_env::is_env_on(TINY_ENCRYPT_ENV_NO_PROGRESS)
|
||||||
}
|
}
|
||||||
@@ -6,13 +6,13 @@ use rust_util::util_time::UnixEpochTime;
|
|||||||
|
|
||||||
use crate::spec::EncEncryptedMeta;
|
use crate::spec::EncEncryptedMeta;
|
||||||
|
|
||||||
pub fn update_out_file_time(enc_meta: Option<EncEncryptedMeta>, path_out: &str) {
|
pub fn update_file_time(enc_meta: Option<EncEncryptedMeta>, path: &str) {
|
||||||
if let Some(enc_meta) = &enc_meta {
|
if let Some(enc_meta) = &enc_meta {
|
||||||
let create_time = enc_meta.c_time.map(SystemTime::from_millis);
|
let create_time = enc_meta.c_time.map(SystemTime::from_millis);
|
||||||
let modify_time = enc_meta.m_time.map(SystemTime::from_millis);
|
let modify_time = enc_meta.m_time.map(SystemTime::from_millis);
|
||||||
if create_time.is_some() || modify_time.is_some() {
|
if create_time.is_some() || modify_time.is_some() {
|
||||||
let set_times_result = fs_set_times::set_times(
|
let set_times_result = fs_set_times::set_times(
|
||||||
path_out,
|
path,
|
||||||
create_time.map(SystemTimeSpec::Absolute),
|
create_time.map(SystemTimeSpec::Absolute),
|
||||||
modify_time.map(SystemTimeSpec::Absolute),
|
modify_time.map(SystemTimeSpec::Absolute),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,28 +1,46 @@
|
|||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
|
use rust_util::{debugging, util_msg};
|
||||||
|
|
||||||
|
use crate::util_env;
|
||||||
|
|
||||||
const PB_PROGRESS: &str = "#-";
|
const PB_PROGRESS: &str = "#-";
|
||||||
const PB_TEMPLATE: &str = "{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} {bytes_per_sec} ({eta})";
|
const PB_TEMPLATE: &str = "{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} {bytes_per_sec} ({eta})";
|
||||||
|
|
||||||
|
|
||||||
pub struct Progress {
|
pub enum Progress {
|
||||||
progress_bar: ProgressBar,
|
NoProgress,
|
||||||
|
Progress(ProgressBar),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Progress {
|
impl Progress {
|
||||||
pub fn new(total: u64) -> Self {
|
pub fn new(total: u64) -> Self {
|
||||||
let progress_bar = ProgressBar::new(total);
|
let no_progress = util_env::get_no_progress();
|
||||||
progress_bar.set_style(ProgressStyle::default_bar()
|
let is_atty = util_msg::is_atty();
|
||||||
.template(PB_TEMPLATE).expect("SHOULD NOT FAIL")
|
|
||||||
.progress_chars(PB_PROGRESS)
|
if no_progress || !is_atty {
|
||||||
);
|
debugging!("No progress: [{}, {}]", no_progress, is_atty);
|
||||||
Self { progress_bar }
|
Self::NoProgress
|
||||||
|
} else {
|
||||||
|
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(progress_bar)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn position(&self, position: u64) {
|
pub fn position(&self, position: u64) {
|
||||||
self.progress_bar.set_position(position)
|
match self {
|
||||||
|
Progress::NoProgress => {}
|
||||||
|
Progress::Progress(progress_bar) => progress_bar.set_position(position),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish(&self) {
|
pub fn finish(&self) {
|
||||||
self.progress_bar.finish_and_clear()
|
match self {
|
||||||
|
Progress::NoProgress => {}
|
||||||
|
Progress::Progress(progress_bar) => progress_bar.finish_and_clear(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
use rust_util::{opt_result, simple_error, XResult};
|
use rust_util::{opt_result, simple_error, XResult};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::util::{decode_base64_url_no_pad, encode_base64_url_no_pad};
|
use crate::util;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
@@ -20,17 +20,31 @@ pub struct WrapKeyHeader {
|
|||||||
pub e_pub_key: String,
|
pub e_pub_key: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl WrapKeyHeader {
|
||||||
|
pub fn from(enc_type: &str, ephemeral_spki: &[u8]) -> Self {
|
||||||
|
WrapKeyHeader {
|
||||||
|
kid: None,
|
||||||
|
enc: enc_type.to_string(),
|
||||||
|
e_pub_key: util::encode_base64_url_no_pad(ephemeral_spki),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_e_pub_key_bytes(self) -> XResult<Vec<u8>> {
|
||||||
|
Ok(opt_result!(util::decode_base64_url_no_pad(&self.e_pub_key), "Invalid envelop e_pub_key: {}"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl WrapKey {
|
impl WrapKey {
|
||||||
pub fn encode(&self) -> XResult<String> {
|
pub fn encode(&self) -> XResult<String> {
|
||||||
let mut buf = String::with_capacity(512);
|
let mut buf = String::with_capacity(512);
|
||||||
buf.push_str("WK:");
|
buf.push_str("WK:");
|
||||||
let header = serde_json::to_string(&self.header)?;
|
let header = serde_json::to_string(&self.header)?;
|
||||||
let header_str = encode_base64_url_no_pad(header.as_bytes());
|
let header_str = util::encode_base64_url_no_pad(header.as_bytes());
|
||||||
buf.push_str(&header_str);
|
buf.push_str(&header_str);
|
||||||
buf.push('.');
|
buf.push('.');
|
||||||
buf.push_str(&encode_base64_url_no_pad(&self.nonce));
|
buf.push_str(&util::encode_base64_url_no_pad(&self.nonce));
|
||||||
buf.push('.');
|
buf.push('.');
|
||||||
buf.push_str(&encode_base64_url_no_pad(&self.encrypted_data));
|
buf.push_str(&util::encode_base64_url_no_pad(&self.encrypted_data));
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,13 +57,13 @@ impl WrapKey {
|
|||||||
return simple_error!("Invalid wrap key.");
|
return simple_error!("Invalid wrap key.");
|
||||||
}
|
}
|
||||||
let header = wks[0].chars().skip(3).collect::<String>();
|
let header = wks[0].chars().skip(3).collect::<String>();
|
||||||
let header_bytes = opt_result!(decode_base64_url_no_pad(&header), "Invalid wrap key header: {}");
|
let header_bytes = opt_result!(util::decode_base64_url_no_pad(&header), "Invalid wrap key header: {}");
|
||||||
let nonce = wks[1];
|
let nonce = wks[1];
|
||||||
let encrypted_data = wks[2];
|
let encrypted_data = wks[2];
|
||||||
let header_str = opt_result!(String::from_utf8(header_bytes), "Invalid wrap key header: {}");
|
let header_str = opt_result!(String::from_utf8(header_bytes), "Invalid wrap key header: {}");
|
||||||
let header: WrapKeyHeader = opt_result!(serde_json::from_str(&header_str), "Invalid wrap key header: {}");
|
let header: WrapKeyHeader = opt_result!(serde_json::from_str(&header_str), "Invalid wrap key header: {}");
|
||||||
let nonce = opt_result!(decode_base64_url_no_pad(nonce), "Invalid wrap key: {}");
|
let nonce = opt_result!(util::decode_base64_url_no_pad(nonce), "Invalid wrap key: {}");
|
||||||
let encrypted_data = opt_result!(decode_base64_url_no_pad(encrypted_data), "Invalid wrap key: {}");
|
let encrypted_data = opt_result!(util::decode_base64_url_no_pad(encrypted_data), "Invalid wrap key: {}");
|
||||||
Ok(WrapKey {
|
Ok(WrapKey {
|
||||||
header,
|
header,
|
||||||
nonce,
|
nonce,
|
||||||
|
|||||||
Reference in New Issue
Block a user