diff --git a/Cargo.toml b/Cargo.toml
index 1e21b9f..794f9ce 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "tiny-encrypt"
-version = "0.0.2"
+version = "0.0.3"
edition = "2021"
license = "MIT"
description = "A simple and tiny file encrypt tool"
diff --git a/README.md b/README.md
index ba4e082..c5812aa 100644
--- a/README.md
+++ b/README.md
@@ -5,32 +5,37 @@ Tiny encrypt for Rust
> Tiny encrypt spec see: https://git.hatter.ink/hatter/tiny-encrypt-java
TODOs:
-* Decrypt supports compress
-* Encrypt subcommand
+* Encrypt subcommand
Encrypt config `~/.tinyencrypt/config-rs.json`:
+
```json
{
- "envelops": [
- {
- "type": "pgp",
- "kid": "KID-1",
- "desc": "this is key 001",
- "publicPart": "----- BEGIN OPENPGP ..."
- },
- {
- "type": "ecdh",
- "kid": "KID-2",
- "desc": "this is key 002",
- "publicPart": "04..."
- }
- ],
- "profiles": {
- "default": ["KID-1", "KID-2"],
- "leve2": ["KID-2"]
- }
- }
+ "envelops": [
+ {
+ "type": "pgp",
+ "kid": "KID-1",
+ "desc": "this is key 001",
+ "publicPart": "----- BEGIN OPENPGP ..."
+ },
+ {
+ "type": "ecdh",
+ "kid": "KID-2",
+ "desc": "this is key 002",
+ "publicPart": "04..."
+ }
+ ],
+ "profiles": {
+ "default": [
+ "KID-1",
+ "KID-2"
+ ],
+ "leve2": [
+ "KID-2"
+ ]
+ }
+}
```
diff --git a/src/cmd_decrypt.rs b/src/cmd_decrypt.rs
index ee40294..0570139 100644
--- a/src/cmd_decrypt.rs
+++ b/src/cmd_decrypt.rs
@@ -15,6 +15,7 @@ use yubikey::YubiKey;
use crate::{file, util};
use crate::card::get_card;
+use crate::compress::GzStreamDecoder;
use crate::crypto::aes_gcm_decrypt;
use crate::spec::{TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta};
use crate::util::{decode_base64, decode_base64_url_no_pad, ENC_AES256_GCM_P256, simple_kdf, TINY_ENC_FILE_EXT};
@@ -66,26 +67,40 @@ pub fn decrypt_single(path: &PathBuf, pin: &Option, slot: &Option XResult {
+fn decrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8], compress: bool) -> XResult {
let mut total_len = 0;
let mut buffer = [0u8; 1024 * 8];
let key = opt_result!(key.try_into(), "Key is not 32 bytes: {}");
let mut decryptor = aes_gcm_stream::Aes256GcmStreamDecryptor::new(key, &nonce);
+ let mut gz_decoder = GzStreamDecoder::new();
loop {
let len = opt_result!(file_in.read(&mut buffer), "Read file failed: {}");
if len == 0 {
let last_block = opt_result!(decryptor.finalize(), "Decrypt file failed: {}");
+ let last_block = if compress {
+ let mut decompressed = opt_result!(gz_decoder.update(&last_block), "Decompress file failed: {}");
+ let last_decompressed_buffer = opt_result!(gz_decoder.finalize(), "Decompress file failed: {}");
+ decompressed.extend_from_slice(&last_decompressed_buffer);
+ decompressed
+ } else {
+ last_block
+ };
opt_result!(file_out.write_all(&last_block), "Write file failed: {}");
success!("Decrypt finished, total bytes: {}", total_len);
break;
} else {
total_len += len;
let decrypted = decryptor.update(&buffer[0..len]);
+ let decrypted = if compress {
+ opt_result!(gz_decoder.update(&decrypted), "Decompress file failed: {}")
+ } else {
+ decrypted
+ };
opt_result!(file_out.write_all(&decrypted), "Write file failed: {}");
}
}