iso14229_1/common/
authentication.rs

1//! Commons of Service 29
2
3use crate::{enum_to_vec, Error, utils};
4
5pub(crate) const ALGORITHM_INDICATOR_LENGTH: usize = 16;
6
7enum_to_vec!(
8    pub enum AuthenticationTask {
9        DeAuthenticate = 0x00,
10        VerifyCertificateUnidirectional = 0x01,
11        VerifyCertificateBidirectional = 0x02,
12        ProofOfOwnership = 0x03,
13        TransmitCertificate = 0x04,
14        RequestChallengeForAuthentication = 0x05,
15        VerifyProofOfOwnershipUnidirectional = 0x06,
16        VerifyProofOfOwnershipBidirectional = 0x07,
17        AuthenticationConfiguration = 0x08,
18    }, u8);
19
20#[derive(Debug, Clone)]
21pub struct NotNullableData(pub(crate) Vec<u8>);
22
23impl NotNullableData {
24    #[inline]
25    pub fn new(
26        data: Vec<u8>,
27    ) -> Result<Self, Error> {
28        if data.is_empty() || data.len() > u16::MAX as usize {
29            return Err(Error::InvalidParam("Data must not be empty, and the length of the data must be less than or equal to 0xFFFF".to_string()));
30        }
31
32        Ok(Self(data))
33    }
34}
35
36impl Into<Vec<u8>> for NotNullableData {
37    #[inline]
38    fn into(mut self) -> Vec<u8> {
39        let len = self.0.len() as u16;
40        let mut result = len.to_be_bytes().to_vec();
41        result.append(&mut self.0);
42
43        result
44    }
45}
46
47#[derive(Debug, Clone)]
48pub struct NullableData(pub(crate) Vec<u8>);
49
50impl NullableData {
51    #[inline]
52    pub fn new(
53        data: Vec<u8>,
54    ) -> Result<Self, Error> {
55        if data.len() > u16::MAX as usize {
56            return Err(Error::InvalidParam("the length of data must be less than or equal to 0xFFFF!".to_string()));
57        }
58
59        Ok(Self(data))
60    }
61}
62
63impl Into<Vec<u8>> for NullableData {
64    #[inline]
65    fn into(mut self) -> Vec<u8> {
66        let len = self.0.len() as u16;
67        let mut result = len.to_be_bytes().to_vec();
68        result.append(&mut self.0);
69
70        result
71    }
72}
73
74#[derive(Debug, Clone)]
75pub struct AlgorithmIndicator(pub [u8; ALGORITHM_INDICATOR_LENGTH]);
76
77impl Into<Vec<u8>> for AlgorithmIndicator {
78    #[inline]
79    fn into(self) -> Vec<u8> {
80        self.0.to_vec()
81    }
82}
83
84#[inline]
85pub(crate) fn parse_nullable(
86    data: &[u8],
87    data_len: usize,
88    offset: &mut usize,
89) -> Result<NullableData, Error> {
90    utils::data_length_check(data_len, *offset + 2, false)?;
91
92    let len = u16::from_be_bytes([data[*offset], data[*offset + 1]]) as usize;
93    *offset += 2;
94    utils::data_length_check(data_len, *offset + len, false)?;
95
96    let result = data[*offset..*offset + len].to_vec();
97    *offset += len;
98
99    Ok(NullableData(result))
100}
101
102#[inline]
103pub(crate) fn parse_not_nullable(
104    data: &[u8],
105    data_len: usize,
106    offset: &mut usize,
107) -> Result<NotNullableData, Error> {
108    utils::data_length_check(data_len, *offset + 2, false)?;
109
110    let len = u16::from_be_bytes([data[*offset], data[*offset + 1]]) as usize;
111    *offset += 2;
112    if len == 0 {
113        return Err(Error::InvalidData(hex::encode(data)));
114    }
115    utils::data_length_check(data_len, *offset + len, false)?;
116
117    let result = data[*offset..*offset + len].to_vec();
118    *offset += len;
119
120    Ok(NotNullableData(result))
121}
122
123#[inline]
124pub(crate) fn parse_algo_indicator(
125    data: &[u8],
126    offset: &mut usize,
127) -> AlgorithmIndicator {
128    let result = &data[*offset..*offset + ALGORITHM_INDICATOR_LENGTH];
129    *offset += ALGORITHM_INDICATOR_LENGTH;
130
131    AlgorithmIndicator(result.try_into().unwrap())
132}