use std::array::TryFromSliceError;
#[cfg(feature = "non-fips")]
use cosmian_findex::Error as FindexError;
use cosmian_kmip::{
KmipError, kmip_0::kmip_types::ErrorReason, kmip_1_4::kmip_types::ResultReason,
};
use cosmian_kms_crypto::{CryptoError, reexport::cosmian_crypto_core::CryptoCoreError};
use cosmian_kms_interfaces::InterfaceError;
use cosmian_logger::reexport::tracing;
#[cfg(feature = "non-fips")]
use cosmian_sse_memories::{ADDRESS_LENGTH, Address, RedisMemoryError};
use thiserror::Error;
use crate::DbError::CryptographicError;
#[cfg(feature = "non-fips")]
use crate::stores::LegacyDbError;
#[derive(Error, Debug)]
pub enum DbError {
#[error("Certificate error: {0}")]
Certificate(String),
#[error("REST client connection error: {0}")]
ClientConnectionError(String),
#[error("Conversion Error: {0}")]
ConversionError(#[from] ConversionDbError),
#[error("Cryptographic error: {0}")]
CryptographicError(String),
#[error("Database Error: {0}")]
DatabaseError(String),
#[error("{0}")]
Default(String),
#[error("Inconsistent operation: {0}")]
InconsistentOperation(String),
#[error("Invalid Request: {0}")]
InvalidRequest(String),
#[error("Item not found: {0}")]
ItemNotFound(String),
#[error("{0}: {1}")]
Kmip14Error(ResultReason, String),
#[error("{0}: {1}")]
Kmip21Error(ErrorReason, String),
#[error("Not Supported: {0}")]
NotSupported(String),
#[error("Proteccio error: {0}")]
Proteccio(String),
#[cfg(feature = "non-fips")]
#[error("Redis Error: {0}")]
Redis(#[from] redis::RedisError),
#[error("Route not supported: {0}")]
RouteNotFound(String),
#[error("Unexpected server error: {0}")]
ServerError(String),
#[error("Ext. store error: {0}")]
Store(String),
#[error("Access denied: {0}")]
Unauthorized(String),
#[error("This KMIP server does not yet support protection masks")]
UnsupportedProtectionMasks,
#[error("Invalid URL: {0}")]
UrlError(String),
#[error("Sql error: {0}")]
SqlError(#[from] sqlx::Error),
#[error("Unwrapped cache error: {0}")]
UnwrappedCache(String),
#[cfg(feature = "non-fips")]
#[error("Findex internal error: {0}")]
Findex(#[from] FindexError<Address<ADDRESS_LENGTH>>),
#[cfg(feature = "non-fips")]
#[error("Redis-Memory error: {0}")]
RedisMemory(#[from] RedisMemoryError),
#[error("Crypto-core error: {0}")]
CryptoCoreError(#[from] CryptoCoreError),
#[cfg(feature = "non-fips")]
#[error("Other error: {0}")]
LegacyDatabaseError(#[from] LegacyDbError),
}
#[derive(Error, Debug)]
pub enum ConversionDbError {
#[error("UUID conversion error: {0}")]
Uuid(#[from] uuid::Error),
#[error("UTF-8 conversion error: {0}")]
FromUtf8(#[from] std::string::FromUtf8Error),
#[error("TryFromIntError conversion error: {0}")]
TryFromInt(#[from] std::num::TryFromIntError),
#[error("TryFromSliceError conversion error: {0}")]
TryFromSlice(#[from] TryFromSliceError),
#[error("JSON serialization error: {0}")]
SerdeJson(#[from] serde_json::Error),
#[error("Conversion error: {0}")]
Other(String),
}
impl From<uuid::Error> for DbError {
fn from(e: uuid::Error) -> Self {
Self::ConversionError(ConversionDbError::Uuid(e))
}
}
impl From<std::string::FromUtf8Error> for DbError {
fn from(e: std::string::FromUtf8Error) -> Self {
Self::ConversionError(ConversionDbError::FromUtf8(e))
}
}
impl From<std::num::TryFromIntError> for DbError {
fn from(e: std::num::TryFromIntError) -> Self {
Self::ConversionError(ConversionDbError::TryFromInt(e))
}
}
impl From<TryFromSliceError> for DbError {
fn from(e: TryFromSliceError) -> Self {
Self::ConversionError(ConversionDbError::TryFromSlice(e))
}
}
impl From<String> for ConversionDbError {
fn from(e: String) -> Self {
Self::Other(e)
}
}
impl From<std::io::Error> for DbError {
fn from(e: std::io::Error) -> Self {
Self::ServerError(e.to_string())
}
}
impl From<serde_json::Error> for DbError {
fn from(e: serde_json::Error) -> Self {
Self::InvalidRequest(e.to_string())
}
}
impl From<tracing::dispatcher::SetGlobalDefaultError> for DbError {
fn from(e: tracing::dispatcher::SetGlobalDefaultError) -> Self {
Self::ServerError(e.to_string())
}
}
impl From<InterfaceError> for DbError {
fn from(value: InterfaceError) -> Self {
match value {
InterfaceError::Db(s) => Self::Store(s),
x => Self::Store(x.to_string()),
}
}
}
impl From<CryptoError> for DbError {
fn from(e: CryptoError) -> Self {
match e {
CryptoError::Kmip(s) => Self::Kmip21Error(ErrorReason::Codec_Error, s),
CryptoError::InvalidSize(s)
| CryptoError::InvalidTag(s)
| CryptoError::Derivation(s)
| CryptoError::IndexingSlicing(s) => Self::InvalidRequest(s),
CryptoError::ObjectNotFound(s) => Self::ItemNotFound(s),
CryptoError::ConversionError(e)
| CryptoError::Default(e)
| CryptoError::NotSupported(e)
| CryptoError::OpenSSL(e) => CryptographicError(e),
CryptoError::Io(e) => CryptographicError(e.to_string()),
CryptoError::SerdeJsonError(e) => CryptographicError(e.to_string()),
#[cfg(feature = "non-fips")]
CryptoError::Covercrypt(e) => CryptographicError(e.to_string()),
CryptoError::TryFromSliceError(e) => CryptographicError(e.to_string()),
}
}
}
impl From<KmipError> for DbError {
fn from(e: KmipError) -> Self {
match e {
KmipError::InvalidKmip21Value(r, s)
| KmipError::InvalidKmip21Object(r, s)
| KmipError::Kmip21(r, s) => Self::Kmip21Error(r, s),
KmipError::Kmip21NotSupported(_, s)
| KmipError::NotSupported(s)
| KmipError::Default(s)
| KmipError::InvalidSize(s)
| KmipError::InvalidTag(s)
| KmipError::Derivation(s)
| KmipError::ConversionError(s)
| KmipError::IndexingSlicing(s)
| KmipError::ObjectNotFound(s) => Self::NotSupported(s),
KmipError::TryFromSliceError(e) => {
Self::ConversionError(ConversionDbError::TryFromSlice(e))
}
KmipError::RegexError(s) => Self::Default(s.to_string()),
KmipError::SerdeJsonError(e) => Self::ConversionError(ConversionDbError::SerdeJson(e)),
KmipError::Deserialization(e) | KmipError::Serialization(e) => {
Self::Kmip21Error(ErrorReason::Codec_Error, e)
}
KmipError::DeserializationSize(expected, actual) => Self::Kmip21Error(
ErrorReason::Codec_Error,
format!("Deserialization: invalid size: {actual}, expected: {expected}"),
),
KmipError::InvalidKmip14Value(result_reason, e)
| KmipError::InvalidKmip14Object(result_reason, e)
| KmipError::Kmip14(result_reason, e) => Self::Kmip14Error(result_reason, e),
}
}
}
impl From<DbError> for InterfaceError {
fn from(value: DbError) -> Self {
Self::Db(value.to_string())
}
}