use crate::*;
#[derive(Clone, Debug, Copy)]
pub struct Nonce(pub [u8; 24]);
impl serde::Serialize for Nonce {
fn serialize<S>(
&self,
serializer: S,
) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let s = base64::encode_config(self.0, base64::URL_SAFE_NO_PAD);
serializer.serialize_str(&s)
}
}
impl<'de> serde::Deserialize<'de> for Nonce {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
let v = base64::decode_config(s, base64::URL_SAFE_NO_PAD)
.map_err(serde::de::Error::custom)?;
if v.len() != 24 {
return Err(serde::de::Error::custom(Error::id("InvalidLen")));
}
let mut out = [0; 24];
out.copy_from_slice(&v);
Ok(Self(out))
}
}
impl From<[u8; 24]> for Nonce {
fn from(f: [u8; 24]) -> Self {
Self(f)
}
}
#[derive(Clone, Debug)]
pub struct Cipher(pub Box<[u8]>);
impl serde::Serialize for Cipher {
fn serialize<S>(
&self,
serializer: S,
) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let s = base64::encode_config(&self.0, base64::URL_SAFE_NO_PAD);
serializer.serialize_str(&s)
}
}
impl<'de> serde::Deserialize<'de> for Cipher {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(Self(
base64::decode_config(s, base64::URL_SAFE_NO_PAD)
.map_err(serde::de::Error::custom)?
.into_boxed_slice(),
))
}
}
impl From<Box<[u8]>> for Cipher {
fn from(f: Box<[u8]>) -> Self {
Self(f)
}
}
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum Wire {
#[serde(rename_all = "camelCase")]
AuthReqV1 {
srv_pub: Id,
nonce: Nonce,
cipher: Cipher,
ice: serde_json::Value,
},
#[serde(rename_all = "camelCase")]
AuthResV1 {
con_key: Id,
req_addr: bool,
},
#[serde(rename_all = "camelCase")]
FwdV1 {
rem_pub: Id,
nonce: Nonce,
cipher: Cipher,
},
#[serde(rename_all = "camelCase")]
DemoV1 {
rem_pub: Id,
},
}
impl Wire {
pub fn decode(wire: &[u8]) -> Result<Self> {
serde_json::from_slice(wire).map_err(Error::err)
}
pub fn encode(&self) -> Result<Vec<u8>> {
serde_json::to_string(&self)
.map_err(Error::err)
.map(|s| s.into_bytes())
}
}
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum FwdInnerV1 {
#[serde(rename_all = "camelCase")]
Offer {
seq: f64,
offer: serde_json::Value,
},
#[serde(rename_all = "camelCase")]
Answer {
seq: f64,
answer: serde_json::Value,
},
#[serde(rename_all = "camelCase")]
Ice {
seq: f64,
ice: serde_json::Value,
},
}
impl FwdInnerV1 {
pub fn decode(wire: &[u8]) -> Result<Self> {
serde_json::from_slice(wire).map_err(Error::err)
}
pub fn encode(&self) -> Result<Vec<u8>> {
serde_json::to_string(&self)
.map_err(Error::err)
.map(|s| s.into_bytes())
}
pub fn set_seq(&mut self, new_seq: f64) {
match self {
FwdInnerV1::Offer { seq, .. } => *seq = new_seq,
FwdInnerV1::Answer { seq, .. } => *seq = new_seq,
FwdInnerV1::Ice { seq, .. } => *seq = new_seq,
}
}
pub fn get_seq(&self) -> f64 {
match self {
FwdInnerV1::Offer { seq, .. } => *seq,
FwdInnerV1::Answer { seq, .. } => *seq,
FwdInnerV1::Ice { seq, .. } => *seq,
}
}
}