use super::Protocol;
use super::cipher::Cipher;
use super::cipher_state::CipherState;
use super::error::HandshakeError;
use super::session_id::SessionId;
use crate::curve::Curve;
pub struct Transport<Proto: Protocol> {
send: CipherState<Proto::Cipher>,
recv: CipherState<Proto::Cipher>,
session_id: SessionId,
local_ephemeral: Option<<Proto::Curve as Curve>::PublicKey>,
remote_ephemeral: Option<<Proto::Curve as Curve>::PublicKey>,
}
impl<Proto: Protocol> Transport<Proto> {
pub(crate) fn new(
send: CipherState<Proto::Cipher>,
recv: CipherState<Proto::Cipher>,
session_id: SessionId,
local_ephemeral: Option<<Proto::Curve as Curve>::PublicKey>,
remote_ephemeral: Option<<Proto::Curve as Curve>::PublicKey>,
) -> Self {
Self {
send,
recv,
session_id,
local_ephemeral,
remote_ephemeral,
}
}
pub const OVERHEAD: usize = <Proto::Cipher as Cipher>::TAG_SIZE;
pub fn send(&mut self, plaintext: &[u8], output: &mut [u8]) -> Result<usize, HandshakeError> {
self.send.encrypt_with_ad(&[], plaintext, output)
}
pub fn receive(
&mut self,
ciphertext: &[u8],
output: &mut [u8],
) -> Result<usize, HandshakeError> {
self.recv.decrypt_with_ad(&[], ciphertext, output)
}
pub fn rekey(&mut self) -> Result<(), HandshakeError> {
self.send.rekey()?;
self.recv.rekey()?;
Ok(())
}
pub fn session_id(&self) -> &SessionId {
&self.session_id
}
pub fn local_ephemeral(&self) -> Option<&<Proto::Curve as Curve>::PublicKey> {
self.local_ephemeral.as_ref()
}
pub fn remote_ephemeral(&self) -> Option<&<Proto::Curve as Curve>::PublicKey> {
self.remote_ephemeral.as_ref()
}
pub fn split(self) -> (TransportSend<Proto>, TransportRecv<Proto>) {
let send = TransportSend {
cipher: self.send,
session_id: self.session_id.clone(),
local_ephemeral: self.local_ephemeral.clone(),
remote_ephemeral: self.remote_ephemeral.clone(),
};
let recv = TransportRecv {
cipher: self.recv,
session_id: self.session_id,
local_ephemeral: self.local_ephemeral,
remote_ephemeral: self.remote_ephemeral,
};
(send, recv)
}
}
pub struct TransportSend<Proto: Protocol> {
cipher: CipherState<Proto::Cipher>,
session_id: SessionId,
local_ephemeral: Option<<Proto::Curve as Curve>::PublicKey>,
remote_ephemeral: Option<<Proto::Curve as Curve>::PublicKey>,
}
impl<Proto: Protocol> TransportSend<Proto> {
pub const OVERHEAD: usize = <Proto::Cipher as Cipher>::TAG_SIZE;
pub fn encrypt(
&mut self,
plaintext: &[u8],
output: &mut [u8],
) -> Result<usize, HandshakeError> {
self.cipher.encrypt_with_ad(&[], plaintext, output)
}
pub fn rekey(&mut self) -> Result<(), HandshakeError> {
self.cipher.rekey()
}
pub fn session_id(&self) -> &SessionId {
&self.session_id
}
pub fn local_ephemeral(&self) -> Option<&<Proto::Curve as Curve>::PublicKey> {
self.local_ephemeral.as_ref()
}
pub fn remote_ephemeral(&self) -> Option<&<Proto::Curve as Curve>::PublicKey> {
self.remote_ephemeral.as_ref()
}
}
pub struct TransportRecv<Proto: Protocol> {
cipher: CipherState<Proto::Cipher>,
session_id: SessionId,
local_ephemeral: Option<<Proto::Curve as Curve>::PublicKey>,
remote_ephemeral: Option<<Proto::Curve as Curve>::PublicKey>,
}
impl<Proto: Protocol> TransportRecv<Proto> {
pub const OVERHEAD: usize = <Proto::Cipher as Cipher>::TAG_SIZE;
pub fn decrypt(
&mut self,
ciphertext: &[u8],
output: &mut [u8],
) -> Result<usize, HandshakeError> {
self.cipher.decrypt_with_ad(&[], ciphertext, output)
}
pub fn rekey(&mut self) -> Result<(), HandshakeError> {
self.cipher.rekey()
}
pub fn session_id(&self) -> &SessionId {
&self.session_id
}
pub fn local_ephemeral(&self) -> Option<&<Proto::Curve as Curve>::PublicKey> {
self.local_ephemeral.as_ref()
}
pub fn remote_ephemeral(&self) -> Option<&<Proto::Curve as Curve>::PublicKey> {
self.remote_ephemeral.as_ref()
}
}