core_crypto_keystore/transaction/
mls.rs1use openmls_traits::key_store::{MlsEntity, MlsEntityId};
2use rusqlite::Connection;
3
4use crate::{
5 CryptoKeystoreError, Transaction, deser,
6 entities::{
7 PersistedMlsGroup, StoredEncryptionKeyPair, StoredEpochEncryptionKeypair, StoredEpochEncryptionKeypairPkRef,
8 StoredHpkePrivateKey, StoredKeyPackage, StoredPskBundle,
9 },
10 ser,
11 traits::{EntityDatabaseMutation as _, EntityDeleteBorrowed as _, EntityGetBorrowed as _},
12};
13
14pub(crate) fn read_mls_entity<V: MlsEntity>(conn: &Connection, id: &[u8]) -> Option<V> {
16 if id.is_empty() {
17 return None;
18 }
19
20 match V::ID {
21 MlsEntityId::GroupState => {
22 let v = PersistedMlsGroup::get_borrowed(conn, id).ok().flatten()?;
23 deser(&v.state).ok()
24 }
25 MlsEntityId::SignatureKeyPair => {
26 unimplemented!("Don't use this API to load a signature key pair. Load a StoredCredential instead.")
27 }
28 MlsEntityId::KeyPackage => {
29 let v = StoredKeyPackage::get_borrowed(conn, id).ok().flatten()?;
30 deser(&v.key_package).ok()
31 }
32 MlsEntityId::HpkePrivateKey => {
33 let v = StoredHpkePrivateKey::get_borrowed(conn, id).ok().flatten()?;
34 deser(&v.sk).ok()
35 }
36 MlsEntityId::PskBundle => {
37 let v = StoredPskBundle::get_borrowed(conn, id).ok().flatten()?;
38 deser(&v.psk).ok()
39 }
40 MlsEntityId::EncryptionKeyPair => {
41 let v = StoredEncryptionKeyPair::get_borrowed(conn, id).ok().flatten()?;
42 deser(&v.sk).ok()
43 }
44 MlsEntityId::EpochEncryptionKeyPair => {
45 let kp_ref = StoredEpochEncryptionKeypairPkRef::parse_bytes(id).ok()?;
46 let v = StoredEpochEncryptionKeypair::get_borrowed(conn, kp_ref)
47 .ok()
48 .flatten()?;
49 deser(&v.keypairs).ok()
50 }
51 }
52}
53
54#[cfg_attr(target_os = "unknown", async_trait::async_trait(?Send))]
55#[cfg_attr(not(target_os = "unknown"), async_trait::async_trait)]
56impl openmls_traits::key_store::OpenMlsKeyStore for Transaction {
57 type Error = CryptoKeystoreError;
58
59 async fn store<V: MlsEntity + Sync>(&self, id: &[u8], value: &V) -> Result<(), Self::Error>
60 where
61 Self: Sized,
62 {
63 if id.is_empty() {
64 return Err(CryptoKeystoreError::MlsKeyStoreError(
65 "The provided key is empty".into(),
66 ));
67 }
68
69 let data = ser(value)?;
70
71 match V::ID {
72 MlsEntityId::GroupState => {
73 return Err(CryptoKeystoreError::IncorrectApiUsage(
74 "Groups must not be saved using OpenMLS's APIs. You should use the keystore's provided methods",
75 ));
76 }
77 MlsEntityId::SignatureKeyPair => {
78 return Err(CryptoKeystoreError::IncorrectApiUsage(
79 "Signature keys must not be saved using OpenMLS's APIs. Save a credential via the keystore API
80 instead.",
81 ));
82 }
83 MlsEntityId::KeyPackage => {
84 StoredKeyPackage {
85 key_package_ref: id.into(),
86 key_package: data,
87 }
88 .save(self)?;
89 }
90 MlsEntityId::HpkePrivateKey => {
91 StoredHpkePrivateKey {
92 pk: id.into(),
93 sk: data,
94 }
95 .save(self)?;
96 }
97 MlsEntityId::PskBundle => {
98 StoredPskBundle {
99 psk_id: id.into(),
100 psk: data,
101 }
102 .save(self)?;
103 }
104 MlsEntityId::EncryptionKeyPair => {
105 StoredEncryptionKeyPair {
106 pk: id.into(),
107 sk: data,
108 }
109 .save(self)?;
110 }
111 MlsEntityId::EpochEncryptionKeyPair => {
112 let StoredEpochEncryptionKeypairPkRef {
113 conversation_id,
114 own_leaf_idx,
115 epoch,
116 } = StoredEpochEncryptionKeypairPkRef::parse_bytes(id)?;
117 StoredEpochEncryptionKeypair {
118 conversation_id: conversation_id.bytes().into(),
119 own_leaf_idx,
120 epoch,
121 keypairs: data,
122 }
123 .save(self)?;
124 }
125 }
126
127 Ok(())
128 }
129
130 async fn read<V: MlsEntity>(&self, id: &[u8]) -> Option<V>
131 where
132 Self: Sized,
133 {
134 let conn = self.conn().ok()?;
135 read_mls_entity(&conn, id)
136 }
137
138 async fn delete<V: MlsEntity>(&self, id: &[u8]) -> Result<(), Self::Error> {
139 match V::ID {
140 MlsEntityId::SignatureKeyPair => unimplemented!(
141 "Deleting a signature key pair should not be done through this API, any keypair should be deleted via
142 deleting a credential."
143 ),
144 MlsEntityId::GroupState => PersistedMlsGroup::delete_borrowed(self, id)?,
145 MlsEntityId::HpkePrivateKey => StoredHpkePrivateKey::delete_borrowed(self, id)?,
146 MlsEntityId::KeyPackage => StoredKeyPackage::delete_borrowed(self, id)?,
147 MlsEntityId::PskBundle => StoredPskBundle::delete_borrowed(self, id)?,
148 MlsEntityId::EncryptionKeyPair => StoredEncryptionKeyPair::delete_borrowed(self, id)?,
149 MlsEntityId::EpochEncryptionKeyPair => {
150 let kp_ref = StoredEpochEncryptionKeypairPkRef::parse_bytes(id)?;
151 StoredEpochEncryptionKeypair::delete_borrowed(self, kp_ref)?
152 }
153 };
154
155 Ok(())
156 }
157}