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