Skip to main content

core_crypto_keystore/
error.rs

1/// Error type to represent various errors that can happen in the KeyStore
2#[derive(Debug, thiserror::Error)]
3pub enum CryptoKeystoreError {
4    #[error("The given key doesn't contain valid utf-8")]
5    KeyReprError(#[from] std::str::Utf8Error),
6    #[error("A transaction must be in progress to perform this operation.")]
7    MutatingOperationWithoutTransaction,
8    #[error("cannot open a new transaction as there exists another transaction currently in progress")]
9    TransactionInProgress,
10    #[error(transparent)]
11    TryFromSliceError(#[from] std::array::TryFromSliceError),
12    #[error("One of the Keystore locks has been poisoned")]
13    LockPoisonError,
14    #[error("The keystore has run out of keypackage bundles!")]
15    OutOfKeyPackageBundles,
16    #[error("Incorrect API usage: {0}")]
17    IncorrectApiUsage(&'static str),
18    #[error("The credential tied to this signature keypair is different from the provided one")]
19    SignatureKeyPairDoesNotBelongToCredential,
20    #[error("The uniqueness constraint has been violated for {0}")]
21    AlreadyExists(&'static str),
22    #[error("The provided buffer is too big to be persisted in the store")]
23    BlobTooBig,
24    #[error("This database connection has been closed")]
25    Closed,
26    #[error(transparent)]
27    KeyStoreValueTransformError(#[from] postcard::Error),
28    #[error(transparent)]
29    IoError(#[from] std::io::Error),
30    #[cfg(not(target_os = "unknown"))]
31    #[error(transparent)]
32    TimeError(#[from] std::time::SystemTimeError),
33    #[error("aead::Error: {0}")]
34    AesGcmError(&'static str),
35    #[cfg(target_os = "unknown")]
36    #[error("{0}")]
37    SerdeWasmBindgenError(String),
38    #[error(transparent)]
39    DbError(#[from] rusqlite::Error),
40    #[error(transparent)]
41    DbMigrationError(#[from] Box<refinery::Error>),
42    #[cfg(test)]
43    #[error(transparent)]
44    MlsKeyPackageIdError(#[from] openmls::prelude::KeyPackageIdError),
45    #[cfg(test)]
46    #[error(transparent)]
47    MlsExtensionError(#[from] openmls::prelude::ExtensionError),
48    #[error("Invalid database key size, expected {expected}, got {actual}")]
49    InvalidDbKeySize { expected: usize, actual: usize },
50    #[cfg(feature = "proteus-keystore")]
51    #[error("Invalid key [{key}] size, expected {expected}, got {actual}")]
52    InvalidKeySize {
53        expected: usize,
54        actual: usize,
55        key: &'static str,
56    },
57    #[cfg(feature = "proteus-keystore")]
58    #[error(transparent)]
59    ParseIntError(#[from] std::num::ParseIntError),
60    #[cfg(feature = "proteus-keystore")]
61    #[error("Could not find a free prekey id")]
62    NoFreePrekeyId,
63    #[error("{0}")]
64    MlsKeyStoreError(String),
65    #[error(transparent)]
66    HexDecodeError(#[from] hex::FromHexError),
67    #[error(transparent)]
68    FromUtf8Error(#[from] std::string::FromUtf8Error),
69    #[cfg(target_os = "ios")]
70    #[error(transparent)]
71    HexSaltDecodeError(hex::FromHexError),
72    #[cfg(target_os = "ios")]
73    #[error(transparent)]
74    SecurityFrameworkError(#[from] security_framework::base::Error),
75    #[error("Not implemented (and probably never will)")]
76    NotImplemented,
77    #[error("Failed getting current timestamp")]
78    TimestampError,
79    #[error("Could not find {0} in keystore with value {1}")]
80    NotFound(&'static str, String),
81    #[error(transparent)]
82    SerdeJsonError(#[from] serde_json::Error),
83    #[cfg(target_os = "unknown")]
84    #[error(transparent)]
85    IdbError(#[from] idb::Error),
86    #[cfg(target_os = "unknown")]
87    #[error("Migration from version {0} is not supported")]
88    MigrationNotSupported(u32),
89    #[error("The migration failed: {0}")]
90    MigrationFailed(String),
91    #[error("the provided bytes could not be interpreted as the primary key of {0}")]
92    InvalidPrimaryKeyBytes(&'static str),
93    #[error("the table {0} is unknown")]
94    UnknownTable(&'static str),
95    #[cfg(target_os = "unknown")]
96    #[error("{context}")]
97    RelaxedIdbError {
98        context: &'static str,
99        #[source]
100        error: sqlite_wasm_vfs::relaxed_idb::RelaxedIdbError,
101    },
102}
103
104impl CryptoKeystoreError {
105    #[cfg(target_os = "unknown")]
106    pub(crate) fn relaxed_idb(
107        context: &'static str,
108    ) -> impl FnOnce(sqlite_wasm_vfs::relaxed_idb::RelaxedIdbError) -> Self {
109        move |error| Self::RelaxedIdbError { context, error }
110    }
111}
112
113#[cfg(target_os = "unknown")]
114#[allow(clippy::from_over_into)]
115impl Into<wasm_bindgen::JsValue> for CryptoKeystoreError {
116    fn into(self) -> wasm_bindgen::JsValue {
117        wasm_bindgen::JsValue::from_str(&self.to_string())
118    }
119}
120
121#[cfg(target_os = "unknown")]
122impl From<serde_wasm_bindgen::Error> for CryptoKeystoreError {
123    fn from(jsv: serde_wasm_bindgen::Error) -> Self {
124        Self::SerdeWasmBindgenError(jsv.to_string())
125    }
126}
127
128#[cfg(feature = "proteus-keystore")]
129impl proteus_traits::ProteusErrorCode for CryptoKeystoreError {
130    fn code(&self) -> proteus_traits::ProteusErrorKind {
131        use proteus_traits::ProteusErrorKind;
132        match self {
133            CryptoKeystoreError::KeyReprError(_) => ProteusErrorKind::DecodeError,
134            CryptoKeystoreError::TryFromSliceError(_) => ProteusErrorKind::DecodeError,
135            CryptoKeystoreError::LockPoisonError => ProteusErrorKind::OtherSystemError,
136            CryptoKeystoreError::BlobTooBig => ProteusErrorKind::IoError,
137            CryptoKeystoreError::KeyStoreValueTransformError(_) => ProteusErrorKind::DecodeError,
138            CryptoKeystoreError::IoError(_) => ProteusErrorKind::IoError,
139            CryptoKeystoreError::DbError(_) => ProteusErrorKind::IoError,
140            CryptoKeystoreError::DbMigrationError(_) => ProteusErrorKind::IoError,
141            CryptoKeystoreError::InvalidKeySize { .. } => ProteusErrorKind::InvalidArrayLen,
142            CryptoKeystoreError::ParseIntError(_) => ProteusErrorKind::DecodeError,
143            CryptoKeystoreError::HexDecodeError(_) => ProteusErrorKind::DecodeError,
144            CryptoKeystoreError::FromUtf8Error(_) => ProteusErrorKind::DecodeError,
145            _ => unreachable!(),
146        }
147    }
148}
149
150/// A specialized Result for the KeyStore functions
151pub type CryptoKeystoreResult<T> = Result<T, CryptoKeystoreError>;