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