1use serde::{Deserialize, Serialize};
2use tls_codec::*;
3
4#[cfg(feature = "extensions-draft-08")]
5use crate::component::ComponentId;
6#[cfg(feature = "extensions-draft-08")]
7use crate::messages::proposals::AppDataUpdateOperation;
8
9use super::{extensions::FrankenExtension, FrankenKeyPackage, FrankenLeafNode};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum FrankenProposalType {
13 Add,
14 Update,
15 Remove,
16 PreSharedKey,
17 Reinit,
18 ExternalInit,
19 GroupContextExtensions,
20 #[cfg(feature = "extensions-draft-08")]
21 AppEphemeral,
22 #[cfg(feature = "extensions-draft-08")]
23 AppDataUpdate,
24 Custom(u16),
25}
26
27impl From<u16> for FrankenProposalType {
28 fn from(value: u16) -> Self {
29 match value {
30 1 => FrankenProposalType::Add,
31 2 => FrankenProposalType::Update,
32 3 => FrankenProposalType::Remove,
33 4 => FrankenProposalType::PreSharedKey,
34 5 => FrankenProposalType::Reinit,
35 6 => FrankenProposalType::ExternalInit,
36 7 => FrankenProposalType::GroupContextExtensions,
37 #[cfg(feature = "extensions-draft-08")]
38 8 => FrankenProposalType::AppDataUpdate,
39 #[cfg(feature = "extensions-draft-08")]
40 0x0009 => FrankenProposalType::AppEphemeral,
41 other => FrankenProposalType::Custom(other),
42 }
43 }
44}
45
46impl From<FrankenProposalType> for u16 {
47 fn from(value: FrankenProposalType) -> Self {
48 match value {
49 FrankenProposalType::Add => 1,
50 FrankenProposalType::Update => 2,
51 FrankenProposalType::Remove => 3,
52 FrankenProposalType::PreSharedKey => 4,
53 FrankenProposalType::Reinit => 5,
54 FrankenProposalType::ExternalInit => 6,
55 FrankenProposalType::GroupContextExtensions => 7,
56 #[cfg(feature = "extensions-draft-08")]
57 FrankenProposalType::AppDataUpdate => 8,
58 #[cfg(feature = "extensions-draft-08")]
59 FrankenProposalType::AppEphemeral => 0x0009,
60 FrankenProposalType::Custom(id) => id,
61 }
62 }
63}
64
65impl FrankenProposal {
66 pub fn proposal_type(&self) -> FrankenProposalType {
67 match self {
68 FrankenProposal::Add(_) => FrankenProposalType::Add,
69 FrankenProposal::Update(_) => FrankenProposalType::Update,
70 FrankenProposal::Remove(_) => FrankenProposalType::Remove,
71 FrankenProposal::PreSharedKey(_) => FrankenProposalType::PreSharedKey,
72 FrankenProposal::ReInit(_) => FrankenProposalType::Reinit,
73 FrankenProposal::ExternalInit(_) => FrankenProposalType::ExternalInit,
74 FrankenProposal::GroupContextExtensions(_) => {
75 FrankenProposalType::GroupContextExtensions
76 }
77 #[cfg(feature = "extensions-draft-08")]
78 FrankenProposal::AppEphemeral(_) => FrankenProposalType::AppEphemeral,
79 #[cfg(feature = "extensions-draft-08")]
80 FrankenProposal::AppDataUpdate(_) => FrankenProposalType::AppDataUpdate,
81 FrankenProposal::Custom(FrankenCustomProposal {
82 proposal_type,
83 payload: _,
84 }) => FrankenProposalType::Custom(proposal_type.to_owned()),
85 }
86 }
87}
88
89#[derive(Debug, Clone, PartialEq, Eq)]
90#[repr(u16)]
91pub enum FrankenProposal {
92 Add(FrankenAddProposal),
93 Update(FrankenUpdateProposal),
94 Remove(FrankenRemoveProposal),
95 PreSharedKey(FrankenPreSharedKeyProposal),
96 ReInit(FrankenReInitProposal),
97 ExternalInit(FrankenExternalInitProposal),
98 GroupContextExtensions(Vec<FrankenExtension>),
99 #[cfg(feature = "extensions-draft-08")]
100 AppEphemeral(FrankenAppEphemeralProposal),
101 #[cfg(feature = "extensions-draft-08")]
102 AppDataUpdate(FrankenAppDataUpdateProposal),
103 Custom(FrankenCustomProposal),
104}
105
106#[cfg(feature = "extensions-draft-08")]
107#[derive(
108 Debug,
109 PartialEq,
110 Eq,
111 Clone,
112 Serialize,
113 Deserialize,
114 TlsSize,
115 TlsSerialize,
116 TlsDeserialize,
117 TlsDeserializeBytes,
118)]
119pub struct FrankenAppDataUpdateProposal {
120 pub component_id: ComponentId,
121 pub operation: AppDataUpdateOperation,
122}
123
124#[derive(
125 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
126)]
127pub struct FrankenAddProposal {
128 pub key_package: FrankenKeyPackage,
129}
130
131#[derive(
132 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
133)]
134pub struct FrankenUpdateProposal {
135 pub leaf_node: FrankenLeafNode,
136}
137
138#[derive(
139 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
140)]
141pub struct FrankenRemoveProposal {
142 pub removed: u32,
143}
144
145#[derive(
146 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
147)]
148pub struct FrankenPreSharedKeyProposal {
149 pub psk: FrankenPreSharedKeyId,
150}
151
152#[derive(
153 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
154)]
155pub struct FrankenPreSharedKeyId {
156 pub psk: FrankenPsk,
157 pub psk_nonce: VLBytes,
158}
159
160#[derive(
161 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
162)]
163#[repr(u8)]
164pub enum FrankenPsk {
165 #[tls_codec(discriminant = 1)]
166 External(FrankenExternalPsk),
167 #[tls_codec(discriminant = 2)]
168 Resumption(FrankenResumptionPsk),
169}
170
171#[derive(
172 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
173)]
174pub struct FrankenExternalPsk {
175 pub psk_id: VLBytes,
176}
177
178#[derive(
179 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
180)]
181pub struct FrankenResumptionPsk {
182 pub usage: FrankenResumptionPskUsage,
183 pub psk_group_id: VLBytes,
184 pub psk_epoch: u64,
185}
186
187#[derive(
188 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
189)]
190#[repr(u8)]
191pub enum FrankenResumptionPskUsage {
192 Application = 1,
193 Reinit = 2,
194 Branch = 3,
195}
196
197#[derive(
198 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
199)]
200pub struct FrankenReInitProposal {
201 pub group_id: VLBytes,
202 pub version: u16,
203 pub ciphersuite: u16,
204 pub extensions: Vec<FrankenExtension>,
205}
206
207#[derive(
208 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
209)]
210pub struct FrankenExternalInitProposal {
211 pub kem_output: VLBytes,
212}
213
214#[derive(
215 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
216)]
217pub struct FrankenMessageRange {
218 pub sender: VLBytes,
219 pub first_generation: u32,
220 pub last_generation: u32,
221}
222
223#[cfg(feature = "extensions-draft-08")]
224#[derive(
225 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
226)]
227pub struct FrankenAppEphemeralProposal {
228 pub component_id: u16,
229 pub data: VLBytes,
230}
231
232#[derive(
233 Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
234)]
235pub struct FrankenCustomProposal {
236 pub proposal_type: u16,
237 pub payload: VLBytes,
238}