#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Error {
WrongLength,
KeyRejected(KeyRejected),
BadSignature,
DecryptFailed,
RngFailed,
NotEqual,
Fault,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct KeyRejected(KeyFormatError);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum KeyFormatError {
Asn1(crate::high::asn1::Error),
WrongLength,
LeadingZero,
Compressed,
NotOnCurve,
SmallOrder,
ScalarOutOfRange,
RsaModulus,
RsaExponent,
RsaPrimes,
MultiPrimeRsa,
MlKemModulus,
UnsupportedPkcs8Version,
MismatchedPkcs8Algorithm,
MismatchedPkcs8Parameters,
MismatchedPkcs8PublicKey,
MismatchedPublicKey,
MismatchedRsaComponents,
MismatchedSec1Curve,
MismatchedSec1PublicKey,
}
impl From<KeyFormatError> for Error {
fn from(kfe: KeyFormatError) -> Self {
Self::KeyRejected(KeyRejected(kfe))
}
}
impl core::fmt::Display for KeyRejected {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.0 {
KeyFormatError::Asn1(e) => write!(f, "an ASN.1 decoding error: {e}"),
KeyFormatError::WrongLength => write!(f, "an encoding of the wrong length"),
KeyFormatError::LeadingZero => write!(f, "an integer with a leading zero byte"),
KeyFormatError::Compressed => write!(f, "a compressed point"),
KeyFormatError::NotOnCurve => write!(f, "a point not on the curve"),
KeyFormatError::SmallOrder => write!(f, "a small-order point"),
KeyFormatError::ScalarOutOfRange => {
write!(f, "a private scalar of zero, or not below the group order")
}
KeyFormatError::RsaModulus => {
write!(
f,
"an RSA modulus that is negative, even, or of unsupported size"
)
}
KeyFormatError::RsaExponent => {
write!(
f,
"an RSA public exponent that is even, one, or over 33 bits"
)
}
KeyFormatError::RsaPrimes => write!(f, "unsupported RSA primes"),
KeyFormatError::MultiPrimeRsa => write!(f, "a multi-prime RSA key"),
KeyFormatError::MlKemModulus => write!(f, "an ML-KEM key failing the modulus check"),
KeyFormatError::UnsupportedPkcs8Version => write!(f, "unsupported PKCS#8 version"),
KeyFormatError::MismatchedPkcs8Algorithm => write!(f, "mismatched PKCS#8 algorithm"),
KeyFormatError::MismatchedPkcs8Parameters => {
write!(f, "mismatched PKCS#8 parameters")
}
KeyFormatError::MismatchedPkcs8PublicKey => write!(f, "mismatched PKCS#8 public key"),
KeyFormatError::MismatchedPublicKey => write!(f, "mismatched public key"),
KeyFormatError::MismatchedRsaComponents => {
write!(f, "mismatched RSA private key components")
}
KeyFormatError::MismatchedSec1Curve => write!(f, "mismatched SEC1 curve"),
KeyFormatError::MismatchedSec1PublicKey => write!(f, "mismatched SEC1 public key"),
}
}
}
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::WrongLength => write!(f, "an input or output was the wrong length"),
Self::KeyRejected(e) => write!(f, "a key was rejected: {e}"),
Self::BadSignature => write!(f, "a signature did not verify"),
Self::DecryptFailed => write!(f, "a ciphertext did not authenticate"),
Self::RngFailed => write!(f, "the system random source failed"),
Self::NotEqual => write!(f, "values compared in constant time were not equal"),
Self::Fault => write!(f, "an internal consistency check failed"),
}
}
}
impl core::error::Error for KeyRejected {}
impl core::error::Error for Error {}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
#[test]
fn key_rejected_displays_its_reason() {
assert_eq!(
format!(
"{}",
Error::from(KeyFormatError::Asn1(
crate::high::asn1::Error::UnexpectedTag
))
),
"a key was rejected: an ASN.1 decoding error: unexpected tag"
);
}
}