Implement custom error type
This commit is contained in:
+177
-21
@@ -4,12 +4,17 @@
|
||||
// LICENSE file in the root directory of this source tree.
|
||||
|
||||
//! A list of error types which are produced during an execution of the protocol
|
||||
use std::convert::Infallible;
|
||||
use std::error::Error;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use displaydoc::Display;
|
||||
use thiserror::Error;
|
||||
|
||||
/// Represents an error in the manipulation of internal cryptographic data
|
||||
#[derive(Clone, Debug, Display, Error, Eq, Hash, PartialEq)]
|
||||
pub enum InternalPakeError {
|
||||
#[derive(Clone, Display, Eq, Hash, PartialEq)]
|
||||
pub enum InternalPakeError<T = Infallible> {
|
||||
/// Custom [`SecretKey`](crate::keypair::SecretKey) error type
|
||||
Custom(T),
|
||||
/// Deserializing from a byte sequence failed
|
||||
InvalidByteSequence,
|
||||
/// Invalid length for {name}: expected {len}, but is actually {actual_len}.
|
||||
@@ -55,13 +60,86 @@ pub enum InternalPakeError {
|
||||
UnexpectedEnvelopeContentsError,
|
||||
}
|
||||
|
||||
impl<T: Debug> Debug for InternalPakeError<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Custom(custom) => f.debug_tuple("InvalidByteSequence").field(custom).finish(),
|
||||
Self::InvalidByteSequence => f.debug_tuple("InvalidByteSequence").finish(),
|
||||
Self::SizeError {
|
||||
name,
|
||||
len,
|
||||
actual_len,
|
||||
} => f
|
||||
.debug_struct("SizeError")
|
||||
.field("name", name)
|
||||
.field("len", len)
|
||||
.field("actual_len", actual_len)
|
||||
.finish(),
|
||||
Self::PointError => f.debug_tuple("PointError").finish(),
|
||||
Self::SubGroupError => f.debug_tuple("SubGroupError").finish(),
|
||||
Self::HashingFailure => f.debug_tuple("HashingFailure").finish(),
|
||||
Self::HashToCurveError => f.debug_tuple("HashToCurveError").finish(),
|
||||
Self::HkdfError => f.debug_tuple("HkdfError").finish(),
|
||||
Self::HmacError => f.debug_tuple("HmacError").finish(),
|
||||
Self::SlowHashError => f.debug_tuple("SlowHashError").finish(),
|
||||
Self::SealError => f.debug_tuple("SealError").finish(),
|
||||
Self::SealOpenError => f.debug_tuple("SealOpenError").finish(),
|
||||
Self::SealOpenHmacError => f.debug_tuple("SealOpenHmacError").finish(),
|
||||
Self::InvalidEnvelopeStructureError => {
|
||||
f.debug_tuple("InvalidEnvelopeStructureError").finish()
|
||||
}
|
||||
Self::IncompatibleEnvelopeModeError => {
|
||||
f.debug_tuple("IncompatibleEnvelopeModeError").finish()
|
||||
}
|
||||
Self::UnexpectedEnvelopeContentsError => {
|
||||
f.debug_tuple("UnexpectedEnvelopeContentsError").finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Error> Error for InternalPakeError<T> {}
|
||||
|
||||
impl InternalPakeError {
|
||||
pub fn into_custom<T>(self) -> InternalPakeError<T> {
|
||||
match self {
|
||||
Self::Custom(_) => unreachable!(),
|
||||
Self::InvalidByteSequence => InternalPakeError::InvalidByteSequence,
|
||||
Self::SizeError {
|
||||
name,
|
||||
len,
|
||||
actual_len,
|
||||
} => InternalPakeError::SizeError {
|
||||
name,
|
||||
len,
|
||||
actual_len,
|
||||
},
|
||||
Self::PointError => InternalPakeError::PointError,
|
||||
Self::SubGroupError => InternalPakeError::SubGroupError,
|
||||
Self::HashingFailure => InternalPakeError::HashingFailure,
|
||||
Self::HashToCurveError => InternalPakeError::HashToCurveError,
|
||||
Self::HkdfError => InternalPakeError::HkdfError,
|
||||
Self::HmacError => InternalPakeError::HmacError,
|
||||
Self::SlowHashError => InternalPakeError::SlowHashError,
|
||||
Self::SealError => InternalPakeError::SealError,
|
||||
Self::SealOpenError => InternalPakeError::SealOpenError,
|
||||
Self::SealOpenHmacError => InternalPakeError::SealOpenHmacError,
|
||||
Self::InvalidEnvelopeStructureError => InternalPakeError::InvalidEnvelopeStructureError,
|
||||
Self::IncompatibleEnvelopeModeError => InternalPakeError::IncompatibleEnvelopeModeError,
|
||||
Self::UnexpectedEnvelopeContentsError => {
|
||||
InternalPakeError::UnexpectedEnvelopeContentsError
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an error in password checking
|
||||
#[derive(Clone, Debug, Display, Error, Eq, Hash, PartialEq)]
|
||||
pub enum PakeError {
|
||||
#[derive(Clone, Display, Eq, Hash, PartialEq)]
|
||||
pub enum PakeError<T = Infallible> {
|
||||
/// This error results from an internal error during PRF construction
|
||||
///
|
||||
/// Internal error during PRF verification: {0}
|
||||
CryptoError(InternalPakeError),
|
||||
CryptoError(InternalPakeError<T>),
|
||||
/// This error occurs when the server object that is being called finish() on is malformed
|
||||
/// Incomplete set of keys passed into finish() function
|
||||
IncompleteKeysError,
|
||||
@@ -77,21 +155,62 @@ pub enum PakeError {
|
||||
IdentityGroupElementError,
|
||||
}
|
||||
|
||||
impl<T: Debug> Debug for PakeError<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::CryptoError(internal_pake_error) => f
|
||||
.debug_tuple("CryptoError")
|
||||
.field(internal_pake_error)
|
||||
.finish(),
|
||||
Self::IncompleteKeysError => f.debug_tuple("IncompleteKeysError").finish(),
|
||||
Self::IncompatibleServerStaticPublicKeyError => f
|
||||
.debug_tuple("IncompatibleServerStaticPublicKeyError")
|
||||
.finish(),
|
||||
Self::KeyExchangeMacValidationError => {
|
||||
f.debug_tuple("KeyExchangeMacValidationError").finish()
|
||||
}
|
||||
Self::InvalidLoginError => f.debug_tuple("InvalidLoginError").finish(),
|
||||
Self::SerializationError => f.debug_tuple("SerializationError").finish(),
|
||||
Self::IdentityGroupElementError => f.debug_tuple("IdentityGroupElementError").finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Error> Error for PakeError<T> {}
|
||||
|
||||
// This is meant to express future(ly) non-trivial ways of converting the
|
||||
// internal error into a PakeError
|
||||
impl From<InternalPakeError> for PakeError {
|
||||
fn from(e: InternalPakeError) -> PakeError {
|
||||
impl<T> From<InternalPakeError<T>> for PakeError<T> {
|
||||
fn from(e: InternalPakeError<T>) -> PakeError<T> {
|
||||
PakeError::CryptoError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl PakeError {
|
||||
pub fn into_custom<T>(self) -> PakeError<T> {
|
||||
match self {
|
||||
Self::CryptoError(internal_pake_error) => {
|
||||
PakeError::CryptoError(internal_pake_error.into_custom())
|
||||
}
|
||||
Self::IncompleteKeysError => PakeError::IncompleteKeysError,
|
||||
Self::IncompatibleServerStaticPublicKeyError => {
|
||||
PakeError::IncompatibleServerStaticPublicKeyError
|
||||
}
|
||||
Self::KeyExchangeMacValidationError => PakeError::KeyExchangeMacValidationError,
|
||||
Self::InvalidLoginError => PakeError::InvalidLoginError,
|
||||
Self::SerializationError => PakeError::SerializationError,
|
||||
Self::IdentityGroupElementError => PakeError::IdentityGroupElementError,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an error in protocol handling
|
||||
#[derive(Clone, Debug, Display, Error, Eq, Hash, PartialEq)]
|
||||
pub enum ProtocolError {
|
||||
#[derive(Clone, Display, Eq, Hash, PartialEq)]
|
||||
pub enum ProtocolError<T = Infallible> {
|
||||
/// This error results from an error during password verification
|
||||
///
|
||||
/// Internal error during password verification: {0}
|
||||
VerificationError(PakeError),
|
||||
VerificationError(PakeError<T>),
|
||||
/// This error occurs when the inner envelope is malformed
|
||||
InvalidInnerEnvelopeError,
|
||||
/// This error occurs when the server answer cannot be handled
|
||||
@@ -108,18 +227,38 @@ pub enum ProtocolError {
|
||||
ReflectedValueError,
|
||||
}
|
||||
|
||||
impl<T: Debug> Debug for ProtocolError<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::VerificationError(pake_error) => f
|
||||
.debug_tuple("VerificationError")
|
||||
.field(pake_error)
|
||||
.finish(),
|
||||
Self::InvalidInnerEnvelopeError => f.debug_tuple("InvalidInnerEnvelopeError").finish(),
|
||||
Self::ServerError => f.debug_tuple("ServerError").finish(),
|
||||
Self::ServerInvalidEnvelopeCredentialsFormatError => f
|
||||
.debug_tuple("ServerInvalidEnvelopeCredentialsFormatError")
|
||||
.finish(),
|
||||
Self::ClientError => f.debug_tuple("ClientError").finish(),
|
||||
Self::ReflectedValueError => f.debug_tuple("ReflectedValueError").finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Error> Error for ProtocolError<T> {}
|
||||
|
||||
// This is meant to express future(ly) non-trivial ways of converting the
|
||||
// Pake error into a ProtocolError
|
||||
impl From<PakeError> for ProtocolError {
|
||||
fn from(e: PakeError) -> ProtocolError {
|
||||
impl<T> From<PakeError<T>> for ProtocolError<T> {
|
||||
fn from(e: PakeError<T>) -> ProtocolError<T> {
|
||||
ProtocolError::VerificationError(e)
|
||||
}
|
||||
}
|
||||
|
||||
// This is meant to express future(ly) non-trivial ways of converting the
|
||||
// internal error into a ProtocolError
|
||||
impl From<InternalPakeError> for ProtocolError {
|
||||
fn from(e: InternalPakeError) -> ProtocolError {
|
||||
impl<T> From<InternalPakeError<T>> for ProtocolError<T> {
|
||||
fn from(e: InternalPakeError<T>) -> ProtocolError<T> {
|
||||
ProtocolError::VerificationError(e.into())
|
||||
}
|
||||
}
|
||||
@@ -127,25 +266,42 @@ impl From<InternalPakeError> for ProtocolError {
|
||||
// See https://github.com/rust-lang/rust/issues/64715 and remove this when
|
||||
// merged, and https://github.com/dtolnay/thiserror/issues/62 for why this
|
||||
// comes up in our doc tests.
|
||||
impl From<::std::convert::Infallible> for ProtocolError {
|
||||
impl<T> From<::std::convert::Infallible> for ProtocolError<T> {
|
||||
fn from(_: ::std::convert::Infallible) -> Self {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<generic_bytes::TryFromSizedBytesError> for InternalPakeError {
|
||||
impl ProtocolError {
|
||||
pub fn into_custom<T>(self) -> ProtocolError<T> {
|
||||
match self {
|
||||
Self::VerificationError(pake_error) => {
|
||||
ProtocolError::VerificationError(pake_error.into_custom())
|
||||
}
|
||||
Self::InvalidInnerEnvelopeError => ProtocolError::InvalidInnerEnvelopeError,
|
||||
Self::ServerError => ProtocolError::ServerError,
|
||||
Self::ServerInvalidEnvelopeCredentialsFormatError => {
|
||||
ProtocolError::ServerInvalidEnvelopeCredentialsFormatError
|
||||
}
|
||||
Self::ClientError => ProtocolError::ClientError,
|
||||
Self::ReflectedValueError => ProtocolError::ReflectedValueError,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<generic_bytes::TryFromSizedBytesError> for InternalPakeError<T> {
|
||||
fn from(_: generic_bytes::TryFromSizedBytesError) -> Self {
|
||||
InternalPakeError::InvalidByteSequence
|
||||
}
|
||||
}
|
||||
|
||||
impl From<generic_bytes::TryFromSizedBytesError> for PakeError {
|
||||
impl<T> From<generic_bytes::TryFromSizedBytesError> for PakeError<T> {
|
||||
fn from(e: generic_bytes::TryFromSizedBytesError) -> Self {
|
||||
PakeError::CryptoError(e.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<generic_bytes::TryFromSizedBytesError> for ProtocolError {
|
||||
impl<T> From<generic_bytes::TryFromSizedBytesError> for ProtocolError<T> {
|
||||
fn from(e: generic_bytes::TryFromSizedBytesError) -> Self {
|
||||
PakeError::CryptoError(e.into()).into()
|
||||
}
|
||||
@@ -154,11 +310,11 @@ impl From<generic_bytes::TryFromSizedBytesError> for ProtocolError {
|
||||
pub(crate) mod utils {
|
||||
use super::*;
|
||||
|
||||
pub fn check_slice_size<'a>(
|
||||
pub fn check_slice_size<'a, T>(
|
||||
slice: &'a [u8],
|
||||
expected_len: usize,
|
||||
arg_name: &'static str,
|
||||
) -> Result<&'a [u8], InternalPakeError> {
|
||||
) -> Result<&'a [u8], InternalPakeError<T>> {
|
||||
if slice.len() != expected_len {
|
||||
return Err(InternalPakeError::SizeError {
|
||||
name: arg_name,
|
||||
|
||||
@@ -35,7 +35,7 @@ pub trait KeyExchange<D: Hash, G: Group> {
|
||||
id_u: Vec<u8>,
|
||||
id_s: Vec<u8>,
|
||||
context: Vec<u8>,
|
||||
) -> Result<(Self::KE2State, Self::KE2Message), ProtocolError>;
|
||||
) -> Result<(Self::KE2State, Self::KE2Message), ProtocolError<S::Error>>;
|
||||
|
||||
#[allow(clippy::too_many_arguments, clippy::type_complexity)]
|
||||
fn generate_ke3(
|
||||
|
||||
@@ -80,13 +80,13 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
||||
id_u: Vec<u8>,
|
||||
id_s: Vec<u8>,
|
||||
context: Vec<u8>,
|
||||
) -> Result<(Self::KE2State, Self::KE2Message), ProtocolError> {
|
||||
) -> Result<(Self::KE2State, Self::KE2Message), ProtocolError<S::Error>> {
|
||||
let server_e_kp = KeyPair::<G>::generate_random(rng);
|
||||
let server_nonce = generate_nonce::<R>(rng);
|
||||
|
||||
let mut transcript_hasher = D::new()
|
||||
.chain(STR_RFC)
|
||||
.chain(&serialize(&context, 2)?)
|
||||
.chain(&serialize(&context, 2).map_err(PakeError::into_custom)?)
|
||||
.chain(&id_u)
|
||||
.chain(&serialized_credential_request[..])
|
||||
.chain(&id_s)
|
||||
@@ -456,11 +456,15 @@ impl<HashLen: ArrayLength<u8>> FromBytes for Ke3Message<HashLen> {
|
||||
fn derive_3dh_keys<D: Hash, G: Group, S: SecretKey<G>>(
|
||||
dh: TripleDHComponents<G, S>,
|
||||
hashed_derivation_transcript: &[u8],
|
||||
) -> Result<TripleDHDerivationResult<D>, ProtocolError> {
|
||||
) -> Result<TripleDHDerivationResult<D>, ProtocolError<S::Error>> {
|
||||
let ikm: Vec<u8> = [
|
||||
&dh.sk1.diffie_hellman(dh.pk1)?[..],
|
||||
&dh.sk1
|
||||
.diffie_hellman(dh.pk1)
|
||||
.map_err(InternalPakeError::into_custom)?[..],
|
||||
&dh.sk2.diffie_hellman(dh.pk2)?[..],
|
||||
&dh.sk3.diffie_hellman(dh.pk3)?[..],
|
||||
&dh.sk3
|
||||
.diffie_hellman(dh.pk3)
|
||||
.map_err(InternalPakeError::into_custom)?[..],
|
||||
]
|
||||
.concat();
|
||||
|
||||
@@ -469,25 +473,29 @@ fn derive_3dh_keys<D: Hash, G: Group, S: SecretKey<G>>(
|
||||
&extracted_ikm,
|
||||
STR_HANDSHAKE_SECRET,
|
||||
hashed_derivation_transcript,
|
||||
)?;
|
||||
)
|
||||
.map_err(ProtocolError::into_custom)?;
|
||||
let session_key = derive_secrets::<D>(
|
||||
&extracted_ikm,
|
||||
STR_SESSION_KEY,
|
||||
hashed_derivation_transcript,
|
||||
)?;
|
||||
)
|
||||
.map_err(ProtocolError::into_custom)?;
|
||||
|
||||
let km2 = hkdf_expand_label::<D>(
|
||||
&handshake_secret,
|
||||
STR_SERVER_MAC,
|
||||
b"",
|
||||
<D as Digest>::OutputSize::to_usize(),
|
||||
)?;
|
||||
)
|
||||
.map_err(ProtocolError::into_custom)?;
|
||||
let km3 = hkdf_expand_label::<D>(
|
||||
&handshake_secret,
|
||||
STR_CLIENT_MAC,
|
||||
b"",
|
||||
<D as Digest>::OutputSize::to_usize(),
|
||||
)?;
|
||||
)
|
||||
.map_err(ProtocolError::into_custom)?;
|
||||
|
||||
Ok((
|
||||
GenericArray::clone_from_slice(&session_key),
|
||||
|
||||
+8
-4
@@ -114,7 +114,7 @@ impl<G: Group, S: SecretKey<G>> KeyPair<G, S> {
|
||||
}
|
||||
|
||||
/// Obtains a KeyPair from a slice representing the private key
|
||||
pub fn from_private_key_slice(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
pub fn from_private_key_slice(input: &[u8]) -> Result<Self, ProtocolError<S::Error>> {
|
||||
let sk = S::deserialize(input)?;
|
||||
let pk = sk.public_key()?;
|
||||
Ok(Self { pk, sk })
|
||||
@@ -276,20 +276,24 @@ impl<G: Group> SizedBytes for PrivateKey<G> {
|
||||
|
||||
/// A trait specifying the requirements for a private key container
|
||||
pub trait SecretKey<G: Group>: Clone + Sized + Zeroize {
|
||||
type Error;
|
||||
|
||||
/// Diffie-Hellman key exchange implementation
|
||||
fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalPakeError>;
|
||||
fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalPakeError<Self::Error>>;
|
||||
|
||||
/// Returns public key from private key
|
||||
fn public_key(&self) -> Result<PublicKey<G>, InternalPakeError>;
|
||||
fn public_key(&self) -> Result<PublicKey<G>, InternalPakeError<Self::Error>>;
|
||||
|
||||
/// Serialization into bytes
|
||||
fn serialize(&self) -> Vec<u8>;
|
||||
|
||||
/// Deserialization from bytes
|
||||
fn deserialize(input: &[u8]) -> Result<Self, InternalPakeError>;
|
||||
fn deserialize(input: &[u8]) -> Result<Self, InternalPakeError<Self::Error>>;
|
||||
}
|
||||
|
||||
impl<G: Group> SecretKey<G> for PrivateKey<G> {
|
||||
type Error = std::convert::Infallible;
|
||||
|
||||
fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalPakeError> {
|
||||
let pk_data = GenericArray::<u8, G::ElemLen>::from_slice(&pk.0[..]);
|
||||
let point = G::from_element_slice(pk_data)?;
|
||||
|
||||
+3
-3
@@ -14,7 +14,7 @@ use crate::{
|
||||
},
|
||||
group::Group,
|
||||
key_exchange::traits::{FromBytes, KeyExchange, ToBytes},
|
||||
keypair::{KeyPair, PublicKey, SizedBytesExt},
|
||||
keypair::{KeyPair, PublicKey, SecretKey, SizedBytesExt},
|
||||
opaque::ServerSetup,
|
||||
};
|
||||
use digest::Digest;
|
||||
@@ -193,9 +193,9 @@ impl<CS: CipherSuite> RegistrationUpload<CS> {
|
||||
}
|
||||
|
||||
// Creates a dummy instance used for faking a [CredentialResponse]
|
||||
pub(crate) fn dummy<R: RngCore + CryptoRng>(
|
||||
pub(crate) fn dummy<R: RngCore + CryptoRng, S: SecretKey<CS::Group>>(
|
||||
rng: &mut R,
|
||||
server_setup: &ServerSetup<CS>,
|
||||
server_setup: &ServerSetup<CS, S>,
|
||||
) -> Self {
|
||||
let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::to_usize()];
|
||||
rng.fill_bytes(&mut masking_key);
|
||||
|
||||
+14
-10
@@ -80,7 +80,7 @@ impl<CS: CipherSuite, S: SecretKey<CS::Group>> ServerSetup<CS, S> {
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError<S::Error>> {
|
||||
let seed_len = <CS::Hash as Digest>::OutputSize::to_usize();
|
||||
let key_len = <PrivateKey<CS::Group> as SizedBytes>::Len::to_usize();
|
||||
let checked_slice = check_slice_size(input, seed_len + key_len + key_len, "server_setup")?;
|
||||
@@ -88,7 +88,8 @@ impl<CS: CipherSuite, S: SecretKey<CS::Group>> ServerSetup<CS, S> {
|
||||
Ok(Self {
|
||||
oprf_seed: GenericArray::clone_from_slice(&checked_slice[..seed_len]),
|
||||
keypair: KeyPair::from_private_key_slice(&checked_slice[seed_len..seed_len + key_len])?,
|
||||
fake_keypair: KeyPair::from_private_key_slice(&checked_slice[seed_len + key_len..])?,
|
||||
fake_keypair: KeyPair::from_private_key_slice(&checked_slice[seed_len + key_len..])
|
||||
.map_err(ProtocolError::into_custom)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -402,9 +403,9 @@ impl<CS: CipherSuite> ServerRegistration<CS> {
|
||||
}
|
||||
|
||||
// Creates a dummy instance used for faking a [CredentialResponse]
|
||||
pub(crate) fn dummy<R: RngCore + CryptoRng>(
|
||||
pub(crate) fn dummy<R: RngCore + CryptoRng, S: SecretKey<CS::Group>>(
|
||||
rng: &mut R,
|
||||
server_setup: &ServerSetup<CS>,
|
||||
server_setup: &ServerSetup<CS, S>,
|
||||
) -> Self {
|
||||
Self(RegistrationUpload::dummy(rng, server_setup))
|
||||
}
|
||||
@@ -763,14 +764,14 @@ impl<CS: CipherSuite> ServerLogin<CS> {
|
||||
|
||||
/// From the client's "blinded" password, returns a challenge to be
|
||||
/// sent back to the client, as well as a ServerLogin
|
||||
pub fn start<R: RngCore + CryptoRng>(
|
||||
pub fn start<R: RngCore + CryptoRng, S: SecretKey<CS::Group>>(
|
||||
rng: &mut R,
|
||||
server_setup: &ServerSetup<CS>,
|
||||
server_setup: &ServerSetup<CS, S>,
|
||||
password_file: Option<ServerRegistration<CS>>,
|
||||
l1: CredentialRequest<CS>,
|
||||
credential_identifier: &[u8],
|
||||
params: ServerLoginStartParameters,
|
||||
) -> Result<ServerLoginStartResult<CS>, ProtocolError> {
|
||||
) -> Result<ServerLoginStartResult<CS>, ProtocolError<S::Error>> {
|
||||
let record = match password_file {
|
||||
Some(x) => x,
|
||||
None => ServerRegistration::dummy(rng, server_setup),
|
||||
@@ -797,20 +798,23 @@ impl<CS: CipherSuite> ServerLogin<CS> {
|
||||
&masking_nonce,
|
||||
&server_s_pk,
|
||||
&record.0.envelope,
|
||||
)?;
|
||||
)
|
||||
.map_err(ProtocolError::into_custom)?;
|
||||
|
||||
let (id_u, id_s) = bytestrings_from_identifiers(
|
||||
&optional_ids,
|
||||
&client_s_pk.to_arr(),
|
||||
&server_s_pk.to_arr(),
|
||||
)?;
|
||||
)
|
||||
.map_err(ProtocolError::into_custom)?;
|
||||
|
||||
let l1_bytes = &l1.serialize();
|
||||
|
||||
let oprf_key = oprf_key_from_seed::<CS::Group, CS::Hash>(
|
||||
&server_setup.oprf_seed,
|
||||
credential_identifier,
|
||||
)?;
|
||||
)
|
||||
.map_err(ProtocolError::into_custom)?;
|
||||
let beta = oprf::evaluate(l1.alpha, &oprf_key);
|
||||
|
||||
let credential_response_component =
|
||||
|
||||
Reference in New Issue
Block a user