Files
tiny-encrypt-rs/src/temporary_key.rs
2025-12-28 20:18:39 +08:00

70 lines
2.5 KiB
Rust

// 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<Vec<String>>) -> XResult<Vec<TinyEncryptConfigEnvelop>> {
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<TinyEncryptConfigEnvelop> {
if !k.starts_with(TINY_ENCRYPT_KEY_PREFIX) {
return simple_error!("invalid temporary key");
}
let k_parts = k.split(":").collect::<Vec<_>>();
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<String> {
Ok(opt_result!(
percent_encoding::percent_decode_str(s).decode_utf8(),
"decode: {} failed: {}",
s
)
.to_string())
}