Files
tiny-encrypt-rs/src/spec.rs
2023-09-02 13:41:52 +08:00

145 lines
4.5 KiB
Rust

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<String>,
}
/// 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<String>,
pub encrypted_comment: Option<String>,
pub encrypted_meta: Option<String>,
// ---------------------------------------
pub pgp_envelop: Option<String>,
pub pgp_fingerprint: Option<String>,
pub age_envelop: Option<String>,
pub age_recipient: Option<String>,
pub ecdh_envelop: Option<String>,
pub ecdh_point: Option<String>,
pub envelop: Option<String>,
// ---------------------------------------
pub envelops: Vec<TinyEncryptEnvelop>,
pub encryption_algorithm: Option<String>,
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<String>,
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!");
}
)
}