// syntax // tiny-encrypt-key:type:sid:key_id:public_part[?key=value] // e.g. // tiny-encrypt-key:ext-p256:ext-key-1:02536aef5742b4288f1b44b3cc96f1556c35e4fac4e8e117e1f7ae091e42d0835b:04536aef5742b4288f1b44b3cc96f1556c35e4fac4e8e117e1f7ae091e42d0835bf3f95d932c22a74a91859bd7fdd8829a02d38cf4ec598b1cf6e02fa09f707a6f use crate::config::TinyEncryptConfigEnvelop; use crate::spec::TinyEncryptEnvelopType; use rust_util::{debugging, iff, opt_result, opt_value_result, simple_error, XResult}; const TINY_ENCRYPT_KEY_PREFIX: &str = "tiny-encrypt-key:"; pub fn serialize_config_envelop(config_envelop: &TinyEncryptConfigEnvelop) -> String { let mut s = String::new(); s.push_str(TINY_ENCRYPT_KEY_PREFIX); s.push_str(config_envelop.r#type.get_name()); s.push(':'); s.push_str(&encode(config_envelop.sid.as_deref().unwrap_or(""))); s.push(':'); s.push_str(&encode(&config_envelop.kid)); s.push(':'); s.push_str(&encode(&config_envelop.public_part)); s } pub fn parse_temporary_keys(temporary_keys: &Option>) -> XResult> { let mut temporary_envelops = vec![]; if let Some(temporary_key) = temporary_keys { for t_key in temporary_key { let envelop = opt_result!(deserialize_config_envelop(t_key), "Parse temporary key: {} failed: {}", t_key); temporary_envelops.push(envelop); } debugging!("Temporary envelops: {:?}", temporary_envelops); } Ok(temporary_envelops) } pub fn deserialize_config_envelop(k: &str) -> XResult { if !k.starts_with(TINY_ENCRYPT_KEY_PREFIX) { return simple_error!("invalid temporary key"); } let k_parts = k.split(":").collect::>(); if k_parts.len() != 5 { return simple_error!("invalid temporary key (parts)"); } let envelop_type = opt_value_result!( TinyEncryptEnvelopType::from_name(k_parts[1]), "Unknown envelop type: {}", k_parts[1]); Ok(TinyEncryptConfigEnvelop { r#type: envelop_type, sid: iff!(k_parts[2].is_empty(), None, Some(decode(k_parts[2])?)), kid: decode(k_parts[3])?, desc: None, args: None, public_part: decode(k_parts[4])?, profiles: None, }) } fn encode(s: &str) -> String { percent_encoding::utf8_percent_encode(s, percent_encoding::NON_ALPHANUMERIC).to_string() } fn decode(s: &str) -> XResult { Ok(opt_result!( percent_encoding::percent_decode_str(s).decode_utf8(), "decode: {} failed: {}", s ) .to_string()) }