feat: updates
This commit is contained in:
@@ -3,14 +3,13 @@ use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use base64::Engine;
|
||||
use openpgp_card::crypto_data::Cryptogram;
|
||||
use openpgp_card::OpenPgp;
|
||||
use rust_util::{debugging, failure, opt_result, simple_error, success, util_term, XResult};
|
||||
|
||||
use crate::{file, util};
|
||||
use crate::card::get_card;
|
||||
use crate::spec::{TinyEncryptEnvelop, TinyEncryptMeta};
|
||||
use crate::spec::{TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta};
|
||||
use crate::util::{decode_base64, TINY_ENC_FILE_EXT};
|
||||
|
||||
pub fn decrypt(path: &PathBuf, pin: &Option<String>) -> XResult<()> {
|
||||
@@ -51,26 +50,22 @@ fn decrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8
|
||||
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: {}");
|
||||
if !last_block.is_empty() {
|
||||
opt_result!(file_out.write_all(&last_block), "Write file failed: {}");
|
||||
}
|
||||
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]);
|
||||
if !decrypted.is_empty() {
|
||||
opt_result!(file_out.write_all(&decrypted), "Write file failed: {}");
|
||||
}
|
||||
opt_result!(file_out.write_all(&decrypted), "Write file failed: {}");
|
||||
}
|
||||
}
|
||||
Ok(total_len)
|
||||
}
|
||||
|
||||
fn try_decrypt_key(envelop: &TinyEncryptEnvelop, pin: &Option<String>) -> XResult<Vec<u8>> {
|
||||
match envelop.r#type.to_lowercase().as_str() {
|
||||
"pgp" => try_decrypt_key_pgp(envelop, pin),
|
||||
unknown_type => return simple_error!("Unknown or not supported type: {}", unknown_type)
|
||||
match envelop.r#type {
|
||||
TinyEncryptEnvelopType::Pgp => try_decrypt_key_pgp(envelop, pin),
|
||||
unknown_type => return simple_error!("Unknown or not supported type: {}", unknown_type.get_name())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,13 +119,13 @@ fn select_envelop(meta: &TinyEncryptMeta) -> XResult<&TinyEncryptEnvelop> {
|
||||
success!("Found {} envelops:", envelops.len());
|
||||
if envelops.len() == 1 {
|
||||
let selected_envelop = &envelops[0];
|
||||
success!("Auto selected envelop: #{} {}", 1, selected_envelop.r#type.to_uppercase());
|
||||
success!("Auto selected envelop: #{} {}", 1, selected_envelop.r#type.get_upper_name());
|
||||
return Ok(selected_envelop);
|
||||
}
|
||||
|
||||
envelops.iter().enumerate().for_each(|(i, envelop)| {
|
||||
println!("#{} {}{}", i + 1,
|
||||
envelop.r#type.to_uppercase(),
|
||||
envelop.r#type.get_upper_name(),
|
||||
if envelop.kid.is_empty() {
|
||||
"".into()
|
||||
} else {
|
||||
@@ -141,6 +136,6 @@ fn select_envelop(meta: &TinyEncryptMeta) -> XResult<&TinyEncryptEnvelop> {
|
||||
|
||||
let envelop_number = util::read_number("Please select an envelop:", 1, envelops.len());
|
||||
let selected_envelop = &envelops[envelop_number - 1];
|
||||
success!("Selected envelop: #{} {}", envelop_number, selected_envelop.r#type.to_uppercase());
|
||||
success!("Selected envelop: #{} {}", envelop_number, selected_envelop.r#type.get_upper_name());
|
||||
Ok(selected_envelop)
|
||||
}
|
||||
@@ -46,7 +46,7 @@ pub fn info(path: PathBuf, raw_meta: bool) -> XResult<()> {
|
||||
meta.envelops.as_ref().map(|envelops| envelops.iter().enumerate().for_each(|(i, envelop)| {
|
||||
infos.push(format!("{}: {}{}{}",
|
||||
header(&format!("Envelop #{}", i + 1)),
|
||||
envelop.r#type.to_uppercase(),
|
||||
envelop.r#type.get_upper_name(),
|
||||
iff!(envelop.kid.is_empty(), "".into(), format!(", Kid: {}", envelop.kid)),
|
||||
iff!(envelop.desc.is_none(), "".into(), format!(", Desc: {}", envelop.desc.as_ref().unwrap()))
|
||||
));
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use aes_gcm_stream::Aes256GcmStreamDecryptor;
|
||||
|
||||
#[test]
|
||||
fn test_aes_gcm_01() {
|
||||
|
||||
@@ -35,6 +35,7 @@ enum Commands {
|
||||
Decrypt {
|
||||
/// Files need to be decrypted
|
||||
paths: Vec<PathBuf>,
|
||||
/// PIN
|
||||
#[arg(long)]
|
||||
pin: Option<String>,
|
||||
},
|
||||
@@ -56,7 +57,7 @@ fn main() -> XResult<()> {
|
||||
paths.iter().for_each(|f| information!("{:?}", f));
|
||||
Ok(())
|
||||
}
|
||||
Commands::Decrypt { mut paths, pin } => {
|
||||
Commands::Decrypt { paths, pin } => {
|
||||
for path in &paths {
|
||||
match cmd_decrypt::decrypt(path, &pin) {
|
||||
Ok(_) => success!("Decrypt {} succeed", path.to_str().unwrap_or("N/A")),
|
||||
|
||||
38
src/spec.rs
38
src/spec.rs
@@ -2,10 +2,10 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const TINY_ENCRYPT_VERSION: &'static str = "1.0";
|
||||
|
||||
pub const ENVELOP_TYPE_KMS: &'static str = "kms";
|
||||
pub const ENVELOP_TYPE_PGP: &'static str = "pgp";
|
||||
pub const ENVELOP_TYPE_AGE: &'static str = "age";
|
||||
pub const ENVELOP_TYPE_ECDH: &'static str = "ecdh";
|
||||
// pub const ENVELOP_TYPE_KMS: &'static str = "kms";
|
||||
// pub const ENVELOP_TYPE_PGP: &'static str = "pgp";
|
||||
// pub const ENVELOP_TYPE_AGE: &'static str = "age";
|
||||
// pub const ENVELOP_TYPE_ECDH: &'static str = "ecdh";
|
||||
|
||||
/// Specification: [Tiny Encrypt Spec V1.1](https://git.hatter.ink/hatter/tiny-encrypt-java/src/branch/master/TinyEncryptSpecV1.1.md)
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
@@ -37,20 +37,38 @@ pub struct TinyEncryptMeta {
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TinyEncryptEnvelop {
|
||||
pub r#type: String,
|
||||
pub r#type: TinyEncryptEnvelopType,
|
||||
pub kid: String,
|
||||
pub desc: Option<String>,
|
||||
pub encrypted_key: String,
|
||||
}
|
||||
|
||||
// use serde...
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub enum TinyEncryptEnvelopType {
|
||||
#[serde(rename = "pgp")]
|
||||
Pgp,
|
||||
#[serde(rename = "age")]
|
||||
Age,
|
||||
#[serde(rename = "ecdh")]
|
||||
Ecdh,
|
||||
#[serde(rename = "kms")]
|
||||
Kms,
|
||||
}
|
||||
|
||||
impl TinyEncryptEnvelopType {
|
||||
pub fn get_upper_name(&self) -> String {
|
||||
self.get_name().to_uppercase()
|
||||
}
|
||||
pub fn get_name(&self) -> &'static str {
|
||||
match self {
|
||||
TinyEncryptEnvelopType::Pgp => "pgp",
|
||||
TinyEncryptEnvelopType::Age => "age",
|
||||
TinyEncryptEnvelopType::Ecdh => "ecdh",
|
||||
TinyEncryptEnvelopType::Kms => "kms",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TinyEncryptMeta {
|
||||
pub fn normalize(&mut self) {
|
||||
if self.envelops.is_none() {
|
||||
@@ -65,7 +83,7 @@ impl TinyEncryptMeta {
|
||||
fn normalize_envelop(&mut self) {
|
||||
if let (Some(envelop), Some(envelops)) = (&self.envelop, &mut self.envelops) {
|
||||
envelops.push(TinyEncryptEnvelop {
|
||||
r#type: ENVELOP_TYPE_KMS.into(),
|
||||
r#type: TinyEncryptEnvelopType::Kms,
|
||||
kid: "".into(),
|
||||
desc: None,
|
||||
encrypted_key: envelop.into(),
|
||||
@@ -78,7 +96,7 @@ impl TinyEncryptMeta {
|
||||
if let (Some(pgp_envelop), Some(pgp_fingerprint), Some(envelops))
|
||||
= (&self.pgp_envelop, &self.pgp_fingerprint, &mut self.envelops) {
|
||||
envelops.push(TinyEncryptEnvelop {
|
||||
r#type: ENVELOP_TYPE_PGP.into(),
|
||||
r#type: TinyEncryptEnvelopType::Pgp,
|
||||
kid: pgp_fingerprint.into(),
|
||||
desc: None,
|
||||
encrypted_key: pgp_envelop.into(),
|
||||
@@ -92,7 +110,7 @@ impl TinyEncryptMeta {
|
||||
if let (Some(age_envelop), Some(age_recipient), Some(envelops))
|
||||
= (&self.age_envelop, &self.age_recipient, &mut self.envelops) {
|
||||
envelops.push(TinyEncryptEnvelop {
|
||||
r#type: ENVELOP_TYPE_AGE.into(),
|
||||
r#type: TinyEncryptEnvelopType::Age,
|
||||
kid: age_recipient.into(),
|
||||
desc: None,
|
||||
encrypted_key: age_envelop.into(),
|
||||
@@ -106,7 +124,7 @@ impl TinyEncryptMeta {
|
||||
if let (Some(ecdh_envelop), Some(ecdh_point), Some(envelops))
|
||||
= (&self.ecdh_envelop, &self.ecdh_point, &mut self.envelops) {
|
||||
envelops.push(TinyEncryptEnvelop {
|
||||
r#type: ENVELOP_TYPE_ECDH.into(),
|
||||
r#type: TinyEncryptEnvelopType::Ecdh,
|
||||
kid: ecdh_point.into(),
|
||||
desc: None,
|
||||
encrypted_key: ecdh_envelop.into(),
|
||||
|
||||
Reference in New Issue
Block a user