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