openmls/framing/
message_out.rs1use tls_codec::Serialize;
11
12use super::*;
13
14use crate::{
15 key_packages::KeyPackage, messages::group_info::GroupInfo, prelude::KeyPackageBundle,
16 versions::ProtocolVersion,
17};
18
19#[cfg(any(feature = "test-utils", test))]
20use crate::messages::group_info::VerifiableGroupInfo;
21
22#[derive(Debug, Clone, PartialEq, TlsSerialize, TlsSize, serde::Serialize, serde::Deserialize)]
25pub struct MlsMessageOut {
26 pub(crate) version: ProtocolVersion,
27 pub(crate) body: MlsMessageBodyOut,
28}
29
30#[derive(Debug, PartialEq, Clone, TlsSerialize, TlsSize, serde::Serialize, serde::Deserialize)]
58#[repr(u16)]
59pub enum MlsMessageBodyOut {
60 #[tls_codec(discriminant = 1)]
62 PublicMessage(PublicMessage),
63
64 #[tls_codec(discriminant = 2)]
66 PrivateMessage(PrivateMessage),
67
68 #[tls_codec(discriminant = 3)]
70 Welcome(Welcome),
71
72 #[tls_codec(discriminant = 4)]
74 GroupInfo(GroupInfo),
75
76 #[tls_codec(discriminant = 5)]
78 #[allow(dead_code)]
79 KeyPackage(KeyPackage),
80}
81
82impl From<PublicMessage> for MlsMessageOut {
83 fn from(public_message: PublicMessage) -> Self {
84 Self {
85 version: ProtocolVersion::default(),
86 body: MlsMessageBodyOut::PublicMessage(public_message),
87 }
88 }
89}
90
91impl From<PrivateMessage> for MlsMessageOut {
92 fn from(private_message: PrivateMessage) -> Self {
93 Self {
94 version: ProtocolVersion::default(),
95 body: MlsMessageBodyOut::PrivateMessage(private_message),
96 }
97 }
98}
99
100impl From<GroupInfo> for MlsMessageOut {
101 fn from(group_info: GroupInfo) -> Self {
102 Self {
103 version: group_info.group_context().protocol_version(),
104 body: MlsMessageBodyOut::GroupInfo(group_info),
105 }
106 }
107}
108
109impl From<KeyPackage> for MlsMessageOut {
110 fn from(key_package: KeyPackage) -> Self {
111 Self {
112 version: key_package.protocol_version(),
113 body: MlsMessageBodyOut::KeyPackage(key_package),
114 }
115 }
116}
117
118impl From<KeyPackageBundle> for MlsMessageOut {
119 fn from(key_package: KeyPackageBundle) -> Self {
120 Self {
121 version: key_package.key_package().protocol_version(),
122 body: MlsMessageBodyOut::KeyPackage(key_package.key_package),
123 }
124 }
125}
126
127impl MlsMessageOut {
128 pub(crate) fn from_private_message(
131 private_message: PrivateMessage,
132 version: ProtocolVersion,
133 ) -> Self {
134 Self {
135 version,
136 body: MlsMessageBodyOut::PrivateMessage(private_message),
137 }
138 }
139
140 pub fn from_welcome(welcome: Welcome, version: ProtocolVersion) -> Self {
143 MlsMessageOut {
144 version,
145 body: MlsMessageBodyOut::Welcome(welcome),
146 }
147 }
148
149 pub fn to_bytes(&self) -> Result<Vec<u8>, MlsMessageError> {
151 self.tls_serialize_detached()
152 .map_err(|_| MlsMessageError::UnableToEncode)
153 }
154
155 pub fn body(&self) -> &MlsMessageBodyOut {
157 &self.body
158 }
159}
160
161#[cfg(any(feature = "test-utils", test))]
164impl MlsMessageOut {
165 #[cfg(any(feature = "test-utils", test))]
167 pub fn into_welcome(self) -> Option<Welcome> {
168 match self.body {
169 MlsMessageBodyOut::Welcome(w) => Some(w),
170 _ => None,
171 }
172 }
173
174 #[cfg(any(feature = "test-utils", test))]
175 pub fn into_protocol_message(self) -> Option<ProtocolMessage> {
176 let mls_message_in: MlsMessageIn = self.into();
177
178 match mls_message_in.extract() {
179 MlsMessageBodyIn::PublicMessage(pm) => Some(pm.into()),
180 MlsMessageBodyIn::PrivateMessage(pm) => Some(pm.into()),
181 _ => None,
182 }
183 }
184
185 #[cfg(any(feature = "test-utils", test))]
186 pub fn into_verifiable_group_info(self) -> Option<VerifiableGroupInfo> {
187 match self.body {
188 MlsMessageBodyOut::GroupInfo(group_info) => {
189 Some(group_info.into_verifiable_group_info())
190 }
191 _ => None,
192 }
193 }
194}
195
196impl From<MlsMessageBodyOut> for MlsMessageBodyIn {
197 fn from(value: MlsMessageBodyOut) -> Self {
198 match value {
199 MlsMessageBodyOut::PublicMessage(pm) => MlsMessageBodyIn::PublicMessage(pm.into()),
200 MlsMessageBodyOut::PrivateMessage(pm) => MlsMessageBodyIn::PrivateMessage(pm.into()),
201 MlsMessageBodyOut::Welcome(w) => MlsMessageBodyIn::Welcome(w),
202 MlsMessageBodyOut::GroupInfo(gi) => {
203 MlsMessageBodyIn::GroupInfo(gi.into_verifiable_group_info())
204 }
205 MlsMessageBodyOut::KeyPackage(kp) => MlsMessageBodyIn::KeyPackage(kp.into()),
206 }
207 }
208}
209
210impl From<MlsMessageOut> for MlsMessageIn {
211 fn from(mls_message_out: MlsMessageOut) -> Self {
212 let MlsMessageOut { version, body } = mls_message_out;
213 Self {
214 version,
215 body: body.into(),
216 }
217 }
218}
219
220#[cfg(any(feature = "test-utils", test))]
224impl From<MlsMessageIn> for MlsMessageOut {
225 fn from(mls_message: MlsMessageIn) -> Self {
226 let version = mls_message.version;
227 let body = match mls_message.body {
228 MlsMessageBodyIn::Welcome(w) => MlsMessageBodyOut::Welcome(w),
229 MlsMessageBodyIn::GroupInfo(gi) => MlsMessageBodyOut::GroupInfo(gi.into()),
230 MlsMessageBodyIn::KeyPackage(kp) => MlsMessageBodyOut::KeyPackage(kp.into()),
231 MlsMessageBodyIn::PublicMessage(pm) => MlsMessageBodyOut::PublicMessage(pm.into()),
232 MlsMessageBodyIn::PrivateMessage(pm) => MlsMessageBodyOut::PrivateMessage(pm.into()),
233 };
234 Self { version, body }
235 }
236}