1#[cfg(target_family = "wasm")]
2use crate::keystore_v_1_0_0;
3
4#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
6pub enum MissingKeyErrorKind {
7 #[error("Consumer Data")]
8 ConsumerData,
9 #[error("MLS KeyPackage")]
10 MlsKeyPackage,
11 #[error("MLS SignatureKeyPair")]
12 MlsSignatureKeyPair,
13 #[error("MLS HpkePrivateKey")]
14 MlsHpkePrivateKey,
15 #[error("MLS EncryptionKeyPair")]
16 MlsEncryptionKeyPair,
17 #[error("MLS Epoch EncryptionKeyPair")]
18 MlsEpochEncryptionKeyPair,
19 #[error("MLS PreSharedKeyBundle")]
20 MlsPskBundle,
21 #[error("MLS CredentialBundle")]
22 MlsCredential,
23 #[error("MLS Buffered Commit")]
24 MlsBufferedCommit,
25 #[error("MLS Persisted Group")]
26 PersistedMlsGroup,
27 #[error("MLS Persisted Pending Group")]
28 MlsPendingGroup,
29 #[error("MLS Pending Messages")]
30 MlsPendingMessages,
31 #[error("End-to-end identity enrollment")]
32 E2eiEnrollment,
33 #[error("OIDC refresh token")]
34 E2eiRefreshToken,
35 #[error("End-to-end identity root trust anchor CA cert")]
36 E2eiAcmeCA,
37 #[error("End-to-end identity intermediate CA cert")]
38 E2eiIntermediateCert,
39 #[error("End-to-end identity CRL")]
40 E2eiCrl,
41 #[cfg(feature = "proteus-keystore")]
42 #[error("Proteus PreKey")]
43 ProteusPrekey,
44 #[cfg(feature = "proteus-keystore")]
45 #[error("Proteus Session")]
46 ProteusSession,
47 #[cfg(feature = "proteus-keystore")]
48 #[error("Proteus Identity")]
49 ProteusIdentity,
50}
51
52#[derive(Debug, thiserror::Error)]
54pub enum CryptoKeystoreError {
55 #[error("The requested {0} is not present in the store")]
56 MissingKeyInStore(#[from] MissingKeyErrorKind),
57 #[error("The given key doesn't contain valid utf-8")]
58 KeyReprError(#[from] std::str::Utf8Error),
59 #[error("A transaction must be in progress to perform this operation.")]
60 MutatingOperationWithoutTransaction,
61 #[error("Cannot perform the operation \"{attempted_operation:?}\" while a transaction is in progress.")]
62 TransactionInProgress { attempted_operation: String },
63 #[error(transparent)]
64 TryFromSliceError(#[from] std::array::TryFromSliceError),
65 #[error("One of the Keystore locks has been poisoned")]
66 LockPoisonError,
67 #[error("The keystore has run out of keypackage bundles!")]
68 OutOfKeyPackageBundles,
69 #[error("Incorrect API usage: {0}")]
70 IncorrectApiUsage(&'static str),
71 #[error("The credential tied to this signature keypair is different from the provided one")]
72 SignatureKeyPairDoesNotBelongToCredential,
73 #[error("A uniqueness constraint has been violated")]
74 AlreadyExists,
75 #[error("The provided buffer is too big to be persisted in the store")]
76 BlobTooBig,
77 #[error("Cannot close as multiple strong refs exist")]
78 CannotClose,
79 #[error(transparent)]
80 KeyStoreValueTransformError(#[from] postcard::Error),
81 #[error(transparent)]
82 IoError(#[from] std::io::Error),
83 #[cfg(not(target_family = "wasm"))]
84 #[error(transparent)]
85 TimeError(#[from] std::time::SystemTimeError),
86 #[cfg(target_family = "wasm")]
87 #[error(transparent)]
88 ChannelError(#[from] std::sync::mpsc::TryRecvError),
89 #[cfg(target_family = "wasm")]
90 #[error("The task has been canceled")]
91 WasmExecutorError,
92 #[cfg(target_family = "wasm")]
93 #[error("aead::Error")]
94 AesGcmError,
95 #[cfg(target_family = "wasm")]
96 #[error("{0}")]
97 SerdeWasmBindgenError(String),
98 #[cfg(not(target_family = "wasm"))]
99 #[error(transparent)]
100 DbError(#[from] rusqlite::Error),
101 #[cfg(not(target_family = "wasm"))]
102 #[error(transparent)]
103 DbMigrationError(#[from] Box<refinery::Error>),
104 #[cfg(test)]
105 #[error(transparent)]
106 MlsKeyPackageIdError(#[from] openmls::prelude::KeyPackageIdError),
107 #[cfg(test)]
108 #[error(transparent)]
109 MlsExtensionError(#[from] openmls::prelude::ExtensionError),
110 #[error("Invalid database key size, expected {expected}, got {actual}")]
111 InvalidDbKeySize { expected: usize, actual: usize },
112 #[cfg(feature = "proteus-keystore")]
113 #[error("Invalid key [{key}] size, expected {expected}, got {actual}")]
114 InvalidKeySize {
115 expected: usize,
116 actual: usize,
117 key: &'static str,
118 },
119 #[cfg(feature = "proteus-keystore")]
120 #[error(transparent)]
121 ParseIntError(#[from] std::num::ParseIntError),
122 #[cfg(feature = "proteus-keystore")]
123 #[error("Could not find a free prekey id")]
124 NoFreePrekeyId,
125 #[error("{0}")]
126 MlsKeyStoreError(String),
127 #[error(transparent)]
128 HexDecodeError(#[from] hex::FromHexError),
129 #[error(transparent)]
130 FromUtf8Error(#[from] std::string::FromUtf8Error),
131 #[cfg(target_os = "ios")]
132 #[error(transparent)]
133 HexSaltDecodeError(hex::FromHexError),
134 #[cfg(target_os = "ios")]
135 #[error(transparent)]
136 SecurityFrameworkError(#[from] security_framework::base::Error),
137 #[cfg(target_family = "wasm")]
138 #[error("{0}")]
139 JsError(String),
140 #[error("Not implemented (and probably never will)")]
141 NotImplemented,
142 #[error("Failed getting current timestamp")]
143 TimestampError,
144 #[error("Could not find {0} in keystore with value {1}")]
145 NotFound(&'static str, String),
146 #[cfg(target_family = "wasm")]
147 #[error(transparent)]
148 SerdeJsonError(#[from] serde_json::Error),
149 #[cfg(target_family = "wasm")]
150 #[error(transparent)]
151 IdbError(#[from] idb::Error),
152 #[cfg(target_family = "wasm")]
153 #[error(transparent)]
154 CryptoKeystoreErrorV1_0_0(keystore_v_1_0_0::CryptoKeystoreError),
155 #[cfg(target_family = "wasm")]
156 #[error(transparent)]
157 IdbErrorCryptoKeystoreV1_0_0(idb::Error),
158 #[cfg(target_family = "wasm")]
159 #[error(transparent)]
160 RexieErrorCryptoKeystoreV1_0_0(rexie::Error),
161 #[cfg(target_family = "wasm")]
162 #[error("Migration from version {0} is not supported")]
163 MigrationNotSupported(u32),
164 #[cfg(target_family = "wasm")]
165 #[error("The migration failed.")]
166 MigrationFailed,
167}
168
169#[cfg(target_family = "wasm")]
170impl From<keystore_v_1_0_0::CryptoKeystoreError> for CryptoKeystoreError {
171 fn from(e: keystore_v_1_0_0::CryptoKeystoreError) -> Self {
172 match e {
173 keystore_v_1_0_0::CryptoKeystoreError::RexieError(rexie_error) => match rexie_error {
174 rexie::Error::IdbError(idb_error) => Self::IdbErrorCryptoKeystoreV1_0_0(idb_error),
175 _ => Self::RexieErrorCryptoKeystoreV1_0_0(rexie_error),
176 },
177 _ => Self::CryptoKeystoreErrorV1_0_0(e),
178 }
179 }
180}
181
182#[cfg(target_family = "wasm")]
183impl From<wasm_bindgen::JsValue> for CryptoKeystoreError {
184 fn from(jsv: wasm_bindgen::JsValue) -> Self {
185 Self::JsError(jsv.as_string().unwrap())
186 }
187}
188
189#[cfg(target_family = "wasm")]
190#[allow(clippy::from_over_into)]
191impl Into<wasm_bindgen::JsValue> for CryptoKeystoreError {
192 fn into(self) -> wasm_bindgen::JsValue {
193 wasm_bindgen::JsValue::from_str(&self.to_string())
194 }
195}
196
197#[cfg(target_family = "wasm")]
198impl From<serde_wasm_bindgen::Error> for CryptoKeystoreError {
199 fn from(jsv: serde_wasm_bindgen::Error) -> Self {
200 Self::SerdeWasmBindgenError(jsv.to_string())
201 }
202}
203
204#[cfg(feature = "proteus-keystore")]
205impl proteus_traits::ProteusErrorCode for CryptoKeystoreError {
206 fn code(&self) -> proteus_traits::ProteusErrorKind {
207 use proteus_traits::ProteusErrorKind;
208 match self {
209 CryptoKeystoreError::MissingKeyInStore(k) => match k {
210 MissingKeyErrorKind::ProteusPrekey => ProteusErrorKind::PreKeyNotFound,
211 MissingKeyErrorKind::ProteusSession => ProteusErrorKind::SessionStateNotFoundForTag,
212 MissingKeyErrorKind::ProteusIdentity => ProteusErrorKind::Unknown,
213 _ => unreachable!(),
214 },
215 CryptoKeystoreError::KeyReprError(_) => ProteusErrorKind::DecodeError,
216 CryptoKeystoreError::TryFromSliceError(_) => ProteusErrorKind::DecodeError,
217 CryptoKeystoreError::LockPoisonError => ProteusErrorKind::OtherSystemError,
218 CryptoKeystoreError::BlobTooBig => ProteusErrorKind::IoError,
219 CryptoKeystoreError::KeyStoreValueTransformError(_) => ProteusErrorKind::DecodeError,
220 CryptoKeystoreError::IoError(_) => ProteusErrorKind::IoError,
221 #[cfg(not(target_family = "wasm"))]
222 CryptoKeystoreError::DbError(_) => ProteusErrorKind::IoError,
223 #[cfg(not(target_family = "wasm"))]
224 CryptoKeystoreError::DbMigrationError(_) => ProteusErrorKind::IoError,
225 CryptoKeystoreError::InvalidKeySize { .. } => ProteusErrorKind::InvalidArrayLen,
226 CryptoKeystoreError::ParseIntError(_) => ProteusErrorKind::DecodeError,
227 CryptoKeystoreError::HexDecodeError(_) => ProteusErrorKind::DecodeError,
228 CryptoKeystoreError::FromUtf8Error(_) => ProteusErrorKind::DecodeError,
229 _ => unreachable!(),
230 }
231 }
232}
233
234pub type CryptoKeystoreResult<T> = Result<T, CryptoKeystoreError>;