iso14229_1/request/
secured_data_trans.rs

1//! request of Service 84
2
3
4use crate::{AdministrativeParameter, Configuration, Error, Placeholder, RequestData, SignatureEncryptionCalculation, utils};
5
6#[derive(Debug, Clone)]
7pub struct SecuredDataTrans {
8    pub apar: AdministrativeParameter,
9    pub signature: SignatureEncryptionCalculation,
10    // pub signature_len: u16,
11    pub anti_replay_cnt: u16,
12    pub service: u8,
13    pub service_data: Vec<u8>,
14    pub signature_data: Vec<u8>,
15}
16
17impl SecuredDataTrans {
18    pub fn new(
19        mut apar: AdministrativeParameter,
20        signature: SignatureEncryptionCalculation,
21        anti_replay_cnt: u16,
22        service: u8,
23        service_data: Vec<u8>,
24        signature_data: Vec<u8>,
25    ) -> Result<Self, Error> {
26        if signature_data.len() > u16::MAX as usize {
27            return Err(Error::InvalidParam("length of `Signature/MAC Byte` is out of range".to_string()));
28        }
29
30        if !apar.is_request() {
31            apar.request_set(true);
32        }
33
34        Ok(Self {
35            apar,
36            signature,
37            // signature_len: signature_data.len() as u16,
38            anti_replay_cnt,
39            service,
40            service_data,
41            signature_data,
42        })
43    }
44}
45
46impl<'a> TryFrom<&'a [u8]> for SecuredDataTrans {
47    type Error = Error;
48    fn try_from(data: &'a [u8]) -> Result<Self, Self::Error> {
49        let data_len = data.len();
50        utils::data_length_check(data_len, 8, false)?;
51
52        let mut offset = 0;
53        let apar = AdministrativeParameter::from(u16::from_be_bytes([data[offset], data[offset + 1]]));
54        offset += 2;
55        if !apar.is_request() {
56            return Err(Error::InvalidData(hex::encode(data)));
57        }
58        let signature = SignatureEncryptionCalculation::try_from(data[offset])?;
59        offset += 1;
60
61        let signature_len = u16::from_be_bytes([data[offset], data[offset + 1]]);
62        offset += 2;
63        let anti_replay_cnt = u16::from_be_bytes([data[offset], data[offset + 1]]);
64        offset += 2;
65
66        let service = data[offset];
67        offset += 1;
68
69        utils::data_length_check(data_len, offset + signature_len as usize, false)?;
70
71        let curr_offset = data_len - offset - signature_len as usize;
72        let service_data = data[offset..offset + curr_offset].to_vec();
73        offset += curr_offset;
74
75        let signature_data = data[offset..].to_vec();
76
77        Self::new(
78            apar,
79            signature,
80            anti_replay_cnt,
81            service,
82            service_data,
83            signature_data,
84        )
85    }
86}
87
88impl Into<Vec<u8>> for SecuredDataTrans {
89    fn into(mut self) -> Vec<u8> {
90        let mut result: Vec<_> = self.apar.into();
91        result.push(self.signature.into());
92        let signature_len = self.signature_data.len() as u16;
93        result.extend(signature_len.to_be_bytes());
94        result.extend(self.anti_replay_cnt.to_be_bytes());
95        result.push(self.service);
96        result.append(&mut self.service_data);
97        result.append(&mut self.signature_data);
98
99        result
100    }
101}
102
103impl RequestData for SecuredDataTrans {
104    type SubFunc = Placeholder;
105    #[inline]
106    fn try_parse(data: &[u8], _: Option<Self::SubFunc>, _: &Configuration) -> Result<Self, Error> {
107        Self::try_from(data)
108    }
109    #[inline]
110    fn to_vec(self, _: &Configuration) -> Vec<u8> {
111        self.into()
112    }
113}
114
115#[cfg(test)]
116mod tests {
117    use crate::{AdministrativeParameter, SignatureEncryptionCalculation};
118    use super::SecuredDataTrans;
119
120    #[test]
121    fn new() -> anyhow::Result<()> {
122        let source = hex::decode("84006100000601242EF123AA55DBD10EDC55AA")?;
123
124        let mut apar = AdministrativeParameter::new();
125        apar.signed_set(true)
126            .signature_on_response_set(true);
127
128        let request = SecuredDataTrans::new(
129            apar,
130            SignatureEncryptionCalculation::VehicleManufacturerSpecific(0x00),
131            0x0124,
132            0x2E,
133            hex::decode("F123AA55")?,
134            hex::decode("DBD10EDC55AA")?,
135        )?;
136        let result: Vec<_> = request.into();
137        assert_eq!(result, source[1..].to_vec());
138
139        let request = SecuredDataTrans::try_from(&source[1..])?;
140        assert_eq!(request.apar.is_signed(), true);
141        assert_eq!(request.apar.is_signature_on_response(), true);
142        assert_eq!(request.signature, SignatureEncryptionCalculation::VehicleManufacturerSpecific(0x00));
143        assert_eq!(request.anti_replay_cnt, 0x0124);
144        assert_eq!(request.service, 0x2E);
145        assert_eq!(request.service_data, hex::decode("F123AA55")?);
146        assert_eq!(request.signature_data, hex::decode("DBD10EDC55AA")?);
147
148        Ok(())
149    }
150}