1use std::fmt::Debug;
2
3use openmls_traits::{
4 crypto::OpenMlsCrypto,
5 random::OpenMlsRand,
6 storage::{StorageProvider as StorageProviderTrait, CURRENT_VERSION},
7 types::{Ciphersuite, HpkeCiphertext, HpkeKeyPair},
8};
9use serde::{Deserialize, Serialize};
10use tls_codec::{TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize, VLBytes};
11
12use crate::{
13 ciphersuite::{hpke, HpkePrivateKey, HpkePublicKey, Secret},
14 error::LibraryError,
15 storage::{OpenMlsProvider, StorageProvider},
16};
17
18#[derive(
21 Debug,
22 Clone,
23 Serialize,
24 Deserialize,
25 TlsSerialize,
26 TlsDeserialize,
27 TlsDeserializeBytes,
28 TlsSize,
29 PartialEq,
30 Eq,
31 Hash,
32)]
33pub struct EncryptionKey {
34 key: HpkePublicKey,
35}
36
37impl EncryptionKey {
38 pub(crate) fn key(&self) -> &HpkePublicKey {
40 &self.key
41 }
42
43 pub(crate) fn as_slice(&self) -> &[u8] {
45 self.key.as_slice()
46 }
47
48 pub(crate) fn encrypt(
50 &self,
51 crypto: &impl OpenMlsCrypto,
52 ciphersuite: Ciphersuite,
53 context: &[u8],
54 plaintext: &[u8],
55 ) -> Result<HpkeCiphertext, LibraryError> {
56 hpke::encrypt_with_label(
57 self.as_slice(),
58 "UpdatePathNode",
59 context,
60 plaintext,
61 ciphersuite,
62 crypto,
63 )
64 .map_err(|_| LibraryError::custom("Encryption failed. A serialization issue really"))
65 }
66}
67
68impl From<Vec<u8>> for EncryptionKey {
69 fn from(key: Vec<u8>) -> Self {
70 Self { key: key.into() }
71 }
72}
73
74#[derive(
75 Clone, Serialize, Deserialize, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize,
76)]
77#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq, Eq))]
78pub struct EncryptionPrivateKey {
79 key: HpkePrivateKey,
80}
81
82impl Debug for EncryptionPrivateKey {
83 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84 let mut ds = f.debug_struct("EncryptionPrivateKey");
85
86 #[cfg(feature = "crypto-debug")]
87 ds.field("key", &self.key);
88 #[cfg(not(feature = "crypto-debug"))]
89 ds.field("key", &"***");
90
91 ds.finish()
92 }
93}
94
95impl From<Vec<u8>> for EncryptionPrivateKey {
96 fn from(key: Vec<u8>) -> Self {
97 Self { key: key.into() }
98 }
99}
100
101impl From<HpkePrivateKey> for EncryptionPrivateKey {
102 fn from(key: HpkePrivateKey) -> Self {
103 Self { key }
104 }
105}
106
107impl EncryptionPrivateKey {
108 pub(crate) fn decrypt(
114 &self,
115 crypto: &impl OpenMlsCrypto,
116 ciphersuite: Ciphersuite,
117 ciphertext: &HpkeCiphertext,
118 group_context: &[u8],
119 ) -> Result<Secret, hpke::Error> {
120 hpke::decrypt_with_label(
122 &self.key,
123 "UpdatePathNode",
124 group_context,
125 ciphertext,
126 ciphersuite,
127 crypto,
128 )
129 .map(|secret_bytes| Secret::from_slice(&secret_bytes))
130 }
131}
132
133#[cfg(any(test, feature = "test-utils"))]
134impl EncryptionPrivateKey {
135 pub(crate) fn key(&self) -> &HpkePrivateKey {
136 &self.key
137 }
138}
139
140impl From<HpkePublicKey> for EncryptionKey {
141 fn from(key: HpkePublicKey) -> Self {
142 Self { key }
143 }
144}
145
146#[derive(
147 Debug, Clone, Serialize, Deserialize, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize,
148)]
149#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq, Eq))]
150pub(crate) struct EncryptionKeyPair {
151 public_key: EncryptionKey,
152 private_key: EncryptionPrivateKey,
153}
154
155impl EncryptionKeyPair {
156 pub(crate) fn write<Storage: StorageProvider>(
162 &self,
163 store: &Storage,
164 ) -> Result<(), Storage::Error> {
165 store.write_encryption_key_pair(self.public_key(), self)
166 }
167
168 pub(crate) fn read(
178 provider: &impl OpenMlsProvider,
179 encryption_key: &EncryptionKey,
180 ) -> Option<EncryptionKeyPair> {
181 provider
182 .storage()
183 .encryption_key_pair(encryption_key)
184 .ok()
185 .flatten()
186 }
187
188 pub(crate) fn delete<Storage: StorageProviderTrait<CURRENT_VERSION>>(
194 &self,
195 store: &Storage,
196 ) -> Result<(), Storage::Error> {
197 store.delete_encryption_key_pair(self.public_key())
198 }
199
200 pub(crate) fn public_key(&self) -> &EncryptionKey {
201 &self.public_key
202 }
203
204 pub(crate) fn private_key(&self) -> &EncryptionPrivateKey {
205 &self.private_key
206 }
207
208 pub(crate) fn random(
209 rand: &impl OpenMlsRand,
210 crypto: &impl OpenMlsCrypto,
211 ciphersuite: Ciphersuite,
212 ) -> Result<Self, LibraryError> {
213 let ikm =
214 Secret::random(ciphersuite, rand).map_err(LibraryError::unexpected_crypto_error)?;
215 Ok(crypto
216 .derive_hpke_keypair(ciphersuite.hpke_config(), ikm.as_slice())
217 .map_err(LibraryError::unexpected_crypto_error)?
218 .into())
219 }
220}
221
222#[cfg(feature = "test-utils")]
223pub mod test_utils {
224 use super::*;
225
226 pub fn read_keys_from_key_store(
227 provider: &impl OpenMlsProvider,
228 encryption_key: &EncryptionKey,
229 ) -> HpkeKeyPair {
230 let keys = EncryptionKeyPair::read(provider, encryption_key).unwrap();
231
232 HpkeKeyPair {
233 private: keys.private_key.key,
234 public: keys.public_key.key.as_slice().to_vec(),
235 }
236 }
237
238 pub fn write_keys_from_key_store(provider: &impl OpenMlsProvider, encryption_key: HpkeKeyPair) {
239 let keypair = EncryptionKeyPair::from(encryption_key);
240
241 keypair.write(provider.storage()).unwrap();
242 }
243}
244
245#[cfg(test)]
246impl EncryptionKeyPair {
247 pub(crate) fn from_raw(public_key: Vec<u8>, private_key: Vec<u8>) -> Self {
249 Self {
250 public_key: EncryptionKey {
251 key: public_key.into(),
252 },
253 private_key: EncryptionPrivateKey {
254 key: private_key.into(),
255 },
256 }
257 }
258}
259
260impl From<(HpkePublicKey, HpkePrivateKey)> for EncryptionKeyPair {
261 fn from((public_key, private_key): (HpkePublicKey, HpkePrivateKey)) -> Self {
262 Self {
263 public_key: public_key.into(),
264 private_key: private_key.into(),
265 }
266 }
267}
268
269impl From<HpkeKeyPair> for EncryptionKeyPair {
270 fn from(hpke_keypair: HpkeKeyPair) -> Self {
271 let public_bytes: VLBytes = hpke_keypair.public.into();
272 let private_bytes = hpke_keypair.private;
273 Self {
274 public_key: public_bytes.into(),
275 private_key: private_bytes.into(),
276 }
277 }
278}
279
280impl From<(EncryptionKey, EncryptionPrivateKey)> for EncryptionKeyPair {
281 fn from((public_key, private_key): (EncryptionKey, EncryptionPrivateKey)) -> Self {
282 Self {
283 public_key,
284 private_key,
285 }
286 }
287}