use digest::Digest;
use serde::Serialize;
use srp::server::{SrpServer, SrpServerVerifier};
use getrandom::getrandom;
use crate::types::Result;
pub struct ServerAuthenticationWorkflow<'s, D: Digest> {
delegate: SrpServer<'s, D>,
}
impl<'s, D: Digest> ServerAuthenticationWorkflow<'s, D> {
pub fn new(group: &'s crate::groups::SrpGroup) -> Self {
return Self {
delegate: SrpServer::<'s, D>::new(group),
};
}
pub fn step2(&self, params: ServerStep2Params) -> Result<ServerStep2Result> {
let mut server_private_b = vec![0 as u8; 128];
getrandom(server_private_b.as_mut_slice())?;
let server_public_b = self.delegate.compute_public_ephemeral(
server_private_b.as_slice(),
params.stored_verifier);
return Ok(ServerStep2Result {
server_private_b,
server_public_b
});
}
pub fn step4(&self, params: ServerStep4Params) -> Result<ServerStep4Result<D>> {
let verifier = self.delegate.process_reply(
params.server_private_b,
params.stored_verifier,
params.client_public_a)?;
verifier.verify_client(params.client_proof)?;
return Ok(ServerStep4Result {
verifier
});
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ServerStep2Params<'p> {
#[serde(with = "crate::util::base64_u8")]
pub stored_verifier: &'p [u8],
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ServerStep2Result {
#[serde(with = "crate::util::base64_vec_u8")]
pub server_private_b: Vec<u8>,
#[serde(with = "crate::util::base64_vec_u8")]
pub server_public_b: Vec<u8>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ServerStep4Params<'p> {
#[serde(with = "crate::util::base64_u8")]
pub server_private_b: &'p [u8],
#[serde(with = "crate::util::base64_u8")]
pub stored_verifier: &'p [u8],
#[serde(with = "crate::util::base64_u8")]
pub client_public_a: &'p [u8],
#[serde(with = "crate::util::base64_u8")]
pub client_proof: &'p [u8],
}
pub struct ServerStep4Result<D: Digest> {
verifier: SrpServerVerifier<D>,
}
impl<D: Digest> ServerStep4Result<D> {
pub fn key(&self) -> &[u8] {
return self.verifier.key();
}
pub fn proof(&self) -> &[u8] {
return self.verifier.proof();
}
pub fn verify_client(&self, reply: &[u8]) -> Result<()> {
return self.verifier.verify_client(reply)
.or_else(|err| Err(err.into()));
}
}