use serde::{Deserialize, Serialize}; pub const TINY_ENCRYPT_VERSION: &'static str = "1.0"; #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TinyEncryptConfig { // card cli is not used by tiny-encrypt-rs pub card_cli: String, pub default_key_name: String, pub local_private_key_pem_challenge: String, pub local_private_key_pem_encrypted: String, pub local_public_key_pem: String, pub pgp_encrypt_public_key_pem: Option, } /// Specification: https://git.hatter.ink/hatter/tiny-encrypt-java/src/branch/master/TinyEncryptSpecV1.1.md #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TinyEncryptMeta { pub version: String, pub created: u64, pub user_agent: String, pub comment: Option, pub encrypted_comment: Option, pub encrypted_meta: Option, // --------------------------------------- pub pgp_envelop: Option, pub pgp_fingerprint: Option, pub age_envelop: Option, pub age_recipient: Option, pub ecdh_envelop: Option, pub ecdh_point: Option, pub envelop: Option, // --------------------------------------- pub envelops: Vec, pub encryption_algorithm: Option, pub nonce: String, pub file_length: u64, pub file_last_modified: u64, pub compress: bool, } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TinyEncryptEnvelop { pub r#type: String, pub kid: String, pub desc: Option, pub encrypted_key: String, } // use serde... pub enum TinyEncryptEnvelopType { Pgp, Age, Ecdh, Kms, } impl TinyEncryptMeta { pub fn normalize(&mut self) { self.normalize_ppg_envelop(); self.normalize_age_envelop(); self.normalize_ecdh_envelop(); self.normalize_envelop(); } fn normalize_ppg_envelop(&mut self) { if let (Some(pgp_envelop), Some(pgp_fingerprint)) = (&self.pgp_envelop, &self.pgp_fingerprint) { self.envelops.push(TinyEncryptEnvelop { r#type: "pgp".to_string(), kid: pgp_fingerprint.into(), desc: None, encrypted_key: pgp_envelop.into(), }); self.pgp_envelop = None; self.pgp_fingerprint = None; } } fn normalize_age_envelop(&mut self) { if let (Some(age_envelop), Some(age_recipient)) = (&self.age_envelop, &self.age_recipient) { self.envelops.push(TinyEncryptEnvelop { r#type: "age".to_string(), kid: age_recipient.into(), desc: None, encrypted_key: age_envelop.into(), }); self.age_envelop = None; self.age_recipient = None; } } fn normalize_ecdh_envelop(&mut self) { if let (Some(ecdh_envelop), Some(ecdh_point)) = (&self.ecdh_envelop, &self.ecdh_point) { self.envelops.push(TinyEncryptEnvelop { r#type: "ecdh".to_string(), kid: ecdh_point.into(), desc: None, encrypted_key: ecdh_envelop.into(), }); self.ecdh_envelop = None; self.ecdh_point = None; } } fn normalize_envelop(&mut self) { if let Some(envelop) = &self.envelop { self.envelops.push(TinyEncryptEnvelop { r#type: "kms".to_string(), kid: "#default".into(), desc: None, encrypted_key: envelop.into(), }); self.envelop = None; } } } pub fn get_user_agent() -> String { format!("TinyEncrypt-rs v{}@{}", env!("CARGO_PKG_VERSION"), if cfg!(target_os = "macos") { "MacOS" } else if cfg!(target_os = "ios") { "iOS" } else if cfg!(target_os = "android") { "Android" } else if cfg!(target_os = "windows") { "Windows" } else if cfg!(target_os = "linux") { "Linux" } else if cfg!(target_os = "freebsd") { "FreeBSD" } else if cfg!(target_os = "dragonfly") { "Dragonfly" } else if cfg!(target_os = "openbsd") { "OpenBSD" } else if cfg!(target_os = "netbsd") { "NetBSD" } else { panic!("Unsupported OS!"); } ) }