use std::{any::Any, str};
use bytes::BytesMut;
use crate::{
ConnectError, PathId, Side, TransportError, shared::ConnectionId,
transport_parameters::TransportParameters,
};
#[cfg(any(feature = "aws-lc-rs", feature = "ring"))]
pub(crate) mod ring_like;
#[cfg(feature = "rustls")]
pub mod rustls;
pub trait Session: Send + Sync + 'static {
fn initial_keys(&self, dst_cid: ConnectionId, side: Side) -> Keys;
fn handshake_data(&self) -> Option<Box<dyn Any>>;
fn peer_identity(&self) -> Option<Box<dyn Any>>;
fn early_crypto(&self) -> Option<(Box<dyn HeaderKey>, Box<dyn PacketKey>)>;
fn early_data_accepted(&self) -> Option<bool>;
fn is_handshaking(&self) -> bool;
fn read_handshake(&mut self, buf: &[u8]) -> Result<bool, TransportError>;
fn transport_parameters(&self) -> Result<Option<TransportParameters>, TransportError>;
fn write_handshake(&mut self, buf: &mut Vec<u8>) -> Option<Keys>;
fn next_1rtt_keys(&mut self) -> Option<KeyPair<Box<dyn PacketKey>>>;
fn is_valid_retry(&self, orig_dst_cid: ConnectionId, header: &[u8], payload: &[u8]) -> bool;
fn export_keying_material(
&self,
output: &mut [u8],
label: &[u8],
context: &[u8],
) -> Result<(), ExportKeyingMaterialError>;
}
pub struct KeyPair<T> {
pub local: T,
pub remote: T,
}
pub struct Keys {
pub header: KeyPair<Box<dyn HeaderKey>>,
pub packet: KeyPair<Box<dyn PacketKey>>,
}
impl Keys {
pub(crate) fn local(&self) -> (&dyn HeaderKey, &dyn PacketKey) {
(self.header.local.as_ref(), self.packet.local.as_ref())
}
pub(crate) fn remote(&self) -> (&dyn HeaderKey, &dyn PacketKey) {
(self.header.remote.as_ref(), self.packet.remote.as_ref())
}
}
pub trait ClientConfig: Send + Sync {
fn start_session(
&self,
version: u32,
server_name: &str,
params: &TransportParameters,
) -> Result<Box<dyn Session>, ConnectError>;
}
pub trait ServerConfig: Send + Sync {
fn initial_keys(&self, version: u32, dst_cid: ConnectionId)
-> Result<Keys, UnsupportedVersion>;
fn retry_tag(&self, version: u32, orig_dst_cid: ConnectionId, packet: &[u8]) -> [u8; 16];
fn start_session(&self, version: u32, params: &TransportParameters) -> Box<dyn Session>;
}
pub trait PacketKey: Send + Sync {
fn encrypt(&self, path_id: PathId, packet: u64, buf: &mut [u8], header_len: usize);
fn decrypt(
&self,
path_id: PathId,
packet: u64,
header: &[u8],
payload: &mut BytesMut,
) -> Result<(), CryptoError>;
fn tag_len(&self) -> usize;
fn confidentiality_limit(&self) -> u64;
fn integrity_limit(&self) -> u64;
}
pub trait HeaderKey: Send + Sync {
fn decrypt(&self, pn_offset: usize, packet: &mut [u8]);
fn encrypt(&self, pn_offset: usize, packet: &mut [u8]);
fn sample_size(&self) -> usize;
}
pub trait HmacKey: Send + Sync {
fn sign(&self, data: &[u8], signature_out: &mut [u8]);
fn signature_len(&self) -> usize;
fn verify(&self, data: &[u8], signature: &[u8]) -> Result<(), CryptoError>;
}
#[derive(Debug, PartialEq, Eq)]
pub struct ExportKeyingMaterialError;
pub trait HandshakeTokenKey: Send + Sync {
fn seal(&self, token_nonce: u128, data: &mut Vec<u8>) -> Result<(), CryptoError>;
fn open<'a>(&self, token_nonce: u128, data: &'a mut [u8]) -> Result<&'a [u8], CryptoError>;
}
#[derive(Debug)]
pub struct CryptoError;
#[derive(Debug)]
pub struct UnsupportedVersion;
impl From<UnsupportedVersion> for ConnectError {
fn from(_: UnsupportedVersion) -> Self {
Self::UnsupportedVersion
}
}