2020-06-05 09:35:14 -07:00
|
|
|
// Copyright (c) Facebook, Inc. and its affiliates.
|
|
|
|
|
//
|
|
|
|
|
// This source code is licensed under the MIT license found in the
|
|
|
|
|
// LICENSE file in the root directory of this source tree.
|
|
|
|
|
|
|
|
|
|
//! A list of error types which are produced during an execution of the protocol
|
2021-07-20 11:49:37 +02:00
|
|
|
use std::convert::Infallible;
|
|
|
|
|
use std::error::Error;
|
|
|
|
|
use std::fmt::Debug;
|
|
|
|
|
|
2020-07-06 15:40:35 -04:00
|
|
|
use displaydoc::Display;
|
2020-06-05 09:35:14 -07:00
|
|
|
|
|
|
|
|
/// Represents an error in the manipulation of internal cryptographic data
|
2021-07-20 11:49:37 +02:00
|
|
|
#[derive(Clone, Display, Eq, Hash, PartialEq)]
|
|
|
|
|
pub enum InternalPakeError<T = Infallible> {
|
|
|
|
|
/// Custom [`SecretKey`](crate::keypair::SecretKey) error type
|
|
|
|
|
Custom(T),
|
2020-11-03 21:44:00 +00:00
|
|
|
/// Deserializing from a byte sequence failed
|
|
|
|
|
InvalidByteSequence,
|
2020-07-06 15:40:35 -04:00
|
|
|
/// Invalid length for {name}: expected {len}, but is actually {actual_len}.
|
2020-06-05 09:35:14 -07:00
|
|
|
SizeError {
|
2020-07-06 15:40:35 -04:00
|
|
|
/// name
|
2020-06-05 09:35:14 -07:00
|
|
|
name: &'static str,
|
2020-07-06 15:40:35 -04:00
|
|
|
/// length
|
2020-06-05 09:35:14 -07:00
|
|
|
len: usize,
|
2020-07-06 15:40:35 -04:00
|
|
|
/// actual
|
2020-06-05 09:35:14 -07:00
|
|
|
actual_len: usize,
|
|
|
|
|
},
|
2020-07-06 15:40:35 -04:00
|
|
|
/// Could not decompress point.
|
2020-06-05 09:35:14 -07:00
|
|
|
PointError,
|
2020-07-06 15:40:35 -04:00
|
|
|
/// Key belongs to a small subgroup!
|
2020-06-05 09:35:14 -07:00
|
|
|
SubGroupError,
|
2020-07-06 15:40:35 -04:00
|
|
|
/// hashing to a key failed
|
2020-06-05 09:35:14 -07:00
|
|
|
HashingFailure,
|
2020-11-12 10:00:09 -08:00
|
|
|
/// Computing the hash-to-curve function failed
|
|
|
|
|
HashToCurveError,
|
2020-07-06 15:40:35 -04:00
|
|
|
/// Computing HKDF failed while deriving subkeys
|
2020-06-05 09:35:14 -07:00
|
|
|
HkdfError,
|
2020-07-06 15:40:35 -04:00
|
|
|
/// Computing HMAC failed while supplying a secret key
|
2020-06-05 09:35:14 -07:00
|
|
|
HmacError,
|
2020-07-06 15:40:35 -04:00
|
|
|
/// Computing the slow hashing function failed
|
2020-06-08 21:02:01 -07:00
|
|
|
SlowHashError,
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error occurs when the envelope seal fails
|
|
|
|
|
Constructing the envelope seal failed. */
|
2020-07-02 12:24:53 -07:00
|
|
|
SealError,
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error occurs when the envelope seal open fails
|
|
|
|
|
Opening the envelope seal failed. */
|
2020-07-02 12:24:53 -07:00
|
|
|
SealOpenError,
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error occurs when the envelope seal open hmac check fails
|
|
|
|
|
HMAC check in seal open failed. */
|
2020-07-02 12:24:53 -07:00
|
|
|
SealOpenHmacError,
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error occurs when the envelope cannot be constructed properly
|
|
|
|
|
based on the credentials that were specified to be required. */
|
2021-01-04 14:27:20 -08:00
|
|
|
InvalidEnvelopeStructureError,
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error occurs when attempting to open an envelope of the wrong
|
|
|
|
|
type (base mode, custom identifier) */
|
2021-01-04 14:27:20 -08:00
|
|
|
IncompatibleEnvelopeModeError,
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error occurs when the envelope is opened and deserialization
|
|
|
|
|
fails */
|
2021-01-04 14:27:20 -08:00
|
|
|
UnexpectedEnvelopeContentsError,
|
2020-06-05 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
2021-07-20 11:49:37 +02:00
|
|
|
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 {
|
2021-07-20 14:22:41 +02:00
|
|
|
/// Convert `InternalPakeError<Infallible>` into `InternalPakeError<T>
|
2021-07-20 11:49:37 +02:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
/// Represents an error in password checking
|
2021-07-20 11:49:37 +02:00
|
|
|
#[derive(Clone, Display, Eq, Hash, PartialEq)]
|
|
|
|
|
pub enum PakeError<T = Infallible> {
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error results from an internal error during PRF construction
|
|
|
|
|
|
|
|
|
|
Internal error during PRF verification: {0} */
|
2021-07-20 11:49:37 +02:00
|
|
|
CryptoError(InternalPakeError<T>),
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error occurs when the server object that is being called finish() on is malformed
|
|
|
|
|
Incomplete set of keys passed into finish() function */
|
2020-06-05 09:35:14 -07:00
|
|
|
IncompleteKeysError,
|
2020-07-06 15:40:35 -04:00
|
|
|
/// The provided server public key doesn't match the sealed one
|
2020-06-05 09:35:14 -07:00
|
|
|
IncompatibleServerStaticPublicKeyError,
|
2020-07-06 15:40:35 -04:00
|
|
|
/// Error in key exchange protocol when attempting to validate MACs
|
2020-06-05 09:35:14 -07:00
|
|
|
KeyExchangeMacValidationError,
|
2020-07-06 15:40:35 -04:00
|
|
|
/// Error in validating credentials
|
2020-06-05 09:35:14 -07:00
|
|
|
InvalidLoginError,
|
2020-09-10 17:01:06 -04:00
|
|
|
/// Error with serializing / deserializing protocol messages
|
|
|
|
|
SerializationError,
|
2021-06-15 17:31:12 -07:00
|
|
|
/// Identity group element was encountered during deserialization, which is invalid
|
|
|
|
|
IdentityGroupElementError,
|
2020-06-05 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
2021-07-20 11:49:37 +02:00
|
|
|
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> {}
|
|
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
// This is meant to express future(ly) non-trivial ways of converting the
|
|
|
|
|
// internal error into a PakeError
|
2021-07-20 11:49:37 +02:00
|
|
|
impl<T> From<InternalPakeError<T>> for PakeError<T> {
|
|
|
|
|
fn from(e: InternalPakeError<T>) -> PakeError<T> {
|
2020-06-05 09:35:14 -07:00
|
|
|
PakeError::CryptoError(e)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-20 11:49:37 +02:00
|
|
|
impl PakeError {
|
2021-07-20 14:22:41 +02:00
|
|
|
/// Convert `PakeError<Infallible>` into `PakeError<T>
|
2021-07-20 11:49:37 +02:00
|
|
|
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,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
/// Represents an error in protocol handling
|
2021-07-20 11:49:37 +02:00
|
|
|
#[derive(Clone, Display, Eq, Hash, PartialEq)]
|
|
|
|
|
pub enum ProtocolError<T = Infallible> {
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error results from an error during password verification
|
|
|
|
|
|
|
|
|
|
Internal error during password verification: {0} */
|
2021-07-20 11:49:37 +02:00
|
|
|
VerificationError(PakeError<T>),
|
2021-04-16 01:07:07 -07:00
|
|
|
/// This error occurs when the inner envelope is malformed
|
|
|
|
|
InvalidInnerEnvelopeError,
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error occurs when the server answer cannot be handled
|
|
|
|
|
Server response cannot be handled. */
|
2020-06-05 09:35:14 -07:00
|
|
|
ServerError,
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error occurs when the server specifies an envelope credentials
|
|
|
|
|
format that is invalid */
|
2020-10-09 10:51:58 -07:00
|
|
|
ServerInvalidEnvelopeCredentialsFormatError,
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error occurs when the client request cannot be handled
|
|
|
|
|
Client request cannot be handled. */
|
2020-06-05 09:35:14 -07:00
|
|
|
ClientError,
|
2021-07-31 00:36:57 +02:00
|
|
|
/** This error occurs when the client detects that the server has
|
|
|
|
|
reflected the OPRF value (beta == alpha) */
|
2021-07-12 12:33:19 -07:00
|
|
|
ReflectedValueError,
|
2020-06-05 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
2021-07-20 11:49:37 +02:00
|
|
|
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> {}
|
|
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
// This is meant to express future(ly) non-trivial ways of converting the
|
|
|
|
|
// Pake error into a ProtocolError
|
2021-07-20 11:49:37 +02:00
|
|
|
impl<T> From<PakeError<T>> for ProtocolError<T> {
|
|
|
|
|
fn from(e: PakeError<T>) -> ProtocolError<T> {
|
2020-06-05 09:35:14 -07:00
|
|
|
ProtocolError::VerificationError(e)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This is meant to express future(ly) non-trivial ways of converting the
|
|
|
|
|
// internal error into a ProtocolError
|
2021-07-20 11:49:37 +02:00
|
|
|
impl<T> From<InternalPakeError<T>> for ProtocolError<T> {
|
|
|
|
|
fn from(e: InternalPakeError<T>) -> ProtocolError<T> {
|
2020-06-05 09:35:14 -07:00
|
|
|
ProtocolError::VerificationError(e.into())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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.
|
2021-07-20 11:49:37 +02:00
|
|
|
impl<T> From<::std::convert::Infallible> for ProtocolError<T> {
|
2020-06-05 09:35:14 -07:00
|
|
|
fn from(_: ::std::convert::Infallible) -> Self {
|
|
|
|
|
unreachable!()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-20 11:49:37 +02:00
|
|
|
impl ProtocolError {
|
2021-07-20 14:22:41 +02:00
|
|
|
/// Convert `ProtocolError<Infallible>` into `ProtocolError<T>
|
2021-07-20 11:49:37 +02:00
|
|
|
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> {
|
2020-11-03 21:44:00 +00:00
|
|
|
fn from(_: generic_bytes::TryFromSizedBytesError) -> Self {
|
|
|
|
|
InternalPakeError::InvalidByteSequence
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-20 11:49:37 +02:00
|
|
|
impl<T> From<generic_bytes::TryFromSizedBytesError> for PakeError<T> {
|
2020-11-03 21:44:00 +00:00
|
|
|
fn from(e: generic_bytes::TryFromSizedBytesError) -> Self {
|
|
|
|
|
PakeError::CryptoError(e.into())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-20 11:49:37 +02:00
|
|
|
impl<T> From<generic_bytes::TryFromSizedBytesError> for ProtocolError<T> {
|
2020-11-03 21:44:00 +00:00
|
|
|
fn from(e: generic_bytes::TryFromSizedBytesError) -> Self {
|
|
|
|
|
PakeError::CryptoError(e.into()).into()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
pub(crate) mod utils {
|
|
|
|
|
use super::*;
|
|
|
|
|
|
2021-07-20 11:49:37 +02:00
|
|
|
pub fn check_slice_size<'a, T>(
|
2020-06-05 09:35:14 -07:00
|
|
|
slice: &'a [u8],
|
|
|
|
|
expected_len: usize,
|
|
|
|
|
arg_name: &'static str,
|
2021-07-20 11:49:37 +02:00
|
|
|
) -> Result<&'a [u8], InternalPakeError<T>> {
|
2020-06-05 09:35:14 -07:00
|
|
|
if slice.len() != expected_len {
|
|
|
|
|
return Err(InternalPakeError::SizeError {
|
|
|
|
|
name: arg_name,
|
|
|
|
|
len: expected_len,
|
|
|
|
|
actual_len: slice.len(),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
Ok(slice)
|
|
|
|
|
}
|
2020-10-09 10:51:58 -07:00
|
|
|
|
|
|
|
|
pub fn check_slice_size_atleast<'a>(
|
|
|
|
|
slice: &'a [u8],
|
|
|
|
|
expected_len: usize,
|
|
|
|
|
arg_name: &'static str,
|
|
|
|
|
) -> Result<&'a [u8], InternalPakeError> {
|
|
|
|
|
if slice.len() < expected_len {
|
|
|
|
|
return Err(InternalPakeError::SizeError {
|
|
|
|
|
name: arg_name,
|
|
|
|
|
len: expected_len,
|
|
|
|
|
actual_len: slice.len(),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
Ok(slice)
|
|
|
|
|
}
|
2020-06-05 09:35:14 -07:00
|
|
|
}
|