use rand::CryptoRng;
use super::{
builders::BuilderError as Error,
initiator::registration::RegistrationInitiator,
responder::Responder,
};
use crate::handshake::{
ciphersuite::{initiator::InitiatorCiphersuite, responder::ResponderCiphersuite},
dhkem::DHPublicKey,
initiator::query::QueryInitiator,
};
const RECENT_KEYS_DEFAULT_BOUND: usize = 100;
pub struct PrincipalBuilder<'a, Rng: CryptoRng> {
rng: Rng,
context: &'a [u8],
inner_aad: &'a [u8],
outer_aad: &'a [u8],
responder_recent_keys_upper_bound: usize,
}
impl<'a, Rng: CryptoRng> PrincipalBuilder<'a, Rng> {
pub fn new(rng: Rng) -> Self {
Self {
rng,
context: &[],
inner_aad: &[],
outer_aad: &[],
responder_recent_keys_upper_bound: RECENT_KEYS_DEFAULT_BOUND,
}
}
pub fn context(mut self, context: &'a [u8]) -> Self {
self.context = context;
self
}
pub fn inner_aad(mut self, inner_aad: &'a [u8]) -> Self {
self.inner_aad = inner_aad;
self
}
pub fn outer_aad(mut self, outer_aad: &'a [u8]) -> Self {
self.outer_aad = outer_aad;
self
}
pub fn recent_keys_upper_bound(mut self, recent_keys_upper_bound: usize) -> Self {
self.responder_recent_keys_upper_bound = recent_keys_upper_bound;
self
}
pub fn build_query_initiator(
self,
peer_longterm_ecdh_pk: &'a DHPublicKey,
) -> Result<QueryInitiator<'a>, Error> {
QueryInitiator::new(
peer_longterm_ecdh_pk,
self.context,
self.outer_aad,
self.rng,
)
.map_err(|_| Error::PrincipalBuilderState)
}
pub fn build_registration_initiator(
self,
ciphersuite: InitiatorCiphersuite<'a>,
) -> Result<RegistrationInitiator<'a, Rng>, Error> {
RegistrationInitiator::new(
ciphersuite,
self.context,
self.inner_aad,
self.outer_aad,
self.rng,
)
.map_err(|_| Error::PrincipalBuilderState)
}
pub fn build_responder(
self,
ciphersuite: ResponderCiphersuite<'a>,
) -> Result<Responder<'a, Rng>, Error> {
Ok(Responder::new(
ciphersuite,
self.context,
self.outer_aad,
self.responder_recent_keys_upper_bound,
self.rng,
))
}
}