iso14229_1/request/
authentication.rs

1//! request of Service 29
2
3
4use 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,                     // 0x00
9    VerifyCertificateUnidirectional {   // 0x01
10        config: u8,
11        certificate: NotNullableData,
12        challenge: NullableData,
13    },
14    VerifyCertificateBidirectional {    // 0x02
15        config: u8,
16        certificate: NotNullableData,
17        challenge: NotNullableData,
18    },
19    ProofOfOwnership {                  // 0x03
20        proof_of_ownership: NotNullableData,
21        ephemeral_public_key: NullableData,
22    },
23    TransmitCertificate {               // 0x04
24        cert_evaluation_id: u16,
25        certificate: NotNullableData,
26    },
27    RequestChallengeForAuthentication { // 0x05
28        config: u8,
29        algo_indicator: AlgorithmIndicator,   // Algorithm OIDs can be looked up in the OID repository http://oid-info.com.
30    },
31    VerifyProofOfOwnershipUnidirectional { // 0x06
32        algo_indicator: AlgorithmIndicator,
33        proof_of_ownership: NotNullableData,
34        challenge: NullableData,
35        additional: NullableData,
36    },
37    VerifyProofOfOwnershipBidirectional {   // 0x07
38        algo_indicator: AlgorithmIndicator,
39        proof_of_ownership: NotNullableData,
40        challenge: NotNullableData,
41        additional: NullableData,
42    },
43    AuthenticationConfiguration,    // 0x08
44}
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}