use cbor2::Cbor;
#[derive(Clone, Debug, PartialEq, Cbor)]
struct Protected {
#[cbor(key = 1)]
alg: i8,
}
#[derive(Clone, Debug, PartialEq, Cbor)]
struct Unprotected {
#[cbor(key = 5)]
#[serde(with = "serde_bytes")]
iv: Vec<u8>,
}
#[derive(Clone, Debug, PartialEq, Cbor)]
#[cbor(tag = 16, array)]
struct Encrypt0 {
#[serde(with = "serde_bytes")]
protected: Vec<u8>,
unprotected: Unprotected,
#[serde(with = "serde_bytes")]
ciphertext: Option<Vec<u8>>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let protected = cbor2::to_canonical_vec(&Protected { alg: 10 })?;
assert_eq!(hex::encode(&protected), "a1010a");
let msg = Encrypt0 {
protected,
unprotected: Unprotected {
iv: hex::decode("89f52f65a1c580933b5261a78c")?,
},
ciphertext: Some(hex::decode(
"5974e1b99a3a4cc09a659aa2e9e7fff161d38ce71cb45ce460ffb569",
)?),
};
let bytes = cbor2::to_canonical_vec(&msg)?;
assert_eq!(bytes.len(), 52);
assert_eq!(
hex::encode(&bytes),
"d08343a1010aa1054d89f52f65a1c580933b5261a78c581c\
5974e1b99a3a4cc09a659aa2e9e7fff161d38ce71cb45ce460ffb569"
);
println!("{}", cbor2::diagnostic(&bytes[..])?);
let back: Encrypt0 = cbor2::from_slice(&bytes)?;
assert_eq!(back, msg);
let header: Protected = cbor2::from_slice(&back.protected)?;
assert_eq!(header, Protected { alg: 10 });
assert_eq!(Protected::KEYS, &[("alg", 1)]);
assert_eq!(Encrypt0::TAG, Some(16));
const { assert!(Encrypt0::ARRAY) };
let untagged = &bytes[1..]; let from_untagged: Encrypt0 = cbor2::from_slice(untagged)?;
assert_eq!(from_untagged, msg);
let detached = Encrypt0 {
ciphertext: None,
..msg.clone()
};
let detached_bytes = cbor2::to_canonical_vec(&detached)?;
assert_eq!(*detached_bytes.last().unwrap(), 0xf6); println!("{}", cbor2::diagnostic(&detached_bytes[..])?);
let json = serde_json::to_string(&header)?;
assert_eq!(json, r#"{"alg":10}"#);
println!("{}", json);
Ok(())
}