1use crate::{AlgorithmIndicator, AuthenticationTask, Configuration, Error, NotNullableData, NullableData, parse_algo_indicator, parse_not_nullable, parse_nullable, RequestData, Service, utils};
5
6#[derive(Debug, Clone)]
7pub enum Authentication {
8 DeAuthenticate, VerifyCertificateUnidirectional { config: u8,
11 certificate: NotNullableData,
12 challenge: NullableData,
13 },
14 VerifyCertificateBidirectional { config: u8,
16 certificate: NotNullableData,
17 challenge: NotNullableData,
18 },
19 ProofOfOwnership { proof_of_ownership: NotNullableData,
21 ephemeral_public_key: NullableData,
22 },
23 TransmitCertificate { cert_evaluation_id: u16,
25 certificate: NotNullableData,
26 },
27 RequestChallengeForAuthentication { config: u8,
29 algo_indicator: AlgorithmIndicator, },
31 VerifyProofOfOwnershipUnidirectional { algo_indicator: AlgorithmIndicator,
33 proof_of_ownership: NotNullableData,
34 challenge: NullableData,
35 additional: NullableData,
36 },
37 VerifyProofOfOwnershipBidirectional { algo_indicator: AlgorithmIndicator,
39 proof_of_ownership: NotNullableData,
40 challenge: NotNullableData,
41 additional: NullableData,
42 },
43 AuthenticationConfiguration, }
45
46impl RequestData for Authentication {
47 type SubFunc = AuthenticationTask;
48 fn try_parse(data: &[u8], sub_func: Option<Self::SubFunc>, _: &Configuration) -> Result<Self, Error> {
49 match sub_func {
50 Some(v) => {
51 let data_len = data.len();
52 let mut offset = 0;
53 match v {
54 AuthenticationTask::DeAuthenticate =>
55 Ok(Self::DeAuthenticate),
56 AuthenticationTask::VerifyCertificateUnidirectional => {
57 utils::data_length_check(data_len, 5, false)?;
58
59 let config = data[offset];
60 offset += 1;
61 let certificate = parse_not_nullable(data, data_len, &mut offset)?;
62 let challenge = parse_nullable(data, data_len, &mut offset)?;
63
64 Ok(Self::VerifyCertificateUnidirectional {
65 config,
66 certificate,
67 challenge,
68 })
69 },
70 AuthenticationTask::VerifyCertificateBidirectional => {
71 utils::data_length_check(data_len, 7, false)?;
72
73 let config = data[offset];
74 offset += 1;
75 let certificate = parse_not_nullable(data, data_len, &mut offset)?;
76 let challenge = parse_not_nullable(data, data_len, &mut offset)?;
77
78 Ok(Self::VerifyCertificateBidirectional {
79 config,
80 certificate,
81 challenge,
82 })
83 },
84 AuthenticationTask::ProofOfOwnership => {
85 let proof_of_ownership = parse_not_nullable(data, data_len, &mut offset)?;
86 let ephemeral_public_key = parse_nullable(data, data_len, &mut offset)?;
87
88 Ok(Self::ProofOfOwnership {
89 proof_of_ownership,
90 ephemeral_public_key,
91 })
92 },
93 AuthenticationTask::TransmitCertificate => {
94 utils::data_length_check(data_len, 5, false)?;
95
96 let cert_evaluation_id = u16::from_be_bytes([data[offset], data[offset + 1]]);
97 offset += 2;
98 let certificate = parse_not_nullable(data, data_len, &mut offset)?;
99
100 Ok(Self::TransmitCertificate {
101 cert_evaluation_id,
102 certificate,
103 })
104 },
105 AuthenticationTask::RequestChallengeForAuthentication => {
106 utils::data_length_check(data_len, 17, false)?;
107
108 let config = data[offset];
109 offset += 1;
110 let algo_indicator = parse_algo_indicator(data, &mut offset);
111
112 Ok(Self::RequestChallengeForAuthentication {
113 config,
114 algo_indicator,
115 })
116 },
117 AuthenticationTask::VerifyProofOfOwnershipUnidirectional => {
118 utils::data_length_check(data_len, 19, false)?;
119
120 let algo_indicator = parse_algo_indicator(data, &mut offset);
121 offset += 16;
122 let proof_of_ownership = parse_not_nullable(data, data_len, &mut offset)?;
123 let challenge = parse_nullable(data, data_len, &mut offset)?;
124 let additional = parse_nullable(data, data_len, &mut offset)?;
125
126
127 Ok(Self::VerifyProofOfOwnershipUnidirectional {
128 algo_indicator,
129 proof_of_ownership,
130 challenge,
131 additional,
132 })
133 },
134 AuthenticationTask::VerifyProofOfOwnershipBidirectional => {
135 utils::data_length_check(data_len, 19, false)?;
136
137 let algo_indicator = parse_algo_indicator(data, &mut offset);
138 offset += 16;
139 let proof_of_ownership = parse_not_nullable(data, data_len, &mut offset)?;
140 let challenge = parse_not_nullable(data, data_len, &mut offset)?;
141 let additional = parse_nullable(data, data_len, &mut offset)?;
142
143 Ok(Self::VerifyProofOfOwnershipBidirectional {
144 algo_indicator,
145 proof_of_ownership,
146 challenge,
147 additional,
148 })
149 },
150 AuthenticationTask::AuthenticationConfiguration =>
151 Ok(Self::AuthenticationConfiguration),
152 }
153 },
154 None => panic!("Sub-function required"),
155 }
156 }
157 #[inline]
158 fn to_vec(self, _: &Configuration) -> Vec<u8> {
159 self.into()
160 }
161}
162
163impl Into<Vec<u8>> for Authentication {
164 fn into(self) -> Vec<u8> {
165 let mut result = Vec::new();
166 match self {
167 Self::DeAuthenticate => {},
168 Self::VerifyCertificateUnidirectional {
169 config,
170 certificate,
171 challenge,
172 } => {
173 result.push(config);
174 result.append(&mut certificate.into());
175 result.append(&mut challenge.into());
176 },
177 Self::VerifyCertificateBidirectional {
178 config,
179 certificate,
180 challenge,
181 } => {
182 result.push(config);
183 result.append(&mut certificate.into());
184 result.append(&mut challenge.into());
185 },
186 Self::ProofOfOwnership {
187 proof_of_ownership,
188 ephemeral_public_key,
189 } => {
190 result.append(&mut proof_of_ownership.into());
191 result.append(&mut ephemeral_public_key.into());
192 },
193 Self::TransmitCertificate {
194 cert_evaluation_id,
195 certificate,
196 } => {
197 result.extend(cert_evaluation_id.to_be_bytes());
198 result.append(&mut certificate.into());
199 },
200 Self::RequestChallengeForAuthentication {
201 config,
202 algo_indicator,
203 } => {
204 result.push(config);
205 result.append(&mut algo_indicator.into());
206 },
207 Self::VerifyProofOfOwnershipUnidirectional {
208 algo_indicator,
209 proof_of_ownership,
210 challenge,
211 additional,
212 } => {
213 result.append(&mut algo_indicator.into());
214 result.append(&mut proof_of_ownership.into());
215 result.append(&mut challenge.into());
216 result.append(&mut additional.into());
217 },
218 Self::VerifyProofOfOwnershipBidirectional {
219 algo_indicator,
220 proof_of_ownership,
221 challenge,
222 additional,
223 } => {
224 result.append(&mut algo_indicator.into());
225 result.append(&mut proof_of_ownership.into());
226 result.append(&mut challenge.into());
227 result.append(&mut additional.into());
228 },
229 Self::AuthenticationConfiguration => {}
230 }
231
232 result
233 }
234}