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)]
25pub struct MlsMessageOut {
26 pub(crate) version: ProtocolVersion,
27 pub(crate) body: MlsMessageBodyOut,
28}
29
30#[derive(Debug, PartialEq, Clone, TlsSerialize, TlsSize)]
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
196#[cfg(any(feature = "test-utils", test))]
200impl From<MlsMessageIn> for MlsMessageOut {
201 fn from(mls_message: MlsMessageIn) -> Self {
202 let version = mls_message.version;
203 let body = match mls_message.body {
204 MlsMessageBodyIn::Welcome(w) => MlsMessageBodyOut::Welcome(w),
205 MlsMessageBodyIn::GroupInfo(gi) => MlsMessageBodyOut::GroupInfo(gi.into()),
206 MlsMessageBodyIn::KeyPackage(kp) => MlsMessageBodyOut::KeyPackage(kp.into()),
207 MlsMessageBodyIn::PublicMessage(pm) => MlsMessageBodyOut::PublicMessage(pm.into()),
208 MlsMessageBodyIn::PrivateMessage(pm) => MlsMessageBodyOut::PrivateMessage(pm.into()),
209 };
210 Self { version, body }
211 }
212}
213
214#[cfg(any(feature = "test-utils", test))]
215impl From<MlsMessageOut> for MlsMessageIn {
216 fn from(mls_message_out: MlsMessageOut) -> Self {
217 let version = mls_message_out.version;
218 let body = match mls_message_out.body {
219 MlsMessageBodyOut::PublicMessage(pm) => MlsMessageBodyIn::PublicMessage(pm.into()),
220 MlsMessageBodyOut::PrivateMessage(pm) => MlsMessageBodyIn::PrivateMessage(pm.into()),
221 MlsMessageBodyOut::Welcome(w) => MlsMessageBodyIn::Welcome(w),
222 MlsMessageBodyOut::GroupInfo(gi) => {
223 MlsMessageBodyIn::GroupInfo(gi.into_verifiable_group_info())
224 }
225 MlsMessageBodyOut::KeyPackage(kp) => MlsMessageBodyIn::KeyPackage(kp.into()),
226 };
227 Self { version, body }
228 }
229}