mls_spec/messages/
content_encryption.rs1use crate::{
2 defs::{Epoch, Generation, LeafIndex},
3 group::GroupIdRef,
4 messages::{ContentType, ContentTypeInner, FramedContentAuthData},
5};
6
7pub type ReuseGuard = [u8; 4];
8
9#[derive(Debug, Clone)]
10pub struct PrivateMessageContent {
11 pub inner: ContentTypeInner,
12 pub auth: FramedContentAuthData,
13 pub padding_len: usize,
14}
15
16impl PartialEq for PrivateMessageContent {
17 fn eq(&self, other: &Self) -> bool {
18 self.inner == other.inner && self.auth == other.auth
19 }
20}
21impl Eq for PrivateMessageContent {}
22
23impl tls_codec::Size for PrivateMessageContent {
24 fn tls_serialized_len(&self) -> usize {
25 self.inner.tls_serialized_len() + self.auth.tls_serialized_len() + self.padding_len
26 }
27}
28
29impl tls_codec::Serialize for PrivateMessageContent {
30 fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
31 let mut written = 0;
32 written += self.inner.tls_serialize(writer)?;
33 written += self.auth.tls_serialize(writer)?;
34 writer.write_all(&vec![0u8; self.padding_len][..])?;
35 written += self.padding_len;
36 Ok(written)
37 }
38}
39
40impl PrivateMessageContent {
41 pub(crate) fn consume_padding<R: std::io::Read>(
42 bytes: &mut R,
43 ) -> Result<usize, tls_codec::Error> {
44 let mut padding = Vec::new();
45 bytes.read_to_end(&mut padding).map_err(|_| {
46 tls_codec::Error::DecodingError("Cannot decode padding past MessageContent".into())
47 })?;
48
49 let padding_len = padding.len();
50 if padding.into_iter().any(|b| b != 0x00) {
51 return Err(tls_codec::Error::DecodingError(
52 "MessageContent padding isn't all zeroes!".into(),
53 ));
54 }
55
56 Ok(padding_len)
57 }
58
59 pub fn tls_deserialize_with_content_type<R: std::io::Read>(
60 bytes: &mut R,
61 content_type: ContentType,
62 ) -> Result<Self, tls_codec::Error> {
63 use tls_codec::Deserialize as _;
64
65 let inner = match content_type {
66 ContentType::Reserved => {
67 return Err(tls_codec::Error::DecodingError(
68 "Tried to deserialize a ContentType::RESERVED, which is invalid".into(),
69 ));
70 }
71 ContentType::Application => ContentTypeInner::Application {
72 application_data: crate::tlspl::bytes::tls_deserialize(bytes)?,
73 },
74 ContentType::Proposal => ContentTypeInner::Proposal {
75 proposal: <_>::tls_deserialize(bytes)?,
76 },
77 ContentType::Commit => ContentTypeInner::Commit {
78 commit: <_>::tls_deserialize(bytes)?,
79 },
80 #[cfg(feature = "draft-mahy-mls-new-content-types")]
81 ContentType::Status => ContentTypeInner::Status {
82 application_data: crate::tlspl::bytes::tls_deserialize(bytes)?,
83 },
84 #[cfg(feature = "draft-mahy-mls-new-content-types")]
85 ContentType::Ephemeral => ContentTypeInner::Ephemeral {
86 application_data: crate::tlspl::bytes::tls_deserialize(bytes)?,
87 },
88 #[cfg(feature = "draft-mularczyk-mls-splitcommit")]
89 ContentType::SplitCommit => ContentTypeInner::SplitCommit {
90 split_commit: <_>::tls_deserialize(bytes)?,
91 },
92 };
93 let auth = FramedContentAuthData::tls_deserialize_with_content_type(bytes, content_type)?;
94
95 let padding_len = Self::consume_padding(bytes)?;
96
97 Ok(Self {
98 inner,
99 auth,
100 padding_len,
101 })
102 }
103}
104
105#[derive(Debug, Clone, PartialEq, Eq, tls_codec::TlsSerialize, tls_codec::TlsSize)]
120pub struct PrivateContentAAD<'a> {
121 #[tls_codec(with = "crate::tlspl::bytes")]
122 pub group_id: GroupIdRef<'a>,
123 pub epoch: &'a Epoch,
124 pub content_type: &'a ContentType,
125 #[tls_codec(with = "crate::tlspl::bytes")]
126 pub authenticated_data: &'a [u8],
127}
128
129#[derive(
143 Debug,
144 Clone,
145 PartialEq,
146 Eq,
147 tls_codec::TlsSerialize,
148 tls_codec::TlsDeserialize,
149 tls_codec::TlsSize,
150)]
151pub struct SenderData {
152 pub leaf_index: LeafIndex,
153 pub generation: Generation,
154 pub reuse_guard: ReuseGuard,
155}
156
157#[derive(Debug, Clone, PartialEq, Eq, tls_codec::TlsSerialize, tls_codec::TlsSize)]
171pub struct SenderDataAAD<'a> {
172 pub group_id: GroupIdRef<'a>,
173 pub epoch: &'a Epoch,
174 pub content_type: &'a ContentType,
175}