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