1use crate::connection::TransactionWrapper;
5use crate::entities::{
6 ConsumerData, E2eiAcmeCA, E2eiCrl, E2eiEnrollment, E2eiIntermediateCert, E2eiRefreshToken, EntityBase,
7 EntityTransactionExt, MlsBufferedCommit, MlsCredential, MlsEncryptionKeyPair, MlsEpochEncryptionKeyPair,
8 MlsHpkePrivateKey, MlsKeyPackage, MlsPendingMessage, MlsPskBundle, MlsSignatureKeyPair, PersistedMlsGroup,
9 PersistedMlsPendingGroup, StringEntityId, UniqueEntity,
10};
11#[cfg(feature = "proteus-keystore")]
12use crate::entities::{ProteusIdentity, ProteusPrekey, ProteusSession};
13use crate::{CryptoKeystoreError, CryptoKeystoreResult};
14
15#[derive(Debug)]
16pub enum Entity {
17 ConsumerData(ConsumerData),
18 SignatureKeyPair(MlsSignatureKeyPair),
19 HpkePrivateKey(MlsHpkePrivateKey),
20 MlsKeyPackage(MlsKeyPackage),
21 PskBundle(MlsPskBundle),
22 EncryptionKeyPair(MlsEncryptionKeyPair),
23 MlsEpochEncryptionKeyPair(MlsEpochEncryptionKeyPair),
24 MlsCredential(MlsCredential),
25 MlsBufferedCommit(MlsBufferedCommit),
26 PersistedMlsGroup(PersistedMlsGroup),
27 PersistedMlsPendingGroup(PersistedMlsPendingGroup),
28 MlsPendingMessage(MlsPendingMessage),
29 E2eiEnrollment(E2eiEnrollment),
30 E2eiRefreshToken(E2eiRefreshToken),
31 E2eiAcmeCA(E2eiAcmeCA),
32 E2eiIntermediateCert(E2eiIntermediateCert),
33 E2eiCrl(E2eiCrl),
34 #[cfg(feature = "proteus-keystore")]
35 ProteusIdentity(ProteusIdentity),
36 #[cfg(feature = "proteus-keystore")]
37 ProteusPrekey(ProteusPrekey),
38 #[cfg(feature = "proteus-keystore")]
39 ProteusSession(ProteusSession),
40}
41
42#[derive(Debug, Clone, PartialEq)]
43pub enum EntityId {
44 SignatureKeyPair(Vec<u8>),
45 HpkePrivateKey(Vec<u8>),
46 KeyPackage(Vec<u8>),
47 PskBundle(Vec<u8>),
48 EncryptionKeyPair(Vec<u8>),
49 EpochEncryptionKeyPair(Vec<u8>),
50 MlsCredential(Vec<u8>),
51 MlsBufferedCommit(Vec<u8>),
52 PersistedMlsGroup(Vec<u8>),
53 PersistedMlsPendingGroup(Vec<u8>),
54 MlsPendingMessage(Vec<u8>),
55 E2eiEnrollment(Vec<u8>),
56 E2eiRefreshToken(Vec<u8>),
57 E2eiAcmeCA(Vec<u8>),
58 E2eiIntermediateCert(Vec<u8>),
59 E2eiCrl(Vec<u8>),
60 #[cfg(feature = "proteus-keystore")]
61 ProteusIdentity(Vec<u8>),
62 #[cfg(feature = "proteus-keystore")]
63 ProteusPrekey(Vec<u8>),
64 #[cfg(feature = "proteus-keystore")]
65 ProteusSession(Vec<u8>),
66}
67
68impl EntityId {
69 fn as_id(&self) -> StringEntityId<'_> {
70 match self {
71 EntityId::SignatureKeyPair(vec) => vec.as_slice().into(),
72 EntityId::HpkePrivateKey(vec) => vec.as_slice().into(),
73 EntityId::KeyPackage(vec) => vec.as_slice().into(),
74 EntityId::PskBundle(vec) => vec.as_slice().into(),
75 EntityId::EncryptionKeyPair(vec) => vec.as_slice().into(),
76 EntityId::EpochEncryptionKeyPair(vec) => vec.as_slice().into(),
77 EntityId::MlsCredential(vec) => vec.as_slice().into(),
78 EntityId::MlsBufferedCommit(vec) => vec.as_slice().into(),
79 EntityId::PersistedMlsGroup(vec) => vec.as_slice().into(),
80 EntityId::PersistedMlsPendingGroup(vec) => vec.as_slice().into(),
81 EntityId::MlsPendingMessage(vec) => vec.as_slice().into(),
82 EntityId::E2eiEnrollment(vec) => vec.as_slice().into(),
83 EntityId::E2eiRefreshToken(vec) => vec.as_slice().into(),
84 EntityId::E2eiAcmeCA(vec) => vec.as_slice().into(),
85 EntityId::E2eiIntermediateCert(vec) => vec.as_slice().into(),
86 EntityId::E2eiCrl(vec) => vec.as_slice().into(),
87 #[cfg(feature = "proteus-keystore")]
88 EntityId::ProteusIdentity(vec) => vec.as_slice().into(),
89 #[cfg(feature = "proteus-keystore")]
90 EntityId::ProteusSession(id) => id.as_slice().into(),
91 #[cfg(feature = "proteus-keystore")]
92 EntityId::ProteusPrekey(vec) => vec.as_slice().into(),
93 }
94 }
95
96 pub(crate) fn from_collection_name(entity_id: &'static str, id: &[u8]) -> CryptoKeystoreResult<Self> {
97 match entity_id {
98 MlsSignatureKeyPair::COLLECTION_NAME => Ok(Self::SignatureKeyPair(id.into())),
99 MlsHpkePrivateKey::COLLECTION_NAME => Ok(Self::HpkePrivateKey(id.into())),
100 MlsKeyPackage::COLLECTION_NAME => Ok(Self::KeyPackage(id.into())),
101 MlsPskBundle::COLLECTION_NAME => Ok(Self::PskBundle(id.into())),
102 MlsEncryptionKeyPair::COLLECTION_NAME => Ok(Self::EncryptionKeyPair(id.into())),
103 MlsEpochEncryptionKeyPair::COLLECTION_NAME => Ok(Self::EpochEncryptionKeyPair(id.into())),
104 MlsBufferedCommit::COLLECTION_NAME => Ok(Self::MlsBufferedCommit(id.into())),
105 PersistedMlsGroup::COLLECTION_NAME => Ok(Self::PersistedMlsGroup(id.into())),
106 PersistedMlsPendingGroup::COLLECTION_NAME => Ok(Self::PersistedMlsPendingGroup(id.into())),
107 MlsCredential::COLLECTION_NAME => Ok(Self::MlsCredential(id.into())),
108 MlsPendingMessage::COLLECTION_NAME => Ok(Self::MlsPendingMessage(id.into())),
109 E2eiEnrollment::COLLECTION_NAME => Ok(Self::E2eiEnrollment(id.into())),
110 E2eiCrl::COLLECTION_NAME => Ok(Self::E2eiCrl(id.into())),
111 E2eiAcmeCA::COLLECTION_NAME => Ok(Self::E2eiAcmeCA(id.into())),
112 E2eiRefreshToken::COLLECTION_NAME => Ok(Self::E2eiRefreshToken(id.into())),
113 E2eiIntermediateCert::COLLECTION_NAME => Ok(Self::E2eiIntermediateCert(id.into())),
114 #[cfg(feature = "proteus-keystore")]
115 ProteusIdentity::COLLECTION_NAME => Ok(Self::ProteusIdentity(id.into())),
116 #[cfg(feature = "proteus-keystore")]
117 ProteusPrekey::COLLECTION_NAME => Ok(Self::ProteusPrekey(id.into())),
118 #[cfg(feature = "proteus-keystore")]
119 ProteusSession::COLLECTION_NAME => Ok(Self::ProteusSession(id.into())),
120 _ => Err(CryptoKeystoreError::NotImplemented),
121 }
122 }
123
124 pub(crate) fn collection_name(&self) -> &'static str {
125 match self {
126 EntityId::SignatureKeyPair(_) => MlsSignatureKeyPair::COLLECTION_NAME,
127 EntityId::KeyPackage(_) => MlsKeyPackage::COLLECTION_NAME,
128 EntityId::PskBundle(_) => MlsPskBundle::COLLECTION_NAME,
129 EntityId::EncryptionKeyPair(_) => MlsEncryptionKeyPair::COLLECTION_NAME,
130 EntityId::EpochEncryptionKeyPair(_) => MlsEpochEncryptionKeyPair::COLLECTION_NAME,
131 EntityId::MlsCredential(_) => MlsCredential::COLLECTION_NAME,
132 EntityId::MlsBufferedCommit(_) => MlsBufferedCommit::COLLECTION_NAME,
133 EntityId::PersistedMlsGroup(_) => PersistedMlsGroup::COLLECTION_NAME,
134 EntityId::PersistedMlsPendingGroup(_) => PersistedMlsPendingGroup::COLLECTION_NAME,
135 EntityId::MlsPendingMessage(_) => MlsPendingMessage::COLLECTION_NAME,
136 EntityId::E2eiEnrollment(_) => E2eiEnrollment::COLLECTION_NAME,
137 EntityId::E2eiRefreshToken(_) => E2eiRefreshToken::COLLECTION_NAME,
138 EntityId::E2eiAcmeCA(_) => E2eiAcmeCA::COLLECTION_NAME,
139 EntityId::E2eiIntermediateCert(_) => E2eiIntermediateCert::COLLECTION_NAME,
140 EntityId::E2eiCrl(_) => E2eiCrl::COLLECTION_NAME,
141 #[cfg(feature = "proteus-keystore")]
142 EntityId::ProteusIdentity(_) => ProteusIdentity::COLLECTION_NAME,
143 #[cfg(feature = "proteus-keystore")]
144 EntityId::ProteusPrekey(_) => ProteusPrekey::COLLECTION_NAME,
145 #[cfg(feature = "proteus-keystore")]
146 EntityId::ProteusSession(_) => ProteusSession::COLLECTION_NAME,
147 EntityId::HpkePrivateKey(_) => MlsHpkePrivateKey::COLLECTION_NAME,
148 }
149 }
150}
151
152pub async fn execute_save(tx: &TransactionWrapper<'_>, entity: &Entity) -> CryptoKeystoreResult<()> {
153 match entity {
154 Entity::ConsumerData(consumer_data) => consumer_data.replace(tx).await,
155 Entity::SignatureKeyPair(mls_signature_key_pair) => mls_signature_key_pair.save(tx).await,
156 Entity::HpkePrivateKey(mls_hpke_private_key) => mls_hpke_private_key.save(tx).await,
157 Entity::MlsKeyPackage(mls_key_package) => mls_key_package.save(tx).await,
158 Entity::PskBundle(mls_psk_bundle) => mls_psk_bundle.save(tx).await,
159 Entity::EncryptionKeyPair(mls_encryption_key_pair) => mls_encryption_key_pair.save(tx).await,
160 Entity::MlsEpochEncryptionKeyPair(mls_epoch_encryption_key_pair) => {
161 mls_epoch_encryption_key_pair.save(tx).await
162 }
163 Entity::MlsCredential(mls_credential) => mls_credential.save(tx).await,
164 Entity::MlsBufferedCommit(mls_pending_commit) => mls_pending_commit.save(tx).await,
165 Entity::PersistedMlsGroup(persisted_mls_group) => persisted_mls_group.save(tx).await,
166 Entity::PersistedMlsPendingGroup(persisted_mls_pending_group) => persisted_mls_pending_group.save(tx).await,
167 Entity::MlsPendingMessage(mls_pending_message) => mls_pending_message.save(tx).await,
168 Entity::E2eiEnrollment(e2ei_enrollment) => e2ei_enrollment.save(tx).await,
169 Entity::E2eiRefreshToken(e2ei_refresh_token) => e2ei_refresh_token.replace(tx).await,
170 Entity::E2eiAcmeCA(e2ei_acme_ca) => e2ei_acme_ca.replace(tx).await,
171 Entity::E2eiIntermediateCert(e2ei_intermediate_cert) => e2ei_intermediate_cert.save(tx).await,
172 Entity::E2eiCrl(e2ei_crl) => e2ei_crl.save(tx).await,
173 #[cfg(feature = "proteus-keystore")]
174 Entity::ProteusSession(record) => record.save(tx).await,
175 #[cfg(feature = "proteus-keystore")]
176 Entity::ProteusIdentity(record) => record.save(tx).await,
177 #[cfg(feature = "proteus-keystore")]
178 Entity::ProteusPrekey(record) => record.save(tx).await,
179 }
180}
181
182pub async fn execute_delete(tx: &TransactionWrapper<'_>, entity_id: &EntityId) -> CryptoKeystoreResult<()> {
183 match entity_id {
184 id @ EntityId::SignatureKeyPair(_) => MlsSignatureKeyPair::delete(tx, id.as_id()).await,
185 id @ EntityId::HpkePrivateKey(_) => MlsHpkePrivateKey::delete(tx, id.as_id()).await,
186 id @ EntityId::KeyPackage(_) => MlsKeyPackage::delete(tx, id.as_id()).await,
187 id @ EntityId::PskBundle(_) => MlsPskBundle::delete(tx, id.as_id()).await,
188 id @ EntityId::EncryptionKeyPair(_) => MlsEncryptionKeyPair::delete(tx, id.as_id()).await,
189 id @ EntityId::EpochEncryptionKeyPair(_) => MlsEpochEncryptionKeyPair::delete(tx, id.as_id()).await,
190 id @ EntityId::MlsCredential(_) => MlsCredential::delete(tx, id.as_id()).await,
191 id @ EntityId::MlsBufferedCommit(_) => MlsBufferedCommit::delete(tx, id.as_id()).await,
192 id @ EntityId::PersistedMlsGroup(_) => PersistedMlsGroup::delete(tx, id.as_id()).await,
193 id @ EntityId::PersistedMlsPendingGroup(_) => PersistedMlsPendingGroup::delete(tx, id.as_id()).await,
194 id @ EntityId::MlsPendingMessage(_) => MlsPendingMessage::delete(tx, id.as_id()).await,
195 id @ EntityId::E2eiEnrollment(_) => E2eiEnrollment::delete(tx, id.as_id()).await,
196 id @ EntityId::E2eiRefreshToken(_) => E2eiRefreshToken::delete(tx, id.as_id()).await,
197 id @ EntityId::E2eiAcmeCA(_) => E2eiAcmeCA::delete(tx, id.as_id()).await,
198 id @ EntityId::E2eiIntermediateCert(_) => E2eiIntermediateCert::delete(tx, id.as_id()).await,
199 id @ EntityId::E2eiCrl(_) => E2eiCrl::delete(tx, id.as_id()).await,
200 #[cfg(feature = "proteus-keystore")]
201 id @ EntityId::ProteusSession(_) => ProteusSession::delete(tx, id.as_id()).await,
202 #[cfg(feature = "proteus-keystore")]
203 id @ EntityId::ProteusIdentity(_) => ProteusIdentity::delete(tx, id.as_id()).await,
204 #[cfg(feature = "proteus-keystore")]
205 id @ EntityId::ProteusPrekey(_) => ProteusPrekey::delete(tx, id.as_id()).await,
206 }
207}