core_crypto/mls/conversation/mutable/
encrypt.rs1use openmls::prelude::MlsMessageOutBody;
4
5use super::{ConversationMut, Result};
6use crate::OpenMlsError;
7
8impl ConversationMut {
9 pub async fn encrypt_message(&mut self, message: impl AsRef<[u8]>) -> Result<Vec<u8>> {
23 #[cfg(debug_assertions)]
24 {
25 let group = &self.group().await;
26 debug_assert!(
27 group.pending_commit().is_none(),
28 "precondition failed; a pending commit exists"
29 );
30 debug_assert!(
31 group.pending_proposals().next().is_none(),
32 "precondition failed; a pending proposal exists"
33 );
34 }
35
36 let backend = self.crypto_provider().await?;
37 let credential = self.credential().await?;
38 let signer = credential.signature_key();
39
40 self.mutate_group(async |_, group, _| {
41 let encrypted = group
42 .create_message(&backend, signer, message.as_ref())
43 .map_err(OpenMlsError::wrap("creating encrypted message"))?;
44 debug_assert!(matches!(encrypted.body, MlsMessageOutBody::PrivateMessage(_)));
46 encrypted
47 .to_bytes()
48 .map_err(OpenMlsError::wrap("constructing byte vector of encrypted message"))
49 .map_err(Into::into)
50 })
51 .await
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use crate::test_utils::*;
58
59 #[apply(all_cred_cipher)]
60 async fn can_encrypt_app_message(case: TestContext) {
61 let [alice, bob] = case.sessions().await;
62 Box::pin(async move {
63 let conversation = case.create_conversation([&alice, &bob]).await;
64
65 let msg = b"Hello bob";
66 let encrypted = conversation.guard().await.encrypt_message(msg).await.unwrap();
67 assert_ne!(&msg[..], &encrypted[..]);
68 let decrypted = conversation
69 .guard_of(&bob)
70 .await
71 .decrypt_message(encrypted)
72 .await
73 .unwrap();
74 let decrypted = &decrypted.as_text().unwrap().plaintext;
75 assert_eq!(&decrypted[..], &msg[..]);
76 })
77 .await
78 }
79
80 #[apply(all_cred_cipher)]
82 async fn can_encrypt_consecutive_messages(case: TestContext) {
83 let [alice, bob] = case.sessions().await;
84 Box::pin(async move {
85 let conversation = case.create_conversation([&alice, &bob]).await;
86
87 let msg = b"Hello bob";
88 let encrypted = conversation.guard().await.encrypt_message(msg).await.unwrap();
89 assert_ne!(&msg[..], &encrypted[..]);
90 let decrypted = conversation
91 .guard_of(&bob)
92 .await
93 .decrypt_message(encrypted)
94 .await
95 .unwrap();
96 let decrypted = &decrypted.as_text().unwrap().plaintext;
97 assert_eq!(&decrypted[..], &msg[..]);
98
99 let msg = b"Hello bob again";
100 let encrypted = conversation.guard().await.encrypt_message(msg).await.unwrap();
101 assert_ne!(&msg[..], &encrypted[..]);
102 let decrypted = conversation
103 .guard_of(&bob)
104 .await
105 .decrypt_message(encrypted)
106 .await
107 .unwrap();
108 let decrypted = &decrypted.as_text().unwrap().plaintext;
109 assert_eq!(&decrypted[..], &msg[..]);
110 })
111 .await
112 }
113}