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