iso14229_1/request/
secured_data_trans.rs1use 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 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 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}