Skip to main content

mls_spec/
messages.rs

1mod content;
2pub use self::content::*;
3mod content_type;
4pub use self::content_type::*;
5mod sender;
6pub use self::sender::*;
7mod message_kinds;
8pub use self::message_kinds::*;
9mod content_encryption;
10pub use self::content_encryption::*;
11
12use crate::defs::Epoch;
13use crate::defs::ProtocolVersion;
14
15/// MLS Message
16///
17/// <https://www.rfc-editor.org/rfc/rfc9420.html#section-6-4>
18///
19/// ## TLS Presentation Language
20///
21/// ```notrust,ignore
22/// struct {
23///     ProtocolVersion version = mls10;
24///     WireFormat wire_format;
25///     select (MLSMessage.wire_format) {
26///         case mls_public_message:
27///             PublicMessage public_message;
28///         case mls_private_message:
29///             PrivateMessage private_message;
30///         case mls_welcome:
31///             Welcome welcome;
32///         case mls_group_info:
33///             GroupInfo group_info;
34///         case mls_key_package:
35///             KeyPackage key_package;
36///     };
37/// } MLSMessage;
38/// ```
39#[derive(
40    Debug,
41    Clone,
42    PartialEq,
43    Eq,
44    tls_codec::TlsSerialize,
45    tls_codec::TlsDeserialize,
46    tls_codec::TlsSize,
47)]
48#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
49pub struct MlsMessage {
50    pub version: ProtocolVersion,
51    pub content: MlsMessageContent,
52}
53
54impl MlsMessage {
55    pub fn group_id_and_epoch(&self) -> Option<(&[u8], &Epoch)> {
56        Some(match &self.content {
57            MlsMessageContent::MlsPublicMessage(public_message) => (
58                &public_message.content.group_id,
59                &public_message.content.epoch,
60            ),
61            MlsMessageContent::MlsPrivateMessage(private_message) => {
62                (&private_message.group_id, &private_message.epoch)
63            }
64            MlsMessageContent::GroupInfo(group_info) => (
65                group_info.group_context.group_id(),
66                &group_info.group_context.epoch,
67            ),
68            #[cfg(feature = "draft-ietf-mls-targeted-messages")]
69            MlsMessageContent::MlsTargetedMessage(targeted_message) => {
70                (&targeted_message.group_id, &targeted_message.epoch)
71            }
72            #[cfg(feature = "draft-mahy-mls-semiprivatemessage")]
73            MlsMessageContent::MlsSemiPrivateMessage(semi_private_message) => {
74                (&semi_private_message.group_id, &semi_private_message.epoch)
75            }
76            #[cfg(feature = "draft-mularczyk-mls-splitcommit")]
77            MlsMessageContent::MlsSplitCommitMessage(split_commit_message) => {
78                return split_commit_message
79                    .split_commit_message
80                    .group_id_and_epoch();
81            }
82            #[cfg(feature = "draft-pham-mls-additional-wire-formats")]
83            MlsMessageContent::MlsMessageWithoutAad(message_without_aad) => {
84                match message_without_aad {
85                    crate::drafts::additional_wire_formats::MessageWithoutAad::PublicMessageWithoutAad(public_message_without_aad) => (&public_message_without_aad.content.group_id, &public_message_without_aad.content.epoch),
86                    crate::drafts::additional_wire_formats::MessageWithoutAad::PrivateMessageWithoutAad(private_message_without_aad) => (&private_message_without_aad.group_id, &private_message_without_aad.epoch),
87                }
88            },
89            #[cfg(feature = "draft-mahy-mls-private-external")]
90            MlsMessageContent::MlsPrivateExternalMessage(private_external_message) => (&private_external_message.group_id, &private_external_message.epoch),
91            _ => return None,
92        })
93    }
94}