use crate::utils::*;
use botan_sys::*;
use crate::{EcGroup, RandomNumberGenerator};
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum Spake2pCiphersuite {
P256Sha256,
P256Sha512,
P384Sha256,
P384Sha512,
P521Sha512,
}
impl Spake2pCiphersuite {
fn name(self) -> &'static str {
match self {
Self::P256Sha256 => "P256-SHA256",
Self::P256Sha512 => "P256-SHA512",
Self::P384Sha256 => "P384-SHA256",
Self::P384Sha512 => "P384-SHA512",
Self::P521Sha512 => "P521-SHA512",
}
}
}
#[derive(Debug)]
pub struct Spake2pParams {
obj: botan_spake2p_params_t,
}
unsafe impl Sync for Spake2pParams {}
unsafe impl Send for Spake2pParams {}
botan_impl_drop!(Spake2pParams, botan_spake2p_params_destroy);
impl Spake2pParams {
pub fn new(ciphersuite: Spake2pCiphersuite) -> Result<Self> {
let ciphersuite = make_cstr(ciphersuite.name())?;
let obj = botan_init!(botan_spake2p_params_init, ciphersuite.as_ptr())?;
Ok(Self { obj })
}
pub fn new_custom(group: &EcGroup, seed: &[u8], hash_fn: &str) -> Result<Self> {
let hash_fn = make_cstr(hash_fn)?;
let obj = botan_init!(
botan_spake2p_params_init_custom,
group.handle(),
seed.as_ptr(),
seed.len(),
hash_fn.as_ptr()
)?;
Ok(Self { obj })
}
pub fn share_size(&self) -> Result<usize> {
botan_usize!(botan_spake2p_params_share_size, self.obj)
}
pub fn confirmation_size(&self) -> Result<usize> {
botan_usize!(botan_spake2p_params_confirmation_size, self.obj)
}
pub fn derive_secret(
&self,
password: &str,
prover_id: &[u8],
verifier_id: &[u8],
salt: &[u8],
) -> Result<Vec<u8>> {
let password = make_cstr(password)?;
botan_view_vec!(
botan_spake2p_derive_secret,
self.obj,
password.as_ptr(),
prover_id.as_ptr(),
prover_id.len(),
verifier_id.as_ptr(),
verifier_id.len(),
salt.as_ptr(),
salt.len()
)
}
pub fn registration_record(
&self,
rng: &mut RandomNumberGenerator,
secret: &[u8],
) -> Result<Vec<u8>> {
let rng = rng.handle();
botan_view_vec!(
botan_spake2p_registration_record,
self.obj,
rng,
secret.as_ptr(),
secret.len()
)
}
}
#[derive(Debug)]
pub struct Spake2pProver {
obj: botan_spake2p_prover_t,
}
unsafe impl Sync for Spake2pProver {}
unsafe impl Send for Spake2pProver {}
botan_impl_drop!(Spake2pProver, botan_spake2p_prover_destroy);
impl Spake2pProver {
pub fn new(
params: &Spake2pParams,
secret: &[u8],
prover_id: &[u8],
verifier_id: &[u8],
context: &[u8],
) -> Result<Self> {
let obj = botan_init!(
botan_spake2p_prover_init,
params.obj,
secret.as_ptr(),
secret.len(),
prover_id.as_ptr(),
prover_id.len(),
verifier_id.as_ptr(),
verifier_id.len(),
context.as_ptr(),
context.len()
)?;
Ok(Self { obj })
}
pub fn generate_message(&mut self, rng: &mut RandomNumberGenerator) -> Result<Vec<u8>> {
let rng = rng.handle();
botan_view_vec!(botan_spake2p_prover_generate_message, self.obj, rng)
}
pub fn process_message(
&mut self,
rng: &mut RandomNumberGenerator,
peer_message: &[u8],
) -> Result<Vec<u8>> {
let rng = rng.handle();
botan_view_vec!(
botan_spake2p_prover_process_message,
self.obj,
rng,
peer_message.as_ptr(),
peer_message.len()
)
}
pub fn shared_secret(&self) -> Result<Vec<u8>> {
botan_view_vec!(botan_spake2p_prover_shared_secret, self.obj)
}
}
#[derive(Debug)]
pub struct Spake2pVerifier {
obj: botan_spake2p_verifier_t,
}
unsafe impl Sync for Spake2pVerifier {}
unsafe impl Send for Spake2pVerifier {}
botan_impl_drop!(Spake2pVerifier, botan_spake2p_verifier_destroy);
impl Spake2pVerifier {
pub fn new(
params: &Spake2pParams,
record: &[u8],
prover_id: &[u8],
verifier_id: &[u8],
context: &[u8],
) -> Result<Self> {
let obj = botan_init!(
botan_spake2p_verifier_init,
params.obj,
record.as_ptr(),
record.len(),
prover_id.as_ptr(),
prover_id.len(),
verifier_id.as_ptr(),
verifier_id.len(),
context.as_ptr(),
context.len()
)?;
Ok(Self { obj })
}
pub fn process_message(
&mut self,
rng: &mut RandomNumberGenerator,
peer_message: &[u8],
) -> Result<Vec<u8>> {
let rng = rng.handle();
botan_view_vec!(
botan_spake2p_verifier_process_message,
self.obj,
rng,
peer_message.as_ptr(),
peer_message.len()
)
}
pub fn verify_confirmation(&mut self, confirmation: &[u8]) -> Result<()> {
botan_call!(
botan_spake2p_verifier_verify_confirmation,
self.obj,
confirmation.as_ptr(),
confirmation.len()
)
}
pub fn skip_confirmation(&mut self) -> Result<()> {
botan_call!(botan_spake2p_verifier_skip_confirmation, self.obj)
}
pub fn shared_secret(&self) -> Result<Vec<u8>> {
botan_view_vec!(botan_spake2p_verifier_shared_secret, self.obj)
}
}