core_crypto_keystore/entities/
proteus.rs

1use zeroize::Zeroize;
2
3use crate::connection::FetchFromDatabase;
4
5#[derive(core_crypto_macros::Debug, Clone, Zeroize, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
6#[zeroize(drop)]
7#[sensitive]
8pub struct ProteusIdentity {
9    pub sk: Vec<u8>,
10    pub pk: Vec<u8>,
11}
12
13impl ProteusIdentity {
14    pub const SK_KEY_SIZE: usize = 64;
15    pub const PK_KEY_SIZE: usize = 32;
16    pub const ID: &[u8; 1] = b"1";
17
18    pub fn sk_raw(&self) -> zeroize::Zeroizing<[u8; Self::SK_KEY_SIZE]> {
19        let mut slice = zeroize::Zeroizing::new([0u8; Self::SK_KEY_SIZE]);
20        debug_assert_eq!(self.sk.len(), Self::SK_KEY_SIZE);
21        slice.copy_from_slice(&self.sk[..Self::SK_KEY_SIZE]);
22        slice
23    }
24
25    pub fn pk_raw(&self) -> zeroize::Zeroizing<[u8; Self::PK_KEY_SIZE]> {
26        let mut slice = zeroize::Zeroizing::new([0u8; Self::PK_KEY_SIZE]);
27        debug_assert_eq!(self.pk.len(), Self::PK_KEY_SIZE);
28        slice.copy_from_slice(&self.pk[..Self::PK_KEY_SIZE]);
29        slice
30    }
31}
32
33#[derive(core_crypto_macros::Debug, Clone, Zeroize, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
34#[zeroize(drop)]
35pub struct ProteusPrekey {
36    pub id: u16,
37    id_bytes: Vec<u8>,
38    #[sensitive]
39    pub prekey: Vec<u8>,
40}
41
42impl ProteusPrekey {
43    pub fn from_raw(id: u16, prekey: Vec<u8>) -> Self {
44        Self {
45            id_bytes: id.to_le_bytes().into(),
46            id,
47            prekey,
48        }
49    }
50
51    pub fn id_bytes(&self) -> &[u8] {
52        &self.id_bytes
53    }
54
55    pub fn id_from_slice(slice: &[u8]) -> u16 {
56        if slice.len() < 2 {
57            panic!("Oops, Proteus Prekey id slice is too small!");
58        }
59
60        let mut id_buf = [0u8; 2];
61        id_buf.copy_from_slice(&slice[..2]);
62        let id: u16 = u16::from_le_bytes(id_buf);
63        id
64    }
65
66    pub fn set_id(&mut self, id: u16) {
67        self.id = id;
68        self.id_bytes = self.id.to_le_bytes().into();
69    }
70
71    pub async fn get_free_id(conn: &crate::Database) -> crate::CryptoKeystoreResult<u16> {
72        let mut id = 1u16;
73        let limit = u16::MAX;
74        while id <= limit {
75            if id == limit {
76                return Err(crate::CryptoKeystoreError::NoFreePrekeyId);
77            }
78            if conn.find::<Self>(&id.to_le_bytes()).await?.is_none() {
79                break;
80            }
81            id += 1;
82        }
83
84        Ok(id)
85    }
86}
87
88#[derive(
89    core_crypto_macros::Debug,
90    Clone,
91    Zeroize,
92    PartialEq,
93    Eq,
94    core_crypto_macros::Entity,
95    serde::Serialize,
96    serde::Deserialize,
97)]
98#[zeroize(drop)]
99pub struct ProteusSession {
100    pub id: String,
101    pub session: Vec<u8>,
102}