Browse Source

Hashing of everything

master
Lev 3 years ago
parent
commit
eede8b9c23
  1. 17
      src/crypto.rs
  2. 67
      src/message.rs
  3. 34
      src/tunnel.rs

17
src/crypto.rs

@ -27,7 +27,17 @@ impl PublicKey {
} }
pub fn to_vec(&self) -> serde_cbor::Result<Vec<u8>> { pub fn to_vec(&self) -> serde_cbor::Result<Vec<u8>> {
serde_cbor::to_vec(&self) serde_cbor::to_vec(&self.key)
}
pub fn from_vec(data: Vec<u8>) -> serde_cbor::Result<Self> {
serde_cbor::from_slice(data.as_slice())
}
}
impl PublicKey {
fn hash(&self) -> Vec<u8> {
self.to_vec().unwrap()
} }
} }
@ -103,3 +113,8 @@ fn test_invalid_signing() {
let keys_2 = Keys::generate(); let keys_2 = Keys::generate();
assert!(!keys_2.get_public().verify_sign(&data, &keys_1.sign(&data).unwrap())); assert!(!keys_2.get_public().verify_sign(&data, &keys_1.sign(&data).unwrap()));
} }
#[test]
fn test_pkey_caching() {
assert_ne!(Keys::generate().get_public().hash(), Keys::generate().get_public().hash())
}

67
src/message.rs

@ -4,6 +4,7 @@ use crate::crypto::{Keys, PublicKey};
use crate::res::IFResult; use crate::res::IFResult;
use crate::tunnel::TunnelPublic; use crate::tunnel::TunnelPublic;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use sha2::Digest;
/// A serialized message /// A serialized message
@ -28,7 +29,7 @@ pub enum Signature {
/// Network name and version /// Network name and version
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
struct NetworkInfo { pub struct NetworkInfo {
network_name: String, network_name: String,
version: String, version: String,
} }
@ -46,6 +47,16 @@ pub enum MessageType {
Service(ServiceMessageType), Service(ServiceMessageType),
} }
impl MessageType {
fn hash(&self) -> Vec<u8> {
match self {
MessageType::SingleCast => Vec::from([0]),
MessageType::Broadcast => Vec::from([1]),
MessageType::Service(ServiceMessageType::TunnelBuilding(tunnel)) => [2, 0].iter().chain(tunnel.hash().iter()).copied().collect()
}
}
}
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub enum ServiceMessageType { pub enum ServiceMessageType {
TunnelBuilding(TunnelPublic) TunnelBuilding(TunnelPublic)
@ -61,6 +72,22 @@ pub enum MessageContent {
None, None,
} }
impl MessageContent {
pub fn hash(&self) -> Vec<u8> {
match self {
MessageContent::Plain(v) => sha2::Sha512::new()
.chain(&[0u8; 1])
.chain(v.as_slice())
.result().to_vec(),
MessageContent::Encrypted(v) => sha2::Sha512::new()
.chain(&[1; 1])
.chain(v.as_slice())
.result().to_vec(),
MessageContent::None => Vec::new()
}
}
}
/// The struct for messages that are sent in the network /// The struct for messages that are sent in the network
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub struct Message { pub struct Message {
@ -100,8 +127,14 @@ impl Message {
todo!() todo!()
} }
pub fn calculate_hash(_content: &MessageContent, _message_type: MessageType, _sender_or_encrypted_sender: Option<Vec<u8>>) -> Vec<u8> { pub fn calculate_hash(content: &MessageContent, message_type: MessageType, sender_or_encrypted_sender: Option<Vec<u8>>, network_info: &NetworkInfo) -> Vec<u8> {
todo!() sha2::Sha512::new()
.chain(content.hash().as_slice())
.chain(message_type.hash().as_slice())
.chain(sender_or_encrypted_sender.unwrap_or_default().as_slice())
.chain(network_info.network_name.as_bytes())
.chain(network_info.version.as_bytes())
.result().to_vec()
} }
/// Encrypt hash of the message for the recipient /// Encrypt hash of the message for the recipient
@ -171,6 +204,7 @@ impl MessageBuilder {
let sender_encrypted = if let (Some(sender_keys), Some(recipient)) = (self.sender.as_ref(), self.recipient.as_ref()) { let sender_encrypted = if let (Some(sender_keys), Some(recipient)) = (self.sender.as_ref(), self.recipient.as_ref()) {
Some(recipient.encrypt_data(&sender_keys.get_public().to_vec()?)?) Some(recipient.encrypt_data(&sender_keys.get_public().to_vec()?)?)
} else { None }; } else { None };
let network_info = NetworkInfo::default();
let hash = Message::calculate_hash( let hash = Message::calculate_hash(
&self.content, &self.content,
self.message_type.clone().unwrap(), self.message_type.clone().unwrap(),
@ -179,6 +213,7 @@ impl MessageBuilder {
|| self.sender.as_ref() || self.sender.as_ref()
.map(|sender_keys| sender_keys.get_public().to_vec().unwrap()) .map(|sender_keys| sender_keys.get_public().to_vec().unwrap())
), ),
&network_info
); );
let recipient_verification = self.recipient.as_ref().map(|rec| rec.encrypt_data(&hash).unwrap()); let recipient_verification = self.recipient.as_ref().map(|rec| rec.encrypt_data(&hash).unwrap());
let signature = match (self.sender, self.recipient) { let signature = match (self.sender, self.recipient) {
@ -197,7 +232,31 @@ impl MessageBuilder {
hash, hash,
recipient_verification, recipient_verification,
tunnel_id: self.tunnel_id, tunnel_id: self.tunnel_id,
network_info: Default::default(), network_info,
}) })
} }
} }
#[cfg(test)]
use alloc::vec;
#[test]
fn test_hashing_message_type() {
let msg_type_1 = MessageType::Broadcast;
let msg_type_2 = MessageType::Service(ServiceMessageType::TunnelBuilding(TunnelPublic::new_for_test()));
assert_eq!(msg_type_1.hash(), msg_type_1.hash());
assert_eq!(msg_type_2.hash(), msg_type_2.hash());
assert_ne!(msg_type_1.hash(), msg_type_2.hash())
}
#[test]
fn test_hash_message_content() {
let content_1 = MessageContent::Plain(vec![1, 2, 4, 5]);
let content_2 = MessageContent::Encrypted(vec![1, 2, 4, 5]);
let content_3 = MessageContent::Plain(vec![1, 3, 4, 5]);
assert_eq!(content_1.hash(), content_1.hash());
assert_ne!(content_1.hash(), MessageContent::None.hash());
assert_ne!(content_1.hash(), content_2.hash());
assert_ne!(content_1.hash(), content_3.hash());
assert_ne!(content_3.hash(), content_2.hash());
}

