#[cfg(feature = "exonum_sodiumoxide")]
pub use self::wrappers::sodium_wrapper::{
handshake::{HandshakeParams, NoiseHandshake},
wrapper::{
NoiseWrapper, TransportWrapper, HANDSHAKE_HEADER_LENGTH, MAX_HANDSHAKE_MESSAGE_LENGTH,
MIN_HANDSHAKE_MESSAGE_LENGTH,
},
};
use async_trait::async_trait;
use byteorder::{ByteOrder, LittleEndian};
use exonum::crypto::x25519;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
use crate::events::codec::MessagesCodec;
pub mod error;
pub mod wrappers;
#[cfg(test)]
mod tests;
pub const MAX_MESSAGE_LENGTH: usize = 65_535;
pub const TAG_LENGTH: usize = 16;
pub const HEADER_LENGTH: usize = 4;
#[derive(Debug)]
pub struct HandshakeData {
pub codec: MessagesCodec,
pub raw_message: Vec<u8>,
pub peer_key: x25519::PublicKey,
}
#[async_trait]
pub trait Handshake<S> {
async fn listen(self, stream: &mut S) -> anyhow::Result<HandshakeData>;
async fn send(self, stream: &mut S) -> anyhow::Result<HandshakeData>;
}
pub struct HandshakeRawMessage(pub Vec<u8>);
impl HandshakeRawMessage {
pub async fn read<S>(sock: &mut S) -> anyhow::Result<Self>
where
S: AsyncRead + Unpin,
{
let mut len_buf = [0_u8; HANDSHAKE_HEADER_LENGTH];
sock.read_exact(&mut len_buf).await?;
let len = LittleEndian::read_uint(&len_buf, HANDSHAKE_HEADER_LENGTH);
let mut message = vec![0_u8; len as usize];
sock.read_exact(&mut message).await?;
Ok(Self(message))
}
pub async fn write<S>(&self, sock: &mut S) -> anyhow::Result<()>
where
S: AsyncWrite + Unpin,
{
let len = self.0.len();
debug_assert!(len < MAX_HANDSHAKE_MESSAGE_LENGTH);
let mut len_buf = [0_u8; HANDSHAKE_HEADER_LENGTH];
LittleEndian::write_uint(&mut len_buf, len as u64, HANDSHAKE_HEADER_LENGTH);
sock.write_all(&len_buf).await?;
sock.write_all(&self.0).await.map_err(From::from)
}
}