openmls/framing/
message_in.rs1use super::*;
18use crate::{
19 key_packages::KeyPackageIn, messages::group_info::VerifiableGroupInfo,
20 versions::ProtocolVersion,
21};
22
23#[derive(PartialEq, Debug, Clone, TlsSize, TlsSerialize)]
38pub struct MlsMessageIn {
39 pub(crate) version: ProtocolVersion,
40 pub(crate) body: MlsMessageBodyIn,
41}
42
43#[derive(Debug, PartialEq, Clone, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize)]
50#[repr(u16)]
51pub enum MlsMessageBodyIn {
52 #[tls_codec(discriminant = 1)]
54 PublicMessage(PublicMessageIn),
55
56 #[tls_codec(discriminant = 2)]
58 PrivateMessage(PrivateMessageIn),
59
60 #[tls_codec(discriminant = 3)]
62 Welcome(Welcome),
63
64 #[tls_codec(discriminant = 4)]
66 GroupInfo(VerifiableGroupInfo),
67
68 #[tls_codec(discriminant = 5)]
70 KeyPackage(KeyPackageIn),
71
72 #[cfg(feature = "targeted-messages-draft")]
74 #[cfg_attr(docsrs, doc(cfg(feature = "targeted-messages-draft")))]
75 #[tls_codec(discriminant = 6)]
76 TargetedMessage(crate::targeted_messages::TargetedMessageIn),
77}
78
79impl MlsMessageIn {
80 pub fn wire_format(&self) -> WireFormat {
82 match self.body {
83 MlsMessageBodyIn::PrivateMessage(_) => WireFormat::PrivateMessage,
84 MlsMessageBodyIn::PublicMessage(_) => WireFormat::PublicMessage,
85 MlsMessageBodyIn::Welcome(_) => WireFormat::Welcome,
86 MlsMessageBodyIn::GroupInfo(_) => WireFormat::GroupInfo,
87 MlsMessageBodyIn::KeyPackage(_) => WireFormat::KeyPackage,
88 #[cfg(feature = "targeted-messages-draft")]
89 MlsMessageBodyIn::TargetedMessage(_) => WireFormat::TargetedMessage,
90 }
91 }
92
93 pub fn extract(self) -> MlsMessageBodyIn {
96 self.body
97 }
98
99 pub fn try_into_protocol_message(self) -> Result<ProtocolMessage, ProtocolMessageError> {
101 self.try_into()
102 }
103
104 #[cfg(all(feature = "targeted-messages-draft", any(feature = "test-utils", test)))]
107 #[cfg_attr(docsrs, doc(cfg(feature = "targeted-messages-draft")))]
108 pub fn into_targeted_message(self) -> Option<crate::targeted_messages::TargetedMessageIn> {
109 match self.body {
110 MlsMessageBodyIn::TargetedMessage(tm) => Some(tm),
111 _ => None,
112 }
113 }
114
115 #[cfg(any(test, feature = "test-utils"))]
116 pub fn into_keypackage(self) -> Option<crate::key_packages::KeyPackage> {
117 match self.body {
118 MlsMessageBodyIn::KeyPackage(key_package) => {
119 debug_assert!(key_package.version_is_supported(self.version));
120 Some(key_package.into())
121 }
122 _ => None,
123 }
124 }
125
126 #[cfg(test)]
127 pub(crate) fn into_plaintext(self) -> Option<PublicMessage> {
128 match self.body {
129 MlsMessageBodyIn::PublicMessage(m) => Some(m.into()),
130 _ => None,
131 }
132 }
133
134 #[cfg(test)]
135 pub(crate) fn into_ciphertext(self) -> Option<PrivateMessageIn> {
136 match self.body {
137 MlsMessageBodyIn::PrivateMessage(m) => Some(m),
138 _ => None,
139 }
140 }
141
142 #[cfg(any(feature = "test-utils", test))]
146 pub fn into_welcome(self) -> Option<Welcome> {
147 match self.body {
148 MlsMessageBodyIn::Welcome(w) => Some(w),
149 _ => None,
150 }
151 }
152
153 #[cfg(any(feature = "test-utils", test))]
154 pub fn into_protocol_message(self) -> Option<ProtocolMessage> {
155 match self.body {
156 MlsMessageBodyIn::PublicMessage(m) => Some(m.into()),
157 MlsMessageBodyIn::PrivateMessage(m) => Some(m.into()),
158 _ => None,
159 }
160 }
161
162 #[cfg(any(feature = "test-utils", test))]
163 pub fn into_verifiable_group_info(self) -> Option<VerifiableGroupInfo> {
164 match self.body {
165 MlsMessageBodyIn::GroupInfo(group_info) => Some(group_info),
166 _ => None,
167 }
168 }
169}
170
171#[derive(Debug, Clone)]
175pub enum ProtocolMessage {
176 PrivateMessage(PrivateMessageIn),
178 PublicMessage(Box<PublicMessageIn>),
180}
181
182impl ProtocolMessage {
183 pub fn wire_format(&self) -> WireFormat {
185 match self {
186 ProtocolMessage::PrivateMessage(_) => WireFormat::PrivateMessage,
187 ProtocolMessage::PublicMessage(_) => WireFormat::PublicMessage,
188 }
189 }
190
191 pub fn group_id(&self) -> &GroupId {
193 match self {
194 ProtocolMessage::PrivateMessage(ref m) => m.group_id(),
195 ProtocolMessage::PublicMessage(ref m) => m.group_id(),
196 }
197 }
198
199 pub fn epoch(&self) -> GroupEpoch {
201 match self {
202 ProtocolMessage::PrivateMessage(ref m) => m.epoch(),
203 ProtocolMessage::PublicMessage(ref m) => m.epoch(),
204 }
205 }
206
207 pub fn content_type(&self) -> ContentType {
209 match self {
210 ProtocolMessage::PrivateMessage(ref m) => m.content_type(),
211 ProtocolMessage::PublicMessage(ref m) => m.content_type(),
212 }
213 }
214
215 pub fn is_external(&self) -> bool {
217 match &self {
218 ProtocolMessage::PublicMessage(p) => {
219 matches!(
220 p.sender(),
221 Sender::NewMemberProposal | Sender::NewMemberCommit | Sender::External(_)
222 )
223 }
224 ProtocolMessage::PrivateMessage(_) => false,
226 }
227 }
228
229 pub fn is_handshake_message(&self) -> bool {
231 self.content_type().is_handshake_message()
232 }
233}
234
235impl From<PrivateMessageIn> for ProtocolMessage {
236 fn from(private_message: PrivateMessageIn) -> Self {
237 ProtocolMessage::PrivateMessage(private_message)
238 }
239}
240
241impl From<PublicMessageIn> for ProtocolMessage {
242 fn from(public_message: PublicMessageIn) -> Self {
243 ProtocolMessage::PublicMessage(Box::new(public_message))
244 }
245}
246
247impl TryFrom<MlsMessageIn> for ProtocolMessage {
248 type Error = ProtocolMessageError;
249
250 fn try_from(msg: MlsMessageIn) -> Result<Self, Self::Error> {
251 match msg.body {
252 MlsMessageBodyIn::PublicMessage(m) => Ok(m.into()),
253 MlsMessageBodyIn::PrivateMessage(m) => Ok(ProtocolMessage::PrivateMessage(m)),
254 _ => Err(ProtocolMessageError::WrongWireFormat),
255 }
256 }
257}
258
259#[cfg(any(feature = "test-utils", test))]
260impl From<PublicMessage> for ProtocolMessage {
261 fn from(msg: PublicMessage) -> Self {
262 PublicMessageIn::from(msg).into()
263 }
264}