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 .app_msg
75 .unwrap();
76 assert_eq!(&decrypted[..], &msg[..]);
77 })
78 .await
79 }
80
81 #[apply(all_cred_cipher)]
83 async fn can_encrypt_consecutive_messages(case: TestContext) {
84 let [alice, bob] = case.sessions().await;
85 Box::pin(async move {
86 let conversation = case.create_conversation([&alice, &bob]).await;
87
88 let msg = b"Hello bob";
89 let encrypted = conversation.guard().await.encrypt_message(msg).await.unwrap();
90 assert_ne!(&msg[..], &encrypted[..]);
91 let decrypted = conversation
92 .guard_of(&bob)
93 .await
94 .decrypt_message(encrypted)
95 .await
96 .unwrap()
97 .app_msg
98 .unwrap();
99 assert_eq!(&decrypted[..], &msg[..]);
100
101 let msg = b"Hello bob again";
102 let encrypted = conversation.guard().await.encrypt_message(msg).await.unwrap();
103 assert_ne!(&msg[..], &encrypted[..]);
104 let decrypted = conversation
105 .guard_of(&bob)
106 .await
107 .decrypt_message(encrypted)
108 .await
109 .unwrap()
110 .app_msg
111 .unwrap();
112 assert_eq!(&decrypted[..], &msg[..]);
113 })
114 .await
115 }
116}