Skip to content

Commit

Permalink
Implemented deserialization of TorSecretKeyV3 and TorPublicKeyV3 with…
Browse files Browse the repository at this point in the history
… non-borrowable data source
  • Loading branch information
teawithsand committed Oct 31, 2021
1 parent aa1ad36 commit 27f6421
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 28 deletions.
5 changes: 4 additions & 1 deletion src/onion/v3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ mod key;
mod onion;

#[cfg(feature = "serialize")]
mod serde;
mod serde_key;

#[cfg(feature = "serialize")]
mod serde_onion;
21 changes: 0 additions & 21 deletions src/onion/v3/onion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use std::fmt::{Display, Formatter};
use std::fmt;
use std::str::FromStr;

#[cfg(feature = "serialize")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use sha3::Digest;

use crate::onion::v3::TorPublicKeyV3;
Expand Down Expand Up @@ -175,25 +173,6 @@ impl FromStr for OnionAddressV3 {
}
}

#[cfg(feature = "serialize")]
impl Serialize for OnionAddressV3 {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where
S: Serializer {
let res = self.get_address_without_dot_onion();
serializer.serialize_str(&res)
}
}

#[cfg(feature = "serialize")]
impl<'de> Deserialize<'de> for OnionAddressV3 {
//noinspection SpellCheckingInspection
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error> where
D: Deserializer<'de> {
let raw_onion_addr = <&str>::deserialize(deserializer)?;
Ok(Self::from_str(raw_onion_addr).map_err(de::Error::custom)?)
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
36 changes: 30 additions & 6 deletions src/onion/v3/serde.rs → src/onion/v3/serde_key.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::borrow::Cow;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

use crate::onion::v3::{TorPublicKeyV3, TorSecretKeyV3};
Expand All @@ -19,8 +20,8 @@ impl Serialize for TorPublicKeyV3 {
impl<'de> Deserialize<'de> for TorSecretKeyV3 {
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error> where
D: Deserializer<'de> {
let text = <&str>::deserialize(deserializer)?;
let raw = base64::decode(text).map_err(serde::de::Error::custom)?;
let text = <Cow<'_, str>>::deserialize(deserializer)?;
let raw = base64::decode(&text[..]).map_err(serde::de::Error::custom)?;
if raw.len() != 64 {
return Err(serde::de::Error::custom("Invalid secret key length"));
}
Expand All @@ -33,8 +34,8 @@ impl<'de> Deserialize<'de> for TorSecretKeyV3 {
impl<'de> Deserialize<'de> for TorPublicKeyV3 {
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error> where
D: Deserializer<'de> {
let text = <&str>::deserialize(deserializer)?;
let raw = base64::decode(text).map_err(serde::de::Error::custom)?;
let text = <Cow<'_, str>>::deserialize(deserializer)?;
let raw = base64::decode(&text[..]).map_err(serde::de::Error::custom)?;
if raw.len() != 32 {
return Err(serde::de::Error::custom("Invalid secret key length"));
}
Expand All @@ -48,6 +49,7 @@ impl<'de> Deserialize<'de> for TorPublicKeyV3 {

#[cfg(test)]
mod test {
use std::io::Cursor;
use super::*;

#[test]
Expand All @@ -61,10 +63,32 @@ mod test {

#[test]
fn test_can_serialize_and_deserialize_public_key() {
let sk = TorSecretKeyV3::generate().public();
let pk = TorSecretKeyV3::generate().public();
let data = serde_json::to_vec(&pk).unwrap();
let rpk: TorPublicKeyV3 = serde_json::from_slice(&data).unwrap();

assert_eq!(pk, rpk);
}

#[test]
fn test_can_serialize_and_deserialize_secret_key_with_no_borrowing() {
let sk = TorSecretKeyV3::generate();
let data = serde_json::to_vec(&sk).unwrap();
let rsk: TorPublicKeyV3 = serde_json::from_slice(&data).unwrap();

let mut c = Cursor::new(&data);
let rsk: TorSecretKeyV3 = serde_json::from_reader(&mut c).unwrap();

assert_eq!(sk, rsk);
}

#[test]
fn test_can_serialize_and_deserialize_public_key_with_no_borrowing() {
let pk = TorSecretKeyV3::generate().public();
let data = serde_json::to_vec(&pk).unwrap();

let mut c = Cursor::new(&data);
let rpk: TorPublicKeyV3 = serde_json::from_reader(&mut c).unwrap();

assert_eq!(pk, rpk);
}
}
24 changes: 24 additions & 0 deletions src/onion/v3/serde_onion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use std::str::FromStr;

use serde::{de, Deserialize, Deserializer, Serialize, Serializer};

use crate::onion::OnionAddressV3;

impl Serialize for OnionAddressV3 {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where
S: Serializer {
let res = self.get_address_without_dot_onion();
serializer.serialize_str(&res)
}
}

impl<'de> Deserialize<'de> for OnionAddressV3 {
//noinspection SpellCheckingInspection
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error> where
D: Deserializer<'de> {
let raw_onion_addr = <&str>::deserialize(deserializer)?;
Ok(Self::from_str(raw_onion_addr).map_err(de::Error::custom)?)
}
}

// TODO(teawithsand): testing for these

0 comments on commit 27f6421

Please sign in to comment.