openmls/messages/
codec.rs1use tls_codec::{Deserialize, DeserializeBytes, Serialize, Size};
6
7use super::{
8 proposals::{
9 AppAckProposal, ExternalInitProposal, GroupContextExtensionProposal, PreSharedKeyProposal,
10 Proposal, ProposalType, ReInitProposal, RemoveProposal,
11 },
12 proposals_in::{AddProposalIn, ProposalIn, UpdateProposalIn},
13 CustomProposal,
14};
15
16impl Size for Proposal {
17 fn tls_serialized_len(&self) -> usize {
18 self.proposal_type().tls_serialized_len()
19 + match self {
20 Proposal::Add(p) => p.tls_serialized_len(),
21 Proposal::Update(p) => p.tls_serialized_len(),
22 Proposal::Remove(p) => p.tls_serialized_len(),
23 Proposal::PreSharedKey(p) => p.tls_serialized_len(),
24 Proposal::ReInit(p) => p.tls_serialized_len(),
25 Proposal::ExternalInit(p) => p.tls_serialized_len(),
26 Proposal::GroupContextExtensions(p) => p.tls_serialized_len(),
27 Proposal::AppAck(p) => p.tls_serialized_len(),
28 Proposal::SelfRemove => 0,
29 Proposal::Custom(p) => p.payload().tls_serialized_len(),
30 }
31 }
32}
33
34impl Serialize for Proposal {
35 fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
36 let written = self.proposal_type().tls_serialize(writer)?;
37 match self {
38 Proposal::Add(p) => p.tls_serialize(writer),
39 Proposal::Update(p) => p.tls_serialize(writer),
40 Proposal::Remove(p) => p.tls_serialize(writer),
41 Proposal::PreSharedKey(p) => p.tls_serialize(writer),
42 Proposal::ReInit(p) => p.tls_serialize(writer),
43 Proposal::ExternalInit(p) => p.tls_serialize(writer),
44 Proposal::GroupContextExtensions(p) => p.tls_serialize(writer),
45 Proposal::AppAck(p) => p.tls_serialize(writer),
46 Proposal::SelfRemove => Ok(0),
47 Proposal::Custom(p) => p.payload().tls_serialize(writer),
48 }
49 .map(|l| written + l)
50 }
51}
52
53impl Size for &ProposalIn {
54 fn tls_serialized_len(&self) -> usize {
55 self.proposal_type().tls_serialized_len()
56 + match self {
57 ProposalIn::Add(p) => p.tls_serialized_len(),
58 ProposalIn::Update(p) => p.tls_serialized_len(),
59 ProposalIn::Remove(p) => p.tls_serialized_len(),
60 ProposalIn::PreSharedKey(p) => p.tls_serialized_len(),
61 ProposalIn::ReInit(p) => p.tls_serialized_len(),
62 ProposalIn::ExternalInit(p) => p.tls_serialized_len(),
63 ProposalIn::GroupContextExtensions(p) => p.tls_serialized_len(),
64 ProposalIn::AppAck(p) => p.tls_serialized_len(),
65 ProposalIn::SelfRemove => 0,
66 ProposalIn::Custom(p) => p.payload().tls_serialized_len(),
67 }
68 }
69}
70
71impl Size for ProposalIn {
72 fn tls_serialized_len(&self) -> usize {
73 (&self).tls_serialized_len()
74 }
75}
76
77impl Serialize for &ProposalIn {
78 fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
79 let written = self.proposal_type().tls_serialize(writer)?;
80 match self {
81 ProposalIn::Add(p) => p.tls_serialize(writer),
82 ProposalIn::Update(p) => p.tls_serialize(writer),
83 ProposalIn::Remove(p) => p.tls_serialize(writer),
84 ProposalIn::PreSharedKey(p) => p.tls_serialize(writer),
85 ProposalIn::ReInit(p) => p.tls_serialize(writer),
86 ProposalIn::ExternalInit(p) => p.tls_serialize(writer),
87 ProposalIn::GroupContextExtensions(p) => p.tls_serialize(writer),
88 ProposalIn::AppAck(p) => p.tls_serialize(writer),
89 ProposalIn::SelfRemove => Ok(0),
90 ProposalIn::Custom(p) => p.payload().tls_serialize(writer),
91 }
92 .map(|l| written + l)
93 }
94}
95
96impl Serialize for ProposalIn {
97 fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
98 (&self).tls_serialize(writer)
99 }
100}
101
102impl Deserialize for ProposalIn {
103 fn tls_deserialize<R: std::io::Read>(bytes: &mut R) -> Result<Self, tls_codec::Error>
104 where
105 Self: Sized,
106 {
107 let proposal_type = ProposalType::tls_deserialize(bytes)?;
108 let proposal = match proposal_type {
109 ProposalType::Add => ProposalIn::Add(AddProposalIn::tls_deserialize(bytes)?),
110 ProposalType::Update => ProposalIn::Update(UpdateProposalIn::tls_deserialize(bytes)?),
111 ProposalType::Remove => ProposalIn::Remove(RemoveProposal::tls_deserialize(bytes)?),
112 ProposalType::PreSharedKey => {
113 ProposalIn::PreSharedKey(PreSharedKeyProposal::tls_deserialize(bytes)?)
114 }
115 ProposalType::Reinit => ProposalIn::ReInit(ReInitProposal::tls_deserialize(bytes)?),
116 ProposalType::ExternalInit => {
117 ProposalIn::ExternalInit(ExternalInitProposal::tls_deserialize(bytes)?)
118 }
119 ProposalType::GroupContextExtensions => ProposalIn::GroupContextExtensions(
120 GroupContextExtensionProposal::tls_deserialize(bytes)?,
121 ),
122 ProposalType::AppAck => ProposalIn::AppAck(AppAckProposal::tls_deserialize(bytes)?),
123 ProposalType::SelfRemove => ProposalIn::SelfRemove,
124 ProposalType::Custom(_) => {
125 let payload = Vec::<u8>::tls_deserialize(bytes)?;
126 let custom_proposal = CustomProposal::new(proposal_type.into(), payload);
127 ProposalIn::Custom(custom_proposal)
128 }
129 };
130 Ok(proposal)
131 }
132}
133
134impl DeserializeBytes for ProposalIn {
135 fn tls_deserialize_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), tls_codec::Error>
136 where
137 Self: Sized,
138 {
139 let mut bytes_ref = bytes;
140 let proposal = ProposalIn::tls_deserialize(&mut bytes_ref)?;
141 let remainder = &bytes[proposal.tls_serialized_len()..];
142 Ok((proposal, remainder))
143 }
144}