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