core_crypto_keystore/
lib.rs

1#![doc = include_str!("../README.md")]
2#![doc = include_str!("../../docs/KEYSTORE_IMPLEMENTATION.md")]
3
4mod error;
5pub use error::*;
6
7pub mod connection;
8pub use connection::{Connection, DatabaseKey};
9pub mod entities;
10pub mod transaction;
11
12pub(crate) mod mls;
13pub use self::mls::CryptoKeystoreMls;
14pub use self::mls::{deser, ser};
15
16cfg_if::cfg_if! {
17    if #[cfg(feature = "proteus-keystore")] {
18        pub(crate) mod proteus;
19        pub use self::proteus::CryptoKeystoreProteus;
20    }
21}
22#[cfg(target_family = "wasm")]
23pub use connection::keystore_v_1_0_0;
24
25#[cfg(not(target_family = "wasm"))]
26use sha2::{Digest, Sha256};
27
28#[cfg(feature = "dummy-entity")]
29pub mod dummy_entity {
30    use crate::{
31        CryptoKeystoreResult, MissingKeyErrorKind,
32        entities::{Entity, EntityBase, EntityFindParams, StringEntityId},
33    };
34
35    #[derive(Debug, Eq, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
36    pub struct DummyStoreValue;
37    #[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
38    #[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
39    impl EntityBase for DummyStoreValue {
40        type ConnectionType = crate::connection::KeystoreDatabaseConnection;
41        type AutoGeneratedFields = ();
42        const COLLECTION_NAME: &'static str = "";
43
44        fn to_missing_key_err_kind() -> MissingKeyErrorKind {
45            MissingKeyErrorKind::PersistedMlsGroup
46        }
47
48        fn to_transaction_entity(self) -> crate::transaction::dynamic_dispatch::Entity {
49            unimplemented!("Not implemented")
50        }
51    }
52
53    #[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
54    #[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
55    impl Entity for DummyStoreValue {
56        fn id_raw(&self) -> &[u8] {
57            b""
58        }
59
60        async fn find_all(
61            _conn: &mut Self::ConnectionType,
62            _params: EntityFindParams,
63        ) -> CryptoKeystoreResult<Vec<Self>> {
64            Ok(vec![])
65        }
66        async fn find_one(
67            _conn: &mut Self::ConnectionType,
68            _id: &StringEntityId,
69        ) -> CryptoKeystoreResult<Option<Self>> {
70            Ok(Some(DummyStoreValue))
71        }
72        async fn find_many(conn: &mut Self::ConnectionType, ids: &[StringEntityId]) -> CryptoKeystoreResult<Vec<Self>> {
73            // Default, inefficient & naive method
74            let mut ret = Vec::with_capacity(ids.len());
75            for id in ids {
76                if let Some(entity) = Self::find_one(conn, id).await? {
77                    ret.push(entity);
78                }
79            }
80
81            Ok(ret)
82        }
83        async fn count(_conn: &mut Self::ConnectionType) -> CryptoKeystoreResult<usize> {
84            Ok(0)
85        }
86
87        #[cfg(target_family = "wasm")]
88        fn encrypt(&mut self, _cipher: &aes_gcm::Aes256Gcm) -> CryptoKeystoreResult<()> {
89            Ok(())
90        }
91        #[cfg(target_family = "wasm")]
92        fn decrypt(&mut self, _cipher: &aes_gcm::Aes256Gcm) -> CryptoKeystoreResult<()> {
93            Ok(())
94        }
95    }
96
97    #[derive(Debug, Clone, PartialEq, Eq)]
98    pub struct DummyValue(Vec<u8>);
99
100    impl From<&str> for DummyValue {
101        fn from(id: &str) -> Self {
102            DummyValue(format!("dummy value {id}").into_bytes())
103        }
104    }
105}
106
107/// Used to calculate ID hashes for some MlsEntities' SQLite tables (not used on wasm).
108/// We only use sha256 on platforms where we use SQLite.
109/// On wasm, we use IndexedDB, a key-value store, via the idb crate.
110#[cfg(not(target_family = "wasm"))]
111pub(crate) fn sha256(data: &[u8]) -> String {
112    let mut hasher = Sha256::new();
113    hasher.update(data);
114    format!("{:x}", hasher.finalize())
115}