M src/addr.rs => src/addr.rs +26 -9
@@ 1,22 1,19 @@
use crate::prelude::*;
+use serde::{ser::Serializer, de::{self, Deserializer}};
-#[derive(PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
+#[derive(PartialEq, Eq, Clone, Hash)]
pub struct SufecAddr {
pub id: PublicKey,
pub at: String,
}
impl SufecAddr {
pub fn to_bytes(&self) -> Vec<u8> {
- let at = self.at.as_bytes();
- [self.id.0.as_ref(), &[at.len() as u8], at].concat()
+ [self.id.0.as_ref(), self.at.as_bytes()].concat()
}
- // The `usize` returned is how many bytes were consumed.
- pub fn from_bytes(bytes: &[u8]) -> Option<(Self, usize)> {
+ pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
let id = PublicKey::from_slice(bytes.get(0..PUBLICKEYBYTES)?)?;
- let at_len = *bytes.get(PUBLICKEYBYTES)? as usize;
- let at_bytes = bytes.get(PUBLICKEYBYTES+1..PUBLICKEYBYTES+1+at_len)?;
- let at = String::from_utf8(at_bytes.to_vec()).ok()?;
- Some((Self{id, at}, PUBLICKEYBYTES + 1 + at_len))
+ let at = String::from_utf8(bytes[PUBLICKEYBYTES..].to_vec()).ok()?;
+ Some(Self{id, at})
}
}
impl From<SufecAddr> for String {
@@ 48,3 45,23 @@ impl Debug for SufecAddr {
<Self as fmt::Display>::fmt(self, f)
}
}
+impl Serialize for SufecAddr {
+ fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
+ s.serialize_str(&self.to_string())
+ }
+}
+impl<'de> Deserialize<'de> for SufecAddr {
+ fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<SufecAddr, D::Error> {
+ deserializer.deserialize_str(AddrVisitor)
+ }
+}
+struct AddrVisitor;
+impl<'de> de::Visitor<'de> for AddrVisitor {
+ type Value = SufecAddr;
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a string")
+ }
+ fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
+ Self::Value::try_from(value).map_err(|_| E::custom("not a valid sufec address"))
+ }
+}
M src/crypto.rs => src/crypto.rs +13 -24
@@ 2,7 2,6 @@ use crate::prelude::*;
use crate::addr::*;
use crate::account::*;
use crate::message::*;
-use crate::error::*;
pub fn encrypt_message(
account: &Account,
@@ 14,7 13,14 @@ pub fn encrypt_message(
let shared_key = tripledh(&account.seckey, &eph_sec, recipient_id, recipient_eph);
let nonce = gen_nonce();
let ciphertext = seal_precomputed(&message.to_bytes(), &nonce, &shared_key);
- let concat = [&account.addr.to_bytes(), eph_pub.0.as_ref(), &nonce.0, &ciphertext].concat();
+ let addr_bytes = account.addr.to_bytes();
+ let concat = [
+ (addr_bytes.len() as u32).to_be_bytes().as_ref(),
+ &addr_bytes,
+ eph_pub.0.as_ref(),
+ &nonce.0,
+ &ciphertext,
+ ].concat();
sealedbox::seal(&concat, recipient_id)
}
@@ 25,7 31,11 @@ pub fn decrypt_message(
old_eph: &SecretKey,
) -> Option<(SufecAddr, Message)> {
let inner = sealedbox::open(outer, &account.addr.id, &account.seckey).ok()?;
- let (their_addr, mut offset) = SufecAddr::from_bytes(&inner)?;
+ let mut offset = 0;
+ let addr_len = u32::from_be_bytes(inner.get(..4)?.try_into().unwrap()) as usize;
+ offset += 4;
+ let their_addr = SufecAddr::from_bytes(inner.get(offset..offset+addr_len)?)?;
+ offset += addr_len;
let their_eph = inner.get(offset..offset+PUBLICKEYBYTES)?;
let their_eph = PublicKey::from_slice(their_eph).unwrap();
offset += PUBLICKEYBYTES;
@@ 62,24 72,3 @@ fn tripledh(
}
shared_key
}
-
-pub struct EncryptedStream {
- pub stream: TcpStream,
- pub key: PrecomputedKey,
- pub nonce: Nonce,
-}
-impl EncryptedStream {
- pub fn send<T: AsRef<[u8]>>(&mut self, data: T) -> io::Result<()> {
- let encrypted = seal_precomputed(data.as_ref(), &self.nonce, &self.key);
- self.nonce.increment_le_inplace();
- self.stream.write_all(&encrypted)
- }
- pub fn receive(&mut self, len: usize) -> Result<Vec<u8>, ServerError> {
- let mut ciphertext_buf = vec![0; len + MACBYTES];
- self.stream.read_exact(&mut ciphertext_buf)?;
- let decrypted = open_precomputed(&ciphertext_buf, &self.nonce, &self.key)
- .map_err(|_| ServerError::DecryptionFailed)?;
- self.nonce.increment_le_inplace();
- Ok(decrypted)
- }
-}
M src/message.rs => src/message.rs +7 -5
@@ 9,7 9,7 @@ pub struct Message {
pub content: MessageContent,
}
-#[derive(Serialize, Deserialize, Debug, Clone)]
+#[derive(Debug, Clone)]
pub enum MessageContent {
Text(String),
}
@@ 50,17 50,19 @@ impl Message {
bytes = &bytes[1..];
let mut other_recipients = Vec::new();
for _ in 0..num_other_recipients {
- let (recipient, len) = SufecAddr::from_bytes(bytes)?;
+ let len = u32::from_be_bytes(bytes.get(..4)?.try_into().unwrap()) as usize;
+ bytes = &bytes[4..];
+ let addr = SufecAddr::from_bytes(&bytes[..len])?;
bytes = &bytes[len..];
- other_recipients.push(recipient);
+ other_recipients.push(addr);
}
- let timestamp = u64::from_be_bytes(bytes[..8].try_into().unwrap());
+ let timestamp = u64::from_be_bytes(bytes.get(..8)?.try_into().unwrap());
bytes = &bytes[8..];
let mut hashes = vec![];
let num_hashes = *bytes.first()?;
bytes = &bytes[1..];
for _ in 0..num_hashes {
- let timestamp = u64::from_be_bytes(bytes[..8].try_into().unwrap());
+ let timestamp = u64::from_be_bytes(bytes.get(..8)?.try_into().unwrap());
bytes = &bytes[8..];
let hash = bytes[..DIGESTBYTES].try_into().unwrap();
hashes.push((timestamp, Digest(hash)));
M src/server.rs => src/server.rs +29 -12
@@ 46,9 46,12 @@ pub fn send(
return Err(ServerError::BadServer("invalid recipient keys"));
}
let keys_buf = stream.receive(keys_length)?;
- for key in keys_buf.chunks(PUBLICKEYBYTES).map(|k| PublicKey::from_slice(k).unwrap()) {
+ let keys = keys_buf.chunks(PUBLICKEYBYTES).map(|k| PublicKey::from_slice(k).unwrap());
+ for (i, key) in keys.enumerate() {
let copy = encrypt_message(account, &recipient, &key, &message);
- stream.send(&(copy.len() as u32).to_be_bytes())?;
+ if i == 0 {
+ stream.send(&(copy.len() as u32).to_be_bytes())?;
+ }
stream.send(©)?;
}
_ = stream.receive(1)?;
@@ 86,20 89,34 @@ pub struct ListeningConn {
stream: EncryptedStream,
}
impl ListeningConn {
- /// The 3 values returned are the timestamp the server received the message,
- /// the sender's address and the message.
+ /// Returns the sender's address and the message.
/// `Ok(None)` means you were sent an invalid message by a misbehaving client.
- pub fn receive(&mut self) -> Result<Option<(u64, SufecAddr, Message)>, ServerError> {
+ pub fn receive(&mut self) -> Result<Option<(SufecAddr, Message)>, ServerError> {
let length_buf = self.stream.receive(4)?.try_into().unwrap();
let length = u32::from_be_bytes(length_buf) as usize;
let msg_buf = self.stream.receive(length)?;
- // Avoid panicking on reading the timestamp.
- if msg_buf.len() < 8 {
- return Err(ServerError::BadServer("transmission has invalid length"));
- }
- let timestamp = u64::from_be_bytes(msg_buf[..8].try_into().unwrap());
self.stream.send(&[0])?;
- Ok(decrypt_message(&self.account, &msg_buf[8..], &self.new_eph_sec, &self.old_eph_sec)
- .map(|(from, msg)| (timestamp, from, msg)))
+ Ok(decrypt_message(&self.account, &msg_buf, &self.new_eph_sec, &self.old_eph_sec))
+ }
+}
+
+pub struct EncryptedStream {
+ pub stream: TcpStream,
+ pub key: PrecomputedKey,
+ pub nonce: Nonce,
+}
+impl EncryptedStream {
+ pub fn send<T: AsRef<[u8]>>(&mut self, data: T) -> io::Result<()> {
+ let encrypted = seal_precomputed(data.as_ref(), &self.nonce, &self.key);
+ self.nonce.increment_le_inplace();
+ self.stream.write_all(&encrypted)
+ }
+ pub fn receive(&mut self, len: usize) -> Result<Vec<u8>, ServerError> {
+ let mut ciphertext_buf = vec![0; len + MACBYTES];
+ self.stream.read_exact(&mut ciphertext_buf)?;
+ let decrypted = open_precomputed(&ciphertext_buf, &self.nonce, &self.key)
+ .map_err(|_| ServerError::DecryptionFailed)?;
+ self.nonce.increment_le_inplace();
+ Ok(decrypted)
}
}