#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error(transparent)]
Attributes(#[from] AttributesError),
#[error(transparent)]
Conversions(#[from] ConversionsError),
#[error(transparent)]
Cipher(#[from] CipherError),
#[error(transparent)]
Kdf(#[from] KdfError),
#[error(transparent)]
Nonce(#[from] NonceError),
#[error(transparent)]
Seal(#[from] SealError),
#[error(transparent)]
Sign(#[from] SignError),
#[error(transparent)]
Threshold(#[from] ThresholdError),
#[error(transparent)]
Verify(#[from] VerifyError),
#[error("key split error: {0}")]
KeySplit(String),
#[error(transparent)]
Multibase(#[from] multi_base::Error),
#[error(transparent)]
Multicodec(#[from] multi_codec::Error),
#[error(transparent)]
Multiutil(#[from] multi_util::Error),
#[error(transparent)]
Multisig(#[from] multi_sig::Error),
#[error(transparent)]
Multitrait(#[from] multi_trait::Error),
#[error(transparent)]
Multihash(#[from] multi_hash::Error),
#[error(transparent)]
Utf8(#[from] std::string::FromUtf8Error),
#[error("Duplicate Multikey attribute: {0}")]
DuplicateAttribute(u8),
#[error("Missing Multikey sigil")]
MissingSigil,
#[error("Unsupported key algorithm: {0}")]
UnsupportedAlgorithm(String),
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum AttributesError {
#[error("Unsupported key codec: {0}")]
UnsupportedCodec(multi_codec::Codec),
#[error("Key data unit missing")]
MissingKey,
#[error("Not a secret key {0}")]
NotSecretKey(multi_codec::codec::Codec),
#[error("Key is encrypted")]
EncryptedKey,
#[error("Invalid attribute name {0}")]
InvalidAttributeName(String),
#[error("Invalid attribute value {0}")]
InvalidAttributeValue(u8),
#[error("Missing threshold")]
MissingThreshold,
#[error("Missing limit")]
MissingLimit,
#[error("Missing share identifier")]
MissingShareIdentifier,
#[error("Missing threshold data")]
MissingThresholdData,
#[error("Missing group public key")]
MissingGroupPublicKey,
#[error("Missing threshold participants")]
MissingThresholdParticipants,
#[error("Threshold marker CBOR error: {0}")]
ThresholdMarkerCbor(String),
#[error("Missing threshold marker signature")]
MissingThresholdMarkerSig,
#[error("Threshold marker signature verification failed")]
ThresholdMarkerSigInvalid,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum ConversionsError {
#[error(transparent)]
Ssh(#[from] SshErrors),
#[error("Public key error: {0}")]
PublicKeyFailure(String),
#[error("Secret key error: {0}")]
SecretKeyFailure(String),
#[error("Unsupported SSH key algorithm: {0}")]
UnsupportedAlgorithm(String),
#[error("Unsupported key codec: {0}")]
UnsupportedCodec(multi_codec::Codec),
}
#[derive(Debug)]
pub enum SshErrors {
Key(ssh_key::Error),
KeyLabel(ssh_encoding::LabelError),
Encoding(ssh_encoding::Error),
}
impl std::fmt::Display for SshErrors {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SshErrors::Key(err) => write!(f, "{}", err),
SshErrors::KeyLabel(err) => write!(f, "{}", err),
SshErrors::Encoding(err) => write!(f, "{}", err),
}
}
}
impl std::error::Error for SshErrors {}
impl From<ssh_encoding::Error> for SshErrors {
fn from(err: ssh_encoding::Error) -> Self {
SshErrors::Encoding(err)
}
}
impl From<ssh_key::Error> for SshErrors {
fn from(err: ssh_key::Error) -> Self {
SshErrors::Key(err)
}
}
impl From<ssh_encoding::LabelError> for SshErrors {
fn from(err: ssh_encoding::LabelError) -> Self {
SshErrors::KeyLabel(err)
}
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum CipherError {
#[error("Unsupported cipher codec: {0}")]
UnsupportedCodec(multi_codec::Codec),
#[error("Missing cipher codec")]
MissingCodec,
#[error("Missing cipher nonce")]
MissingNonce,
#[error("Invalid cipher nonce length")]
InvalidNonceLen,
#[error("Invalid cipher nonce")]
InvalidNonce,
#[error("Missing cipher key")]
MissingKey,
#[error("Missing cipher key length")]
MissingKeyLen,
#[error("Invalid cipher key")]
InvalidKey,
#[error("Encryption error: {0}")]
EncryptionFailed(String),
#[error("Decryption failed")]
DecryptionFailed,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum KdfError {
#[error(transparent)]
Bcrypt(#[from] bcrypt_pbkdf::Error),
#[error("Unsupported KDF codec: {0}")]
UnsupportedCodec(multi_codec::Codec),
#[error("Missing KDF codec")]
MissingCodec,
#[error("Missing KDF salt")]
MissingSalt,
#[error("Invalid KDF salt length")]
InvalidSaltLen,
#[error("Missing KDF rounds")]
MissingRounds,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum NonceError {
#[error("Missing Nonce codec")]
MissingSigil,
#[error("Missing Nonce bytes")]
MissingBytes,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum SealError {
#[error("Not an encryption key")]
NotEncryptionKey,
#[error("Not a decapsulation key")]
NotDecapsulationKey,
#[error("Not an encapsulation key")]
NotEncapsulationKey,
#[error("Unsupported AEAD codec: {0}")]
UnsupportedAeadCodec(multi_codec::Codec),
#[error("Encapsulation failed: {0}")]
EncapsulationFailed(String),
#[error("Decapsulation failed: {0}")]
DecapsulationFailed(String),
#[error("AEAD seal failed: {0}")]
AeadSealFailed(String),
#[error("AEAD open failed")]
AeadOpenFailed,
#[error("Invalid sealed message format: {0}")]
InvalidFormat(String),
#[error("Key derivation failed: {0}")]
KeyDerivationFailed(String),
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum SignError {
#[error("Not a signing key")]
NotSigningKey,
#[error("Signing failed: {0}")]
SigningFailed(String),
#[error("Missing signature scheme")]
MissingScheme,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum ThresholdError {
#[error(transparent)]
Bls(#[from] blsful::BlsError),
#[error("Invalid threshold ({0}) and limit ({1}). Limit must be greater than threshold")]
InvalidThresholdLimit(usize, usize),
#[error("Not a secret key; only secret keys may be split and combined")]
NotASecretKey,
#[error("Is a key share when we expect a key")]
IsAKeyShare,
#[error("Not enough shares to combine")]
NotEnoughShares,
#[error("Combining secret key shares failed: {0}")]
ShareCombineFailed(String),
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum VerifyError {
#[error("Missing signature")]
MissingSignature,
#[error("Missing message")]
MissingMessage,
#[error("Bad signature: {0}")]
BadSignature(String),
}
impl Error {
pub fn kind(&self) -> &str {
match self {
Self::Attributes(_) => "Attributes",
Self::Conversions(_) => "Conversions",
Self::Cipher(_) => "Cipher",
Self::Kdf(_) => "Kdf",
Self::Nonce(_) => "Nonce",
Self::Seal(_) => "Seal",
Self::Sign(_) => "Sign",
Self::Threshold(_) => "Threshold",
Self::Verify(_) => "Verify",
Self::KeySplit(_) => "KeySplit",
Self::Multibase(_) => "Multibase",
Self::Multicodec(_) => "Multicodec",
Self::Multiutil(_) => "Multiutil",
Self::Multisig(_) => "Multisig",
Self::Multitrait(_) => "Multitrait",
Self::Multihash(_) => "Multihash",
Self::Utf8(_) => "Utf8",
Self::DuplicateAttribute(_) => "DuplicateAttribute",
Self::MissingSigil => "MissingSigil",
Self::UnsupportedAlgorithm(_) => "UnsupportedAlgorithm",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_kind() {
let err = Error::MissingSigil;
assert_eq!(err.kind(), "MissingSigil");
}
#[test]
fn test_error_display() {
let err = Error::MissingSigil;
assert!(!err.to_string().is_empty());
}
#[test]
fn test_error_send_sync() {
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
assert_send::<Error>();
assert_sync::<Error>();
}
}