feat: v0.5.4, many updates

This commit is contained in:
2023-10-28 00:10:27 +08:00
parent 19269bf6de
commit 80e3a3540e
15 changed files with 186 additions and 128 deletions

24
Cargo.lock generated
View File

@@ -377,9 +377,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fbc60abd742b35f2492f808e1abbb83d45f72db402e14c55057edc9c7b1e9e4" checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@@ -1334,16 +1334,14 @@ dependencies = [
[[package]] [[package]]
name = "rsa" name = "rsa"
version = "0.9.2" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d"
dependencies = [ dependencies = [
"byteorder",
"const-oid", "const-oid",
"digest", "digest",
"num-bigint-dig", "num-bigint-dig",
"num-integer", "num-integer",
"num-iter",
"num-traits", "num-traits",
"pkcs1", "pkcs1",
"pkcs8", "pkcs8",
@@ -1416,9 +1414,9 @@ dependencies = [
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.20" version = "0.38.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
dependencies = [ dependencies = [
"bitflags 2.4.1", "bitflags 2.4.1",
"errno", "errno",
@@ -1470,18 +1468,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.189" version = "1.0.190"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.189" version = "1.0.190"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1729,7 +1727,7 @@ dependencies = [
[[package]] [[package]]
name = "tiny-encrypt" name = "tiny-encrypt"
version = "0.5.3" version = "0.5.4"
dependencies = [ dependencies = [
"aes-gcm-stream", "aes-gcm-stream",
"base64", "base64",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "tiny-encrypt" name = "tiny-encrypt"
version = "0.5.3" version = "0.5.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"

View File

@@ -22,7 +22,7 @@ use crate::consts::{
ENC_CHACHA20_POLY1305_P256, ENC_CHACHA20_POLY1305_P384, ENC_CHACHA20_POLY1305_X25519, ENC_CHACHA20_POLY1305_P256, ENC_CHACHA20_POLY1305_P384, ENC_CHACHA20_POLY1305_X25519,
SALT_COMMENT, TINY_ENC_CONFIG_FILE, TINY_ENC_FILE_EXT, SALT_COMMENT, TINY_ENC_CONFIG_FILE, TINY_ENC_FILE_EXT,
}; };
use crate::crypto_cryptor::Cryptor; use crate::crypto_cryptor::{Cryptor, KeyNonce};
use crate::spec::{EncEncryptedMeta, TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta}; use crate::spec::{EncEncryptedMeta, TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta};
use crate::util::SecVec; use crate::util::SecVec;
use crate::util_digest::DigestWrite; use crate::util_digest::DigestWrite;
@@ -114,7 +114,7 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
util::require_tiny_enc_file_and_exists(path)?; util::require_tiny_enc_file_and_exists(path)?;
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()); debugging!("Found meta: {}", serde_json::to_string_pretty(&meta).unwrap());
@@ -136,12 +136,13 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
let key = SecVec(try_decrypt_key(config, selected_envelop, pin, slot)?); let key = SecVec(try_decrypt_key(config, selected_envelop, pin, slot)?);
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.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)); debugging!("Decrypt nonce: {}", hex::encode(&nonce.0));
let enc_meta = parse_encrypted_meta(&meta, cryptor, &key.0, &nonce.0)?; let enc_meta = parse_encrypted_meta(&meta, cryptor, &key_nonce)?;
parse_encrypted_comment(&meta, cryptor, &key.0, &nonce.0)?; parse_encrypted_comment(&meta, cryptor, &key_nonce)?;
// Decrypt to output // Decrypt to output
if cmd_decrypt.direct_print { if cmd_decrypt.direct_print {
@@ -152,7 +153,7 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
let mut output: Vec<u8> = Vec::with_capacity(10 * 1024); let mut output: Vec<u8> = Vec::with_capacity(10 * 1024);
let _ = decrypt_file( let _ = decrypt_file(
&mut file_in, meta.file_length, &mut output, cryptor, &key.0, &nonce.0, meta.compress, &mut file_in, meta.file_length, &mut output, cryptor, &key_nonce, meta.compress,
)?; )?;
match String::from_utf8(output) { match String::from_utf8(output) {
Err(_) => warning!("File is not UTF-8 content."), Err(_) => warning!("File is not UTF-8 content."),
@@ -169,7 +170,7 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
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(
&mut file_in, meta.file_length, &mut digest_write, cryptor, &key.0, &nonce.0, meta.compress, &mut file_in, meta.file_length, &mut digest_write, cryptor, &key_nonce, meta.compress,
)?; )?;
let digest = digest_write.digest(); let digest = digest_write.digest();
success!("File digest {}: {}", digest_algorithm.to_uppercase(), hex::encode(digest)); success!("File digest {}: {}", digest_algorithm.to_uppercase(), hex::encode(digest));
@@ -187,7 +188,7 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
let mut file_out = File::create(path_out)?; let mut file_out = File::create(path_out)?;
let _ = decrypt_file( let _ = decrypt_file(
&mut file_in, meta.file_length, &mut file_out, cryptor, &key.0, &nonce.0, 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_out_file_time(enc_meta, path_out);
@@ -200,11 +201,11 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
} }
fn decrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write, fn decrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write,
cryptor: Cryptor, key: &[u8], nonce: &[u8], compress: bool) -> XResult<u64> { cryptor: Cryptor, key_nonce: &KeyNonce, compress: bool) -> XResult<u64> {
let mut total_len = 0_u64; let mut total_len = 0_u64;
let mut buffer = [0u8; 1024 * 8]; let mut buffer = [0u8; 1024 * 8];
let progress = Progress::new(file_len); let progress = Progress::new(file_len);
let mut decryptor = cryptor.decryptor(key, nonce)?; let mut decryptor = cryptor.decryptor(key_nonce)?;
let mut gz_decoder = GzStreamDecoder::new(); let mut gz_decoder = GzStreamDecoder::new();
loop { loop {
let len = opt_result!(file_in.read(&mut buffer), "Read file failed: {}"); let len = opt_result!(file_in.read(&mut buffer), "Read file failed: {}");
@@ -237,11 +238,11 @@ fn decrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write,
Ok(total_len) Ok(total_len)
} }
fn parse_encrypted_comment(meta: &TinyEncryptMeta, crypto: Cryptor, key: &[u8], nonce: &[u8]) -> XResult<()> { fn parse_encrypted_comment(meta: &TinyEncryptMeta, crypto: Cryptor, key_nonce: &KeyNonce) -> XResult<()> {
if let Some(encrypted_comment) = &meta.encrypted_comment { if let Some(encrypted_comment) = &meta.encrypted_comment {
match util::decode_base64(encrypted_comment) { match util::decode_base64(encrypted_comment) {
Err(e) => warning!("Decode encrypted comment failed: {}", e), Err(e) => warning!("Decode encrypted comment failed: {}", e),
Ok(ec_bytes) => match crypto_simple::try_decrypt_with_salt(crypto, key, nonce, SALT_COMMENT, &ec_bytes) { Ok(ec_bytes) => match crypto_simple::try_decrypt_with_salt(crypto, key_nonce, SALT_COMMENT, &ec_bytes) {
Err(e) => warning!("Decrypt encrypted comment failed: {}", e), Err(e) => warning!("Decrypt encrypted comment failed: {}", e),
Ok(decrypted_comment_bytes) => match String::from_utf8(decrypted_comment_bytes.clone()) { Ok(decrypted_comment_bytes) => match String::from_utf8(decrypted_comment_bytes.clone()) {
Err(_) => success!("Encrypted message hex: {}", hex::encode(&decrypted_comment_bytes)), Err(_) => success!("Encrypted message hex: {}", hex::encode(&decrypted_comment_bytes)),
@@ -253,7 +254,7 @@ fn parse_encrypted_comment(meta: &TinyEncryptMeta, crypto: Cryptor, key: &[u8],
Ok(()) Ok(())
} }
fn parse_encrypted_meta(meta: &TinyEncryptMeta, cryptor: Cryptor, key: &[u8], nonce: &[u8]) -> XResult<Option<EncEncryptedMeta>> { fn parse_encrypted_meta(meta: &TinyEncryptMeta, cryptor: Cryptor, key_nonce: &KeyNonce) -> XResult<Option<EncEncryptedMeta>> {
let enc_encrypted_meta = match &meta.encrypted_meta { let enc_encrypted_meta = match &meta.encrypted_meta {
None => return Ok(None), None => return Ok(None),
Some(enc_encrypted_meta) => enc_encrypted_meta, Some(enc_encrypted_meta) => enc_encrypted_meta,
@@ -261,7 +262,7 @@ fn parse_encrypted_meta(meta: &TinyEncryptMeta, cryptor: Cryptor, key: &[u8], no
let enc_encrypted_meta_bytes = opt_result!( let enc_encrypted_meta_bytes = opt_result!(
util::decode_base64(enc_encrypted_meta), "Decode enc-encrypted-meta failed: {}"); util::decode_base64(enc_encrypted_meta), "Decode enc-encrypted-meta failed: {}");
let enc_meta = opt_result!( let enc_meta = opt_result!(
EncEncryptedMeta::unseal(cryptor, key, nonce, &enc_encrypted_meta_bytes), "Unseal enc-encrypted-meta failed: {}"); EncEncryptedMeta::unseal(cryptor, key_nonce, &enc_encrypted_meta_bytes), "Unseal enc-encrypted-meta failed: {}");
debugging!("Encrypted meta: {:?}", enc_meta); debugging!("Encrypted meta: {:?}", enc_meta);
if let Some(filename) = &enc_meta.filename { if let Some(filename) = &enc_meta.filename {
information!("Source filename: {}", filename); information!("Source filename: {}", filename);
@@ -320,8 +321,9 @@ fn try_decrypt_key_ecdh(config: &Option<TinyEncryptConfig>,
slot_id, slot_id,
), "Decrypt via PIV card failed: {}"); ), "Decrypt via PIV card failed: {}");
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 decrypted_key = crypto_simple::decrypt( let decrypted_key = crypto_simple::decrypt(
cryptor, &key, &wrap_key.nonce, &wrap_key.encrypted_data)?; cryptor, &key_nonce, &wrap_key.encrypted_data)?;
util::zeroize(pin); util::zeroize(pin);
util::zeroize(key); util::zeroize(key);
util::zeroize(shared_secret); util::zeroize(shared_secret);
@@ -346,8 +348,9 @@ fn try_decrypt_key_ecdh_pgp_x25519(envelop: &TinyEncryptEnvelop, pin: &Option<St
let shared_secret = trans.decipher(Cryptogram::ECDH(&epk_bytes))?; let shared_secret = trans.decipher(Cryptogram::ECDH(&epk_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 decrypted_key = crypto_simple::decrypt( let decrypted_key = crypto_simple::decrypt(
cryptor, &key, &wrap_key.nonce, &wrap_key.encrypted_data)?; cryptor, &key_nonce, &wrap_key.encrypted_data)?;
util::zeroize(key); util::zeroize(key);
util::zeroize(shared_secret); util::zeroize(shared_secret);
Ok(decrypted_key) Ok(decrypted_key)

View File

@@ -18,7 +18,7 @@ use crate::consts::{
ENC_CHACHA20_POLY1305_P256, ENC_CHACHA20_POLY1305_P384, ENC_CHACHA20_POLY1305_X25519, ENC_CHACHA20_POLY1305_P256, ENC_CHACHA20_POLY1305_P384, ENC_CHACHA20_POLY1305_X25519,
SALT_COMMENT, TINY_ENC_CONFIG_FILE, TINY_ENC_FILE_EXT, SALT_COMMENT, TINY_ENC_CONFIG_FILE, TINY_ENC_FILE_EXT,
}; };
use crate::crypto_cryptor::Cryptor; use crate::crypto_cryptor::{Cryptor, KeyNonce};
use crate::crypto_rsa; use crate::crypto_rsa;
use crate::spec::{ use crate::spec::{
EncEncryptedMeta, EncMetadata, TINY_ENCRYPT_VERSION_10, EncEncryptedMeta, EncMetadata, TINY_ENCRYPT_VERSION_10,
@@ -112,7 +112,13 @@ pub fn encrypt(cmd_encrypt: CmdEncrypt) -> XResult<()> {
Ok(()) Ok(())
} }
fn encrypt_single(path: &PathBuf, envelops: &[&TinyEncryptConfigEnvelop], cmd_encrypt: &CmdEncrypt) -> XResult<u64> { pub fn encrypt_single(path: &PathBuf, envelops: &[&TinyEncryptConfigEnvelop], cmd_encrypt: &CmdEncrypt) -> XResult<u64> {
let path_display = format!("{}", path.display());
let path_out = format!("{}{}", path_display, TINY_ENC_FILE_EXT);
encrypt_single_file_out(path, &path_out, envelops, cmd_encrypt)
}
pub fn encrypt_single_file_out(path: &PathBuf, path_out: &str, envelops: &[&TinyEncryptConfigEnvelop], cmd_encrypt: &CmdEncrypt) -> XResult<u64> {
let path_display = format!("{}", path.display()); let path_display = format!("{}", path.display());
if path_display.ends_with(TINY_ENC_FILE_EXT) { if path_display.ends_with(TINY_ENC_FILE_EXT) {
information!("Tiny enc file skipped: {}", path_display); information!("Tiny enc file skipped: {}", path_display);
@@ -126,17 +132,17 @@ fn encrypt_single(path: &PathBuf, envelops: &[&TinyEncryptConfigEnvelop], cmd_en
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 path_out = format!("{}{}", path_display, TINY_ENC_FILE_EXT); util::require_file_not_exists(path_out)?;
util::require_file_not_exists(path_out.as_str())?;
let (key, nonce) = util::make_key256_and_nonce(); let (key, nonce) = util::make_key256_and_nonce();
let key_nonce = KeyNonce { k: &key.0, n: &nonce.0 };
let envelops = encrypt_envelops(cryptor, &key.0, envelops)?; let envelops = encrypt_envelops(cryptor, &key.0, envelops)?;
let encrypted_comment = match &cmd_encrypt.encrypted_comment { let encrypted_comment = match &cmd_encrypt.encrypted_comment {
None => None, None => None,
Some(encrypted_comment) => Some(util::encode_base64( Some(encrypted_comment) => Some(util::encode_base64(
&crypto_simple::encrypt_with_salt( &crypto_simple::encrypt_with_salt(
cryptor, &key.0, &nonce.0, SALT_COMMENT, encrypted_comment.as_bytes())?)) cryptor, &key_nonce, SALT_COMMENT, encrypted_comment.as_bytes())?))
}; };
let file_metadata = opt_result!(fs::metadata(path), "Read file: {} meta failed: {}", path.display()); let file_metadata = opt_result!(fs::metadata(path), "Read file: {} meta failed: {}", path.display());
@@ -146,7 +152,7 @@ fn encrypt_single(path: &PathBuf, envelops: &[&TinyEncryptConfigEnvelop], cmd_en
m_time: file_metadata.modified().ok().and_then(|t| t.to_millis()), m_time: file_metadata.modified().ok().and_then(|t| t.to_millis()),
}; };
let enc_encrypted_meta_bytes = opt_result!(enc_encrypted_meta.seal( let enc_encrypted_meta_bytes = opt_result!(enc_encrypted_meta.seal(
cryptor, &key.0, &nonce.0), "Seal enc-encrypted-meta failed: {}"); cryptor, &key_nonce), "Seal enc-encrypted-meta failed: {}");
let enc_metadata = EncMetadata { let enc_metadata = EncMetadata {
comment: cmd_encrypt.comment.clone(), comment: cmd_encrypt.comment.clone(),
@@ -172,7 +178,7 @@ fn encrypt_single(path: &PathBuf, envelops: &[&TinyEncryptConfigEnvelop], cmd_en
} }
} }
let mut file_out = File::create(&path_out)?; let mut file_out = File::create(path_out)?;
let compress_meta = !cmd_encrypt.disable_compress_meta; let compress_meta = !cmd_encrypt.disable_compress_meta;
let _ = util_enc_file::write_tiny_encrypt_meta(&mut file_out, &encrypt_meta, compress_meta)?; let _ = util_enc_file::write_tiny_encrypt_meta(&mut file_out, &encrypt_meta, compress_meta)?;
@@ -183,7 +189,7 @@ fn encrypt_single(path: &PathBuf, envelops: &[&TinyEncryptConfigEnvelop], cmd_en
let start = Instant::now(); let start = Instant::now();
encrypt_file( encrypt_file(
&mut file_in, file_metadata.len(), &mut file_out, cryptor, &mut file_in, file_metadata.len(), &mut file_out, cryptor,
&key.0, &nonce.0, &compress_level, &key_nonce, &compress_level,
)?; )?;
drop(file_out); drop(file_out);
let encrypt_duration = start.elapsed(); let encrypt_duration = start.elapsed();
@@ -216,7 +222,7 @@ fn process_compatible_with_1_0(mut encrypt_meta: TinyEncryptMeta) -> XResult<Tin
} }
fn encrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write, cryptor: Cryptor, fn encrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write, cryptor: Cryptor,
key: &[u8], nonce: &[u8], compress_level: &Option<u32>) -> XResult<u64> { key_nonce: &KeyNonce, compress_level: &Option<u32>) -> XResult<u64> {
let compress = compress_level.is_some(); let compress = compress_level.is_some();
let mut total_len = 0_u64; let mut total_len = 0_u64;
let mut write_len = 0_u64; let mut write_len = 0_u64;
@@ -231,7 +237,7 @@ fn encrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write, cr
} }
}; };
let progress = Progress::new(file_len); let progress = Progress::new(file_len);
let mut encryptor = cryptor.encryptor(key, nonce)?; let mut encryptor = cryptor.encryptor(key_nonce)?;
loop { loop {
let len = opt_result!(file_in.read(&mut buffer), "Read file failed: {}"); let len = opt_result!(file_in.read(&mut buffer), "Read file failed: {}");
if len == 0 { if len == 0 {
@@ -334,9 +340,10 @@ fn encrypt_envelop_shared_secret(cryptor: Cryptor,
envelop: &TinyEncryptConfigEnvelop) -> XResult<TinyEncryptEnvelop> { envelop: &TinyEncryptConfigEnvelop) -> XResult<TinyEncryptEnvelop> {
let shared_key = util::simple_kdf(shared_secret); let shared_key = util::simple_kdf(shared_secret);
let nonce = util::make_nonce(); let nonce = util::make_nonce();
let key_nonce = KeyNonce { k: &shared_key, n: &nonce.0 };
let encrypted_key = crypto_simple::encrypt( let encrypted_key = crypto_simple::encrypt(
cryptor, &shared_key, &nonce.0, key)?; cryptor, &key_nonce, key)?;
let wrap_key = WrapKey { let wrap_key = WrapKey {
header: WrapKeyHeader { header: WrapKeyHeader {

View File

@@ -4,13 +4,15 @@ use std::path::PathBuf;
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use clap::Args; use clap::Args;
use rust_util::{opt_result, simple_error, success, util_time, warning, XResult}; use rust_util::{debugging, failure, iff, opt_result, simple_error, success, 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;
use crate::{util_enc_file, util_envelop}; use crate::{util, util_enc_file, util_envelop};
use crate::config::TinyEncryptConfig; use crate::config::TinyEncryptConfig;
use crate::consts::{DATE_TIME_FORMAT, TINY_ENC_AES_GCM, TINY_ENC_CONFIG_FILE, TINY_ENC_FILE_EXT}; use crate::consts::{DATE_TIME_FORMAT, TINY_ENC_AES_GCM, TINY_ENC_CONFIG_FILE, TINY_ENC_FILE_EXT};
use crate::wrap_key::WrapKey;
#[derive(Debug, Args)] #[derive(Debug, Args)]
pub struct CmdInfo { pub struct CmdInfo {
@@ -25,7 +27,7 @@ pub fn info(cmd_info: CmdInfo) -> XResult<()> {
for (i, path) in cmd_info.paths.iter().enumerate() { for (i, path) in cmd_info.paths.iter().enumerate() {
if i > 0 { println!("{}", "-".repeat(88)); } if i > 0 { println!("{}", "-".repeat(88)); }
if let Err(e) = info_single(path, &cmd_info) { if let Err(e) = info_single(path, &cmd_info) {
warning!("Parse Tiny Encrypt file info failed: {}", e); failure!("Parse Tiny Encrypt file info failed: {}", e);
} }
} }
println!(); println!();
@@ -40,7 +42,9 @@ pub fn info_single(path: &PathBuf, cmd_info: &CmdInfo) -> XResult<()> {
let config = TinyEncryptConfig::load(TINY_ENC_CONFIG_FILE).ok(); let config = TinyEncryptConfig::load(TINY_ENC_CONFIG_FILE).ok();
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 file_in_len = file_in.metadata().map(|m| m.len()).unwrap_or(0);
let (meta_len, 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
); );
@@ -53,7 +57,20 @@ pub fn info_single(path: &PathBuf, cmd_info: &CmdInfo) -> XResult<()> {
infos.push("Tiny Encrypt File Info".to_string()); infos.push("Tiny Encrypt File Info".to_string());
let compressed = if meta.compress { " [compressed]" } else { "" }; let compressed = if meta.compress { " [compressed]" } else { "" };
infos.push(format!("{}: {}{}", header("File name"), path_display, compressed)); infos.push(format!("{}: {}{}", header("File name"), path_display, compressed));
infos.push(format!("{}: {} bytes", header("File size"), meta.file_length));
if meta.compress && file_in_len > (2 + 4 + meta_len as u64) {
let actual_file_in_len = file_in_len - 2 - 4 - meta_len as u64;
infos.push(format!("{}: {}, after compressed {}, ratio: {}%",
header("File size"),
util_size::get_display_size(meta.file_length as i64),
util_size::get_display_size(actual_file_in_len as i64),
util::ratio(actual_file_in_len, meta.file_length)
));
} else {
infos.push(format!("{}: {}", header("File size"),
util_size::get_display_size(meta.file_length as i64)));
}
infos.push(format!("{}: Version: {}, Agent: {}", infos.push(format!("{}: Version: {}, Agent: {}",
header("File summary"), meta.version, meta.user_agent) header("File summary"), meta.version, meta.user_agent)
); );
@@ -77,6 +94,11 @@ 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, || {
if let Ok(wrap_key) = WrapKey::parse(&envelop.encrypted_key) {
debugging!("Wrap key: {}", serde_json::to_string(&wrap_key).expect("SHOULD NOT HAPPEN"));
}
});
}) })
} }
@@ -105,5 +127,5 @@ fn header(h: &str) -> String {
} }
fn to_yes_or_no(opt: &Option<String>) -> String { fn to_yes_or_no(opt: &Option<String>) -> String {
opt.as_ref().map(|_| "YES".to_string()).unwrap_or_else(|| "NO".to_string()) iff!(opt.is_some(), "YES", "NO").to_string()
} }

View File

@@ -1,5 +1,6 @@
use clap::Args; use clap::Args;
use rust_util::XResult; use rust_util::XResult;
use crate::util; use crate::util;
#[derive(Debug, Args)] #[derive(Debug, Args)]

View File

@@ -4,6 +4,10 @@ use flate2::Compression;
use flate2::write::{GzDecoder, GzEncoder}; use flate2::write::{GzDecoder, GzEncoder};
use rust_util::{simple_error, XResult}; use rust_util::{simple_error, XResult};
pub fn compress_default(message: &[u8]) -> XResult<Vec<u8>> {
compress(Compression::default(), message)
}
pub fn compress(compression: Compression, message: &[u8]) -> XResult<Vec<u8>> { pub fn compress(compression: Compression, message: &[u8]) -> XResult<Vec<u8>> {
let mut encoder = GzStreamEncoder::new(compression); let mut encoder = GzStreamEncoder::new(compression);
let mut buff = encoder.update(message)?; let mut buff = encoder.update(message)?;

View File

@@ -2,7 +2,7 @@ use std::cmp::Ordering;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs; use std::fs;
use rust_util::{debugging, iff, opt_result, simple_error, XResult}; use rust_util::{debugging, opt_result, simple_error, XResult};
use rust_util::util_file::resolve_file_path; use rust_util::util_file::resolve_file_path;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@@ -57,20 +57,20 @@ impl TinyEncryptConfig {
); );
let mut config: TinyEncryptConfig = opt_result!( let mut config: TinyEncryptConfig = opt_result!(
serde_json::from_str(&config_contents),"Parse file: {}, failed: {}", file); serde_json::from_str(&config_contents),"Parse file: {}, failed: {}", file);
let mut splitted_profiles = HashMap::new(); let mut splited_profiles = HashMap::new();
for (k, v) in config.profiles.into_iter() { for (k, v) in config.profiles.into_iter() {
if !k.contains(',') { if !k.contains(',') {
splitted_profiles.insert(k, v); splited_profiles.insert(k, v);
} else { } else {
k.split(',') k.split(',')
.map(|k| k.trim()) .map(|k| k.trim())
.filter(|k| !k.is_empty()) .filter(|k| !k.is_empty())
.for_each(|k| { .for_each(|k| {
splitted_profiles.insert(k.to_string(), v.clone()); splited_profiles.insert(k.to_string(), v.clone());
}); });
} }
} }
config.profiles = splitted_profiles; config.profiles = splited_profiles;
Ok(config) Ok(config)
} }
@@ -84,7 +84,7 @@ impl TinyEncryptConfig {
pub fn find_by_kid(&self, kid: &str) -> Option<&TinyEncryptConfigEnvelop> { pub fn find_by_kid(&self, kid: &str) -> Option<&TinyEncryptConfigEnvelop> {
let config_envelops = self.find_by_kid_or_filter(kid, |_| false); let config_envelops = self.find_by_kid_or_filter(kid, |_| false);
iff!(config_envelops.is_empty(), None, Some(config_envelops[0])) config_envelops.first().map(|e| *e)
} }
pub fn find_by_kid_or_type(&self, k_filter: &str) -> Vec<&TinyEncryptConfigEnvelop> { pub fn find_by_kid_or_type(&self, k_filter: &str) -> Vec<&TinyEncryptConfigEnvelop> {

View File

@@ -5,6 +5,12 @@ use zeroize::Zeroize;
use crate::{consts, util_env}; use crate::{consts, util_env};
pub struct KeyNonce<'a, 'b> {
pub k: &'a [u8],
pub n: &'b [u8],
}
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub enum Cryptor { pub enum Cryptor {
Aes256Gcm, Aes256Gcm,
@@ -28,12 +34,12 @@ impl Cryptor {
name.to_string() name.to_string()
} }
pub fn encryptor(self, key: &[u8], nonce: &[u8]) -> XResult<Box<dyn Encryptor>> { pub fn encryptor(self, key_nonce: &KeyNonce) -> XResult<Box<dyn Encryptor>> {
get_encryptor(self, key, nonce) get_encryptor(self, key_nonce)
} }
pub fn decryptor(self, key: &[u8], nonce: &[u8]) -> XResult<Box<dyn Decryptor>> { pub fn decryptor(self, key_nonce: &KeyNonce) -> XResult<Box<dyn Decryptor>> {
get_decryptor(self, key, nonce) get_decryptor(self, key_nonce)
} }
} }
@@ -64,34 +70,34 @@ pub trait Decryptor {
} }
} }
fn get_encryptor(crypto: Cryptor, key: &[u8], nonce: &[u8]) -> XResult<Box<dyn Encryptor>> { fn get_encryptor(crypto: Cryptor, key_nonce: &KeyNonce) -> XResult<Box<dyn Encryptor>> {
match crypto { match crypto {
Cryptor::Aes256Gcm => { Cryptor::Aes256Gcm => {
let mut key: [u8; 32] = opt_result!(key.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, nonce); 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)?, chacha20_poly1305_stream_encryptor: ChaCha20Poly1305StreamEncryptor::new(key_nonce.k, key_nonce.n)?,
})) }))
} }
} }
fn get_decryptor(crypto: Cryptor, key: &[u8], nonce: &[u8]) -> XResult<Box<dyn Decryptor>> { fn get_decryptor(crypto: Cryptor, key_nonce: &KeyNonce) -> XResult<Box<dyn Decryptor>> {
match crypto { match crypto {
Cryptor::Aes256Gcm => { Cryptor::Aes256Gcm => {
let mut key: [u8; 32] = opt_result!(key.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, nonce); 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)?, chacha20_poly1305_stream_decryptor: ChaCha20Poly1305StreamDecryptor::new(key_nonce.k, key_nonce.n)?,
})) }))
} }
} }
@@ -170,9 +176,10 @@ pub fn get_cryptor_by_encryption_algorithm(encryption_algorithm: &Option<String>
fn test_cryptor() { fn test_cryptor() {
let key = [0u8; 32]; let key = [0u8; 32];
let nonce = [0u8; 12]; let nonce = [0u8; 12];
let ciphertext = Cryptor::Aes256Gcm.encryptor(&key, &nonce).unwrap() let key_nonce = KeyNonce { k: &key, n: &nonce };
let ciphertext = Cryptor::Aes256Gcm.encryptor(&key_nonce).unwrap()
.encrypt(b"hello world"); .encrypt(b"hello world");
let plaintext = Cryptor::Aes256Gcm.decryptor(&key, &nonce).unwrap() let plaintext = Cryptor::Aes256Gcm.decryptor(&key_nonce).unwrap()
.decrypt(&ciphertext).unwrap(); .decrypt(&ciphertext).unwrap();
assert_eq!(b"hello world", plaintext.as_slice()); assert_eq!(b"hello world", plaintext.as_slice());

View File

@@ -1,26 +1,28 @@
use rust_util::XResult; use rust_util::XResult;
use crate::crypto_cryptor::Cryptor; use crate::crypto_cryptor::{Cryptor, KeyNonce};
pub fn try_decrypt_with_salt(crypto: Cryptor, key: &[u8], nonce: &[u8], salt: &[u8], message: &[u8]) -> XResult<Vec<u8>> { pub fn try_decrypt_with_salt(crypto: Cryptor, key_nonce: &KeyNonce, salt: &[u8], message: &[u8]) -> XResult<Vec<u8>> {
let new_nonce = build_salted_nonce(nonce, salt); let new_nonce = build_salted_nonce(key_nonce.n, salt);
if let Ok(decrypted) = decrypt(crypto, key, &new_nonce, message) { let new_key_nonce = KeyNonce { k: key_nonce.k, n: &new_nonce };
if let Ok(decrypted) = decrypt(crypto, &new_key_nonce, message) {
return Ok(decrypted); return Ok(decrypted);
} }
decrypt(crypto, key, nonce, message) decrypt(crypto, key_nonce, message)
} }
pub fn decrypt(crypto: Cryptor, key: &[u8], nonce: &[u8], message: &[u8]) -> XResult<Vec<u8>> { pub fn decrypt(crypto: Cryptor, key_nonce: &KeyNonce, message: &[u8]) -> XResult<Vec<u8>> {
crypto.decryptor(key, nonce)?.decrypt(message) crypto.decryptor(key_nonce)?.decrypt(message)
} }
pub fn encrypt_with_salt(crypto: Cryptor, key: &[u8], nonce: &[u8], salt: &[u8], message: &[u8]) -> XResult<Vec<u8>> { pub fn encrypt_with_salt(crypto: Cryptor, key_nonce: &KeyNonce, salt: &[u8], message: &[u8]) -> XResult<Vec<u8>> {
let new_nonce = build_salted_nonce(nonce, salt); let new_nonce = build_salted_nonce(key_nonce.n, salt);
encrypt(crypto, key, &new_nonce, message) let new_key_nonce = KeyNonce { k: key_nonce.k, n: &new_nonce };
encrypt(crypto, &new_key_nonce, message)
} }
pub fn encrypt(crypto: Cryptor, key: &[u8], nonce: &[u8], message: &[u8]) -> XResult<Vec<u8>> { pub fn encrypt(crypto: Cryptor, key_nonce: &KeyNonce, message: &[u8]) -> XResult<Vec<u8>> {
Ok(crypto.encryptor(key, nonce)?.encrypt(message)) Ok(crypto.encryptor(key_nonce)?.encrypt(message))
} }
fn build_salted_nonce(nonce: &[u8], salt: &[u8]) -> Vec<u8> { fn build_salted_nonce(nonce: &[u8], salt: &[u8]) -> Vec<u8> {

41
src/lib.rs Normal file
View File

@@ -0,0 +1,41 @@
pub use cmd_config::CmdConfig;
pub use cmd_config::config;
pub use cmd_decrypt::CmdDecrypt;
pub use cmd_decrypt::decrypt;
pub use cmd_decrypt::decrypt_single;
pub use cmd_encrypt::CmdEncrypt;
pub use cmd_encrypt::encrypt;
pub use cmd_encrypt::encrypt_single;
pub use cmd_encrypt::encrypt_single_file_out;
pub use cmd_info::CmdInfo;
pub use cmd_info::info;
pub use cmd_info::info_single;
pub use cmd_version::CmdVersion;
pub use cmd_version::version;
mod consts;
mod util;
mod util_env;
mod util_digest;
mod util_progress;
mod util_piv;
mod util_pgp;
mod util_p256;
mod util_p384;
mod util_x25519;
mod compress;
mod config;
mod spec;
mod crypto_simple;
mod crypto_rsa;
mod crypto_cryptor;
mod wrap_key;
mod util_envelop;
mod util_file;
mod util_enc_file;
mod cmd_version;
mod cmd_config;
mod cmd_info;
mod cmd_decrypt;
mod cmd_encrypt;

View File

@@ -3,37 +3,7 @@ extern crate core;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use rust_util::XResult; use rust_util::XResult;
use crate::cmd_config::CmdConfig; use tiny_encrypt::{CmdConfig, CmdDecrypt, CmdEncrypt, CmdInfo, CmdVersion};
use crate::cmd_decrypt::CmdDecrypt;
use crate::cmd_encrypt::CmdEncrypt;
use crate::cmd_info::CmdInfo;
use crate::cmd_version::CmdVersion;
mod consts;
mod util;
mod util_env;
mod util_digest;
mod util_progress;
mod util_piv;
mod util_pgp;
mod util_p256;
mod util_p384;
mod util_x25519;
mod compress;
mod config;
mod spec;
mod crypto_simple;
mod crypto_rsa;
mod crypto_cryptor;
mod wrap_key;
mod util_envelop;
mod util_file;
mod util_enc_file;
mod cmd_version;
mod cmd_config;
mod cmd_info;
mod cmd_decrypt;
mod cmd_encrypt;
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
#[command(name = "tiny-encrypt-rs")] #[command(name = "tiny-encrypt-rs")]
@@ -65,10 +35,10 @@ enum Commands {
fn main() -> XResult<()> { fn main() -> XResult<()> {
let args = Cli::parse(); let args = Cli::parse();
match args.command { match args.command {
Commands::Encrypt(cmd_encrypt) => cmd_encrypt::encrypt(cmd_encrypt), Commands::Encrypt(cmd_encrypt) => tiny_encrypt::encrypt(cmd_encrypt),
Commands::Decrypt(cmd_decrypt) => cmd_decrypt::decrypt(cmd_decrypt), Commands::Decrypt(cmd_decrypt) => tiny_encrypt::decrypt(cmd_decrypt),
Commands::Info(cmd_info) => cmd_info::info(cmd_info), Commands::Info(cmd_info) => tiny_encrypt::info(cmd_info),
Commands::Version(cmd_version) => cmd_version::version(cmd_version), Commands::Version(cmd_version) => tiny_encrypt::version(cmd_version),
Commands::Config(cmd_config) => cmd_config::config(cmd_config), Commands::Config(cmd_config) => tiny_encrypt::config(cmd_config),
} }
} }

View File

@@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use crate::{compress, crypto_simple}; use crate::{compress, crypto_simple};
use crate::consts::SALT_META; use crate::consts::SALT_META;
use crate::crypto_cryptor::Cryptor; use crate::crypto_cryptor::{Cryptor, KeyNonce};
use crate::util::{encode_base64, get_user_agent}; use crate::util::{encode_base64, get_user_agent};
pub const TINY_ENCRYPT_VERSION_10: &str = "1.0"; pub const TINY_ENCRYPT_VERSION_10: &str = "1.0";
@@ -105,21 +105,21 @@ pub struct EncEncryptedMeta {
} }
impl EncEncryptedMeta { impl EncEncryptedMeta {
pub fn unseal(crypto: Cryptor, key: &[u8], nonce: &[u8], message: &[u8]) -> XResult<Self> { pub fn unseal(crypto: Cryptor, key_nonce: &KeyNonce, message: &[u8]) -> XResult<Self> {
let mut decrypted = opt_result!(crypto_simple::try_decrypt_with_salt( let mut decrypted = opt_result!(crypto_simple::try_decrypt_with_salt(
crypto, key, nonce, SALT_META, message), "Decrypt failed: {}"); crypto, key_nonce, SALT_META, message), "Decrypt failed: {}");
decrypted = opt_result!(compress::decompress(&decrypted), "Decode faield: {}"); decrypted = opt_result!(compress::decompress(&decrypted), "Decode faield: {}");
let meta = opt_result!( let meta = opt_result!(
serde_json::from_slice::<Self>(&decrypted), "Parse failed: {}"); serde_json::from_slice::<Self>(&decrypted), "Parse failed: {}");
Ok(meta) Ok(meta)
} }
pub fn seal(&self, crypto: Cryptor, key: &[u8], nonce: &[u8]) -> XResult<Vec<u8>> { pub fn seal(&self, crypto: Cryptor, key_nonce: &KeyNonce) -> XResult<Vec<u8>> {
let mut encrypted_meta_json = serde_json::to_vec(self).unwrap(); let mut encrypted_meta_json = serde_json::to_vec(self).unwrap();
encrypted_meta_json = opt_result!( encrypted_meta_json = opt_result!(
compress::compress(Compression::default(), &encrypted_meta_json), "Compress failed: {}"); compress::compress(Compression::default(), &encrypted_meta_json), "Compress failed: {}");
let encrypted = opt_result!(crypto_simple::encrypt_with_salt( let encrypted = opt_result!(crypto_simple::encrypt_with_salt(
crypto, key, nonce, SALT_META, encrypted_meta_json.as_slice()), "Encrypt failed: {}"); crypto, key_nonce, SALT_META, encrypted_meta_json.as_slice()), "Encrypt failed: {}");
Ok(encrypted) Ok(encrypted)
} }
} }

View File

@@ -1,6 +1,5 @@
use std::io::{Read, Write}; use std::io::{Read, Write};
use flate2::Compression;
use rust_util::{debugging, iff, opt_result, simple_error, XResult}; use rust_util::{debugging, iff, opt_result, simple_error, XResult};
use crate::compress; use crate::compress;
@@ -13,7 +12,7 @@ pub fn write_tiny_encrypt_meta(w: &mut impl Write, meta: &TinyEncryptMeta, compr
let mut encrypted_meta_bytes = opt_result!(serde_json::to_vec(&meta), "Generate meta json bytes failed: {}"); let mut encrypted_meta_bytes = opt_result!(serde_json::to_vec(&meta), "Generate meta json bytes failed: {}");
if compress_meta { if compress_meta {
encrypted_meta_bytes = opt_result!( encrypted_meta_bytes = opt_result!(
compress::compress(Compression::default(), &encrypted_meta_bytes), "Compress encrypted meta failed: {}"); compress::compress_default(&encrypted_meta_bytes), "Compress encrypted meta failed: {}");
} }
let encrypted_meta_bytes_len = encrypted_meta_bytes.len() as u32; let encrypted_meta_bytes_len = encrypted_meta_bytes.len() as u32;
debugging!("Encrypted meta len: {}", encrypted_meta_bytes_len); debugging!("Encrypted meta len: {}", encrypted_meta_bytes_len);
@@ -23,16 +22,17 @@ pub fn write_tiny_encrypt_meta(w: &mut impl Write, meta: &TinyEncryptMeta, compr
Ok(encrypted_meta_bytes.len() + 2 + 4) Ok(encrypted_meta_bytes.len() + 2 + 4)
} }
pub fn read_tiny_encrypt_meta_and_normalize(r: &mut impl Read) -> XResult<TinyEncryptMeta> { pub fn read_tiny_encrypt_meta_and_normalize(r: &mut impl Read) -> XResult<(u32, TinyEncryptMeta)> {
let mut meta = read_tiny_encrypt_meta(r); let mut meta_and_len = read_tiny_encrypt_meta(r);
let _ = meta.as_mut().map(|meta| meta.normalize()); let _ = meta_and_len.as_mut().map(|meta| meta.1.normalize());
meta meta_and_len
} }
pub fn read_tiny_encrypt_meta(r: &mut impl Read) -> XResult<TinyEncryptMeta> { pub fn read_tiny_encrypt_meta(r: &mut impl Read) -> XResult<(u32, TinyEncryptMeta)> {
let mut tag_buff = [0_u8; 2]; let mut tag_buff = [0_u8; 2];
opt_result!(r.read_exact(&mut tag_buff), "Read tag failed: {}"); opt_result!(r.read_exact(&mut tag_buff), "Read tag failed: {}");
let tag = u16::from_be_bytes(tag_buff); let tag = u16::from_be_bytes(tag_buff);
debugging!("Found tag: {}", tag);
let is_normal_tiny_enc = tag == TINY_ENC_MAGIC_TAG; let is_normal_tiny_enc = tag == TINY_ENC_MAGIC_TAG;
let is_compressed_tiny_enc = tag == TINY_ENC_COMPRESSED_MAGIC_TAG; let is_compressed_tiny_enc = tag == TINY_ENC_COMPRESSED_MAGIC_TAG;
if !is_normal_tiny_enc && !is_compressed_tiny_enc { if !is_normal_tiny_enc && !is_compressed_tiny_enc {
@@ -57,5 +57,5 @@ pub fn read_tiny_encrypt_meta(r: &mut impl Read) -> XResult<TinyEncryptMeta> {
} }
debugging!("Encrypted meta: {}", String::from_utf8_lossy(&meta_buff)); debugging!("Encrypted meta: {}", String::from_utf8_lossy(&meta_buff));
Ok(opt_result!(serde_json::from_slice(&meta_buff), "Parse meta failed: {}")) Ok((length, opt_result!(serde_json::from_slice(&meta_buff), "Parse meta failed: {}")))
} }

View File

@@ -1,15 +1,18 @@
use std::env; use std::env;
use rust_util::{debugging, warning};
use crate::consts; use crate::consts;
pub fn get_default_encryption_algorithm() -> Option<&'static str> { pub fn get_default_encryption_algorithm() -> Option<&'static str> {
let env_default_algorithm = env::var(consts::TINY_ENCRYPT_ENV_DEFAULT_ALGORITHM).ok(); let env_default_algorithm = env::var(consts::TINY_ENCRYPT_ENV_DEFAULT_ALGORITHM).ok();
debugging!("Environment variable {} = {:?}", consts::TINY_ENCRYPT_ENV_DEFAULT_ALGORITHM, env_default_algorithm);
if let Some(env_algorithm) = env_default_algorithm { if let Some(env_algorithm) = env_default_algorithm {
let lower_default_algorithm = env_algorithm.to_lowercase(); let lower_default_algorithm = env_algorithm.to_lowercase();
match lower_default_algorithm.as_str() { match lower_default_algorithm.as_str() {
"aes" | "aes/gcm" => return Some(consts::TINY_ENC_AES_GCM), "aes" | "aes/gcm" => return Some(consts::TINY_ENC_AES_GCM),
"chacha20" | "chacha20/poly1305" => return Some(consts::TINY_ENC_CHACHA20_POLY1305), "chacha20" | "chacha20/poly1305" => return Some(consts::TINY_ENC_CHACHA20_POLY1305),
_ => {} _ => { warning!("Not matched any algorithm: {}", env_algorithm); }
} }
} }
None None