#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("std::io::Error {0}")]
Io(#[from] std::io::Error),
#[error("DatabaseError::RecycleBinDisabled")]
RecycleBinDisabled,
#[error("DatabaseError::RecycleBinAlreadyExists")]
RecycleBinAlreadyExists,
#[error("DatabaseOpenError {0}")]
DatabaseOpenError(#[from] DatabaseOpenError),
#[error("DatabaseSaveError {0}")]
DatabaseSaveError(#[from] DatabaseSaveError),
#[cfg(feature = "totp")]
#[error("DbOtpError {0}")]
DbOtpError(#[from] crate::db::otp::TOTPError),
#[error("OuterCipherConfigError {0}")]
OuterCipherConfigError(#[from] OuterCipherConfigError),
#[error("InnerCipherConfigError {0}")]
InnerCipherConfigError(#[from] InnerCipherConfigError),
#[error("CompressionConfigError {0}")]
CompressionConfigError(#[from] CompressionConfigError),
#[error("KdfConfigError {0}")]
KdfConfigError(#[from] KdfConfigError),
#[error("CryptographyError {0}")]
CryptographyError(#[from] CryptographyError),
#[error("BlockStreamError {0}")]
BlockStreamError(#[from] BlockStreamError),
#[error("VariantDictionaryError {0}")]
VariantDictionaryError(#[from] VariantDictionaryError),
#[error("XmlParseError {0}")]
XmlParseError(#[from] XmlParseError),
#[error("ParseColorError {0}")]
ParseColorError(#[from] ParseColorError),
#[error("ParseIconIdError {}", icon_id)]
ParseIconIdError { icon_id: usize },
#[cfg(feature = "merge")]
#[error("MergeError {0}")]
MergeError(#[from] crate::db::merge::MergeError),
#[error("String error: {0}")]
String(String),
}
impl From<&str> for Error {
fn from(s: &str) -> Self {
Error::String(s.to_string())
}
}
impl From<String> for Error {
fn from(s: String) -> Self {
Error::String(s)
}
}
impl From<&String> for Error {
fn from(s: &String) -> Self {
Error::String(s.clone())
}
}
pub type Result<T, E = Error> = std::result::Result<T, E>;
pub type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;
#[derive(Debug, thiserror::Error)]
pub enum DatabaseOpenError {
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Key(#[from] DatabaseKeyError),
#[error(transparent)]
DatabaseIntegrity(#[from] DatabaseIntegrityError),
#[error("Opening this database version is not supported")]
UnsupportedVersion,
}
#[derive(Debug, thiserror::Error)]
pub enum DatabaseIntegrityError {
#[error("Invalid KDBX identifier")]
InvalidKDBXIdentifier,
#[error("Invalid KDBX version: {}.{}.{}", version, file_major_version, file_minor_version)]
InvalidKDBXVersion {
version: u32,
file_major_version: u32,
file_minor_version: u32,
},
#[error("Invalid header size: {}", size)]
InvalidFixedHeader { size: usize },
#[error("Invalid field length for type {}: {} (expected {})", field_type, field_size, expected_field_size)]
InvalidKDBFieldLength {
field_type: u16,
field_size: u32,
expected_field_size: u32,
},
#[error("Missing group level")]
MissingKDBGroupLevel,
#[error("Invalid KDBX header field ID: {}", field_id)]
InvalidKDBXHeaderFieldID { field_id: u8 },
#[error("Invalid group level {} (current level {})", group_level, current_level)]
InvalidKDBGroupLevel { group_level: u16, current_level: u16 },
#[error("Missing group ID")]
MissingKDBGroupId,
#[error("Invalid group ID {}", group_id)]
InvalidKDBGroupId { group_id: u32 },
#[error("Invalid group field type: {}", field_type)]
InvalidKDBGroupFieldType { field_type: u16 },
#[error("Invalid entry field type: {}", field_type)]
InvalidKDBEntryFieldType { field_type: u16 },
#[error("Incomplete group")]
IncompleteKDBGroup,
#[error("Incomplete entry")]
IncompleteKDBEntry,
#[error("Invalid fixed cipher ID: {}", cid)]
InvalidFixedCipherID { cid: u32 },
#[error("Header hash masmatch")]
HeaderHashMismatch,
#[error("Invalid outer header entry: {}", entry_type)]
InvalidOuterHeaderEntry { entry_type: u8 },
#[error("Incomplete outer header: Missing {}", missing_field)]
IncompleteOuterHeader { missing_field: String },
#[error("Invalid inner header entry: {}", entry_type)]
InvalidInnerHeaderEntry { entry_type: u8 },
#[error("Incomplete outer header: Missing {}", missing_field)]
IncompleteInnerHeader { missing_field: String },
#[error(transparent)]
Cryptography(#[from] CryptographyError),
#[error(transparent)]
Xml(#[from] XmlParseError),
#[error(transparent)]
OuterCipher(#[from] OuterCipherConfigError),
#[error(transparent)]
InnerCipher(#[from] InnerCipherConfigError),
#[error(transparent)]
Compression(#[from] CompressionConfigError),
#[error(transparent)]
BlockStream(#[from] BlockStreamError),
#[error(transparent)]
VariantDictionary(#[from] VariantDictionaryError),
#[error(transparent)]
KdfSettings(#[from] KdfConfigError),
#[error(transparent)]
Io(#[from] std::io::Error),
}
#[derive(Debug, thiserror::Error)]
pub enum DatabaseSaveError {
#[error("Saving this database version is not supported")]
UnsupportedVersion,
#[error("Error while generating XML")]
Xml(#[from] xml::writer::Error),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Key(#[from] DatabaseKeyError),
#[error(transparent)]
Cryptography(#[from] CryptographyError),
#[error(transparent)]
Random(#[from] getrandom::Error),
}
#[derive(Debug, thiserror::Error)]
pub enum DatabaseKeyError {
#[error("Incorrect key")]
IncorrectKey,
#[error(transparent)]
Cryptography(#[from] CryptographyError),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Xml(#[from] xml::reader::Error),
#[error("Could not obtain a key from the keyfile")]
InvalidKeyFile,
#[cfg(feature = "challenge_response")]
#[error("Error with the challenge-response key: {0}")]
ChallengeResponseKeyError(String),
}
#[derive(Debug, thiserror::Error)]
pub enum OuterCipherConfigError {
#[error(transparent)]
Cryptography(#[from] CryptographyError),
#[error("Invalid outer cipher ID: {:?}", cid)]
InvalidOuterCipherID { cid: Vec<u8> },
}
#[derive(Debug, thiserror::Error)]
pub enum InnerCipherConfigError {
#[error(transparent)]
Cryptography(#[from] CryptographyError),
#[error("Invalid inner cipher ID: {}", cid)]
InvalidInnerCipherID { cid: u32 },
}
#[derive(Debug, thiserror::Error)]
pub enum CompressionConfigError {
#[error("Invalid compression algorithm: {}", cid)]
InvalidCompressionSuite { cid: u32 },
}
#[derive(Debug, thiserror::Error)]
pub enum KdfConfigError {
#[error("Invalid KDF version: {}", version)]
InvalidKDFVersion { version: u32 },
#[error("Invalid KDF UUID: {:?}", uuid)]
InvalidKDFUUID { uuid: Vec<u8> },
#[error(transparent)]
VariantDictionary(#[from] VariantDictionaryError),
}
#[derive(Debug, thiserror::Error)]
pub enum CryptographyError {
#[error(transparent)]
InvalidLength(#[from] cipher::InvalidLength),
#[error(transparent)]
Unpadding(#[from] cipher::block_padding::UnpadError),
#[error(transparent)]
Padding(#[from] cipher::inout::PadError),
#[error(transparent)]
Argon2(#[from] argon2::Error),
}
#[derive(Debug, thiserror::Error)]
pub enum BlockStreamError {
#[error(transparent)]
Cryptography(#[from] CryptographyError),
#[error("Block hash mismatch for block {}", block_index)]
BlockHashMismatch { block_index: u64 },
}
#[derive(Debug, thiserror::Error)]
pub enum VariantDictionaryError {
#[error("Invalid variant dictionary version: {}", version)]
InvalidVersion { version: u16 },
#[error("Invalid value type: {}", value_type)]
InvalidValueType { value_type: u8 },
#[error("Missing key: {}", key)]
MissingKey { key: String },
#[error("Mistyped value: {}", key)]
Mistyped { key: String },
#[error("VariantDictionary did not end with null byte, when it should")]
NotTerminated,
}
#[derive(Debug, thiserror::Error)]
pub enum XmlParseError {
#[error(transparent)]
Xml(#[from] xml::reader::Error),
#[error(transparent)]
Base64(#[from] base64::DecodeError),
#[error(transparent)]
TimestampFormat(#[from] chrono::ParseError),
#[error(transparent)]
IntFormat(#[from] std::num::ParseIntError),
#[error(transparent)]
BoolFormat(#[from] std::str::ParseBoolError),
#[error(transparent)]
Uuid(#[from] uuid::Error),
#[error(transparent)]
Color(#[from] ParseColorError),
#[error(transparent)]
Cryptography(#[from] CryptographyError),
#[error("Decompression error: {}", _0)]
Compression(#[source] std::io::Error),
#[error("Bad XML event: expected {}, got {:?}", expected, event)]
BadEvent {
expected: &'static str,
event: crate::xml_db::parse::SimpleXmlEvent,
},
#[error("Unexpected end of XML document")]
Eof,
}
#[derive(Debug, thiserror::Error)]
#[error("Cannot parse color: '{}'", _0)]
pub struct ParseColorError(pub String);
mod conversions {
use super::{
BlockStreamError, CompressionConfigError, CryptographyError, DatabaseIntegrityError, DatabaseOpenError, InnerCipherConfigError,
KdfConfigError, OuterCipherConfigError, VariantDictionaryError, XmlParseError,
};
impl From<CryptographyError> for DatabaseOpenError {
fn from(e: CryptographyError) -> Self {
DatabaseIntegrityError::from(e).into()
}
}
impl From<BlockStreamError> for DatabaseOpenError {
fn from(e: BlockStreamError) -> Self {
DatabaseIntegrityError::from(e).into()
}
}
impl From<XmlParseError> for DatabaseOpenError {
fn from(e: XmlParseError) -> Self {
DatabaseIntegrityError::from(e).into()
}
}
impl From<InnerCipherConfigError> for DatabaseOpenError {
fn from(e: InnerCipherConfigError) -> Self {
DatabaseIntegrityError::from(e).into()
}
}
impl From<OuterCipherConfigError> for DatabaseOpenError {
fn from(e: OuterCipherConfigError) -> Self {
DatabaseIntegrityError::from(e).into()
}
}
impl From<KdfConfigError> for DatabaseOpenError {
fn from(e: KdfConfigError) -> Self {
DatabaseIntegrityError::from(e).into()
}
}
impl From<VariantDictionaryError> for DatabaseOpenError {
fn from(e: VariantDictionaryError) -> Self {
DatabaseIntegrityError::from(e).into()
}
}
impl From<CompressionConfigError> for DatabaseOpenError {
fn from(e: CompressionConfigError) -> Self {
DatabaseIntegrityError::from(e).into()
}
}
}