34
src/tunnel.rs

@ -1,6 +1,7 @@
use alloc::vec::Vec; use alloc::vec::Vec;
use crate::crypto::PublicKey; use crate::crypto::PublicKey;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use sha2::Digest;
/// A tunnel that is used for communication /// A tunnel that is used for communication
#[derive(Serialize, Clone, Deserialize)] #[derive(Serialize, Clone, Deserialize)]
@ -34,3 +35,36 @@ pub struct TunnelPublic {
/// Public keys of nodes in the tunnel /// Public keys of nodes in the tunnel
nodes_in_tunnel: Option<Vec<PublicKey>>, nodes_in_tunnel: Option<Vec<PublicKey>>,
} }
impl TunnelPublic {
pub fn hash(&self) -> Vec<u8> {
sha2::Sha224::new()
.chain(serde_cbor::to_vec(self).unwrap().as_slice())
.result().to_vec()
}
#[cfg(test)]
pub fn new_for_test() -> Self {
TunnelPublic {
id: Some(56),
local_ids: vec![5, 500, 120],
ttd: 56,
nodes_in_tunnel: Some(vec![crate::crypto::Keys::generate().get_public()])
}
}
}
#[cfg(test)]
use alloc::vec;
#[test]
fn test_tunnel_hashing() {
let tun = TunnelPublic::new_for_test();
assert_eq!(tun.hash(), tun.hash());
assert_ne!(tun.hash(), TunnelPublic {
id: Some(56),
local_ids: vec![5, 500, 120],
ttd: 56,
nodes_in_tunnel: Some(vec![crate::crypto::Keys::generate().get_public()])
}.hash());
}

Loading…
Cancel
Save