use serde::{Deserialize, Serialize};
use serde_enum_str::{Deserialize_enum_str, Serialize_enum_str};
use serde_json::Value;
use std::borrow::Cow;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub(crate) struct JWE<'a> {
pub protected: &'a str,
pub recipients: Vec<Recipient<'a>>,
pub iv: &'a str,
pub ciphertext: &'a str,
pub tag: &'a str,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub(crate) struct ProtectedHeader<'a> {
pub typ: Option<Cow<'a, str>>,
pub alg: Algorithm,
pub enc: EncAlgorithm,
#[serde(skip_serializing_if = "Option::is_none")]
pub skid: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub apu: Option<&'a str>,
pub apv: &'a str,
pub epk: Value,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub(crate) struct Recipient<'a> {
pub header: PerRecipientHeader<'a>,
pub encrypted_key: &'a str,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub(crate) struct PerRecipientHeader<'a> {
pub kid: &'a str,
}
#[derive(Deserialize_enum_str, Serialize_enum_str, Debug, Clone, Eq, PartialEq)]
pub(crate) enum Algorithm {
#[serde(rename = "ECDH-1PU+A256KW")]
Ecdh1puA256kw,
#[serde(rename = "ECDH-ES+A256KW")]
EcdhEsA256kw,
#[serde(other)]
Other(String),
}
impl Algorithm {
pub(crate) fn as_str(&self) -> &str {
match self {
Algorithm::Ecdh1puA256kw => "ECDH-1PU+A256KW",
Algorithm::EcdhEsA256kw => "ECDH-ES+A256KW",
Algorithm::Other(ref s) => &s,
}
}
}
#[derive(Deserialize_enum_str, Serialize_enum_str, Debug, Clone, Eq, PartialEq)]
pub(crate) enum EncAlgorithm {
#[serde(rename = "A256CBC-HS512")]
A256cbcHs512,
#[serde(rename = "XC20P")]
Xc20P,
#[serde(rename = "A256GCM")]
A256Gcm,
#[serde(other)]
Other(String),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn algorithm_serialize_works() {
let alg = Algorithm::Ecdh1puA256kw;
let alg = serde_json::to_string(&alg).expect("unable serialize.");
assert_eq!(alg, "\"ECDH-1PU+A256KW\"");
let alg = Algorithm::Other("Unknown".into());
let alg = serde_json::to_string(&alg).expect("unable serialize.");
assert_eq!(alg, "\"Unknown\"");
}
#[test]
fn algorithm_deserialize_works() {
let alg: Algorithm =
serde_json::from_str("\"ECDH-1PU+A256KW\"").expect("unable deserialize.");
assert_eq!(alg, Algorithm::Ecdh1puA256kw);
let alg: Algorithm = serde_json::from_str("\"Unknown\"").expect("unable deserialize.");
assert_eq!(alg, Algorithm::Other("Unknown".into()));
let alg: Algorithm = serde_json::from_str("\"Unknown 2\"").expect("unable deserialize.");
assert_eq!(alg, Algorithm::Other("Unknown 2".into()));
}
#[test]
fn enc_algorithm_serialize_works() {
let enc_alg = EncAlgorithm::A256cbcHs512;
let enc_alg = serde_json::to_string(&enc_alg).expect("unable serialize.");
assert_eq!(enc_alg, "\"A256CBC-HS512\"");
let enc_alg = EncAlgorithm::Other("Unknown".into());
let enc_alg = serde_json::to_string(&enc_alg).expect("unable serialize.");
assert_eq!(enc_alg, "\"Unknown\"");
}
#[test]
fn enc_algorithm_deserialize_works() {
let enc_alg: EncAlgorithm =
serde_json::from_str("\"A256CBC-HS512\"").expect("unable deserialize.");
assert_eq!(enc_alg, EncAlgorithm::A256cbcHs512);
let enc_alg: EncAlgorithm =
serde_json::from_str("\"Unknown\"").expect("unable deserialize.");
assert_eq!(enc_alg, EncAlgorithm::Other("Unknown".into()));
let enc_alg: EncAlgorithm =
serde_json::from_str("\"Unknown 2\"").expect("unable deserialize.");
assert_eq!(enc_alg, EncAlgorithm::Other("Unknown 2".into()));
}
}