core_crypto_keystore/
lib.rs

1// Wire
2// Copyright (C) 2022 Wire Swiss GmbH
3
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see http://www.gnu.org/licenses/.
16
17#![doc = include_str!("../README.md")]
18#![doc = include_str!("../../docs/KEYSTORE_IMPLEMENTATION.md")]
19
20mod error;
21pub use error::*;
22
23pub mod connection;
24pub use connection::Connection;
25pub mod entities;
26pub mod transaction;
27
28pub(crate) mod mls;
29pub use self::mls::CryptoKeystoreMls;
30pub use self::mls::{deser, ser};
31
32cfg_if::cfg_if! {
33    if #[cfg(feature = "proteus-keystore")] {
34        pub(crate) mod proteus;
35        pub use self::proteus::CryptoKeystoreProteus;
36    }
37}
38#[cfg(target_family = "wasm")]
39pub use connection::keystore_v_1_0_0;
40
41#[cfg(not(target_family = "wasm"))]
42use sha2::{Digest, Sha256};
43
44#[cfg(feature = "dummy-entity")]
45pub mod dummy_entity {
46    use crate::{
47        entities::{Entity, EntityBase, EntityFindParams, StringEntityId},
48        CryptoKeystoreResult, MissingKeyErrorKind,
49    };
50
51    #[derive(Debug, Eq, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
52    pub struct DummyStoreValue;
53    #[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
54    #[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
55    impl EntityBase for DummyStoreValue {
56        type ConnectionType = crate::connection::KeystoreDatabaseConnection;
57        type AutoGeneratedFields = ();
58        const COLLECTION_NAME: &'static str = "";
59
60        fn to_missing_key_err_kind() -> MissingKeyErrorKind {
61            MissingKeyErrorKind::MlsGroup
62        }
63
64        fn to_transaction_entity(self) -> crate::transaction::dynamic_dispatch::Entity {
65            unimplemented!("Not implemented")
66        }
67    }
68
69    #[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
70    #[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
71    impl Entity for DummyStoreValue {
72        fn id_raw(&self) -> &[u8] {
73            b""
74        }
75
76        async fn find_all(
77            _conn: &mut Self::ConnectionType,
78            _params: EntityFindParams,
79        ) -> CryptoKeystoreResult<Vec<Self>> {
80            Ok(vec![])
81        }
82        async fn find_one(
83            _conn: &mut Self::ConnectionType,
84            _id: &StringEntityId,
85        ) -> CryptoKeystoreResult<Option<Self>> {
86            Ok(Some(DummyStoreValue))
87        }
88        async fn find_many(conn: &mut Self::ConnectionType, ids: &[StringEntityId]) -> CryptoKeystoreResult<Vec<Self>> {
89            // Default, inefficient & naive method
90            let mut ret = Vec::with_capacity(ids.len());
91            for id in ids {
92                if let Some(entity) = Self::find_one(conn, id).await? {
93                    ret.push(entity);
94                }
95            }
96
97            Ok(ret)
98        }
99        async fn count(_conn: &mut Self::ConnectionType) -> CryptoKeystoreResult<usize> {
100            Ok(0)
101        }
102
103        #[cfg(target_family = "wasm")]
104        fn encrypt(&mut self, _cipher: &aes_gcm::Aes256Gcm) -> CryptoKeystoreResult<()> {
105            Ok(())
106        }
107        #[cfg(target_family = "wasm")]
108        fn decrypt(&mut self, _cipher: &aes_gcm::Aes256Gcm) -> CryptoKeystoreResult<()> {
109            Ok(())
110        }
111    }
112
113    #[derive(Debug, Clone, PartialEq, Eq)]
114    pub struct DummyValue(Vec<u8>);
115
116    impl From<&str> for DummyValue {
117        fn from(id: &str) -> Self {
118            DummyValue(format!("dummy value {id}").into_bytes())
119        }
120    }
121}
122
123/// Used to calculate ID hashes for some MlsEntities' SQLite tables (not used on wasm).
124/// We only use sha256 on platforms where we use SQLite.
125/// On wasm, we use IndexedDB, a key-value store, via the idb crate.
126#[cfg(not(target_family = "wasm"))]
127pub(crate) fn sha256(data: &[u8]) -> String {
128    let mut hasher = Sha256::new();
129    hasher.update(data);
130    format!("{:x}", hasher.finalize())
131}