openpgp_card/ocard/data/
kdf_do.rs1use std::convert::TryFrom;
5
6use crate::ocard::data::KdfDo;
7use crate::ocard::tags::Tags;
8use crate::ocard::tlv::tag::Tag;
9use crate::ocard::tlv::value::Value;
10use crate::ocard::tlv::Tlv;
11use crate::Error;
12
13impl TryFrom<&[u8]> for KdfDo {
14 type Error = Error;
15 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
16 let tlv = Tlv::new(Tags::KdfDo, Value::from(value, true)?);
17
18 if let Some(Value::S(data)) = tlv.find(Tag::from([0x81])) {
19 let kdf_algo: u8 = if data.len() == 1 {
20 data[0]
21 } else {
22 return Err(Error::ParseError(
23 "couldn't parse kdf algorithm field in KDF DO".to_string(),
24 ));
25 };
26
27 let hash_algo: Option<u8> = tlv.find(Tag::from([0x82])).and_then(|v| match v {
28 Value::S(data) => {
29 if data.len() == 1 {
30 Some(data[0])
31 } else {
32 None
33 }
34 }
35 _ => None,
36 });
37
38 let iter_count: Option<u32> = tlv.find(Tag::from([0x83])).and_then(|v| match v {
39 Value::S(data) => match &data[..] {
40 [a, b, c, d] => Some(u32::from_be_bytes([*a, *b, *c, *d])),
41 _ => None,
42 },
43 _ => None,
44 });
45
46 let salt_pw1: Option<Vec<u8>> = tlv.find(Tag::from([0x84])).and_then(|v| match v {
47 Value::S(data) => Some(data.to_vec()),
48 _ => None,
49 });
50
51 let salt_rc: Option<Vec<u8>> = tlv.find(Tag::from([0x85])).and_then(|v| match v {
52 Value::S(data) => Some(data.to_vec()),
53 _ => None,
54 });
55
56 let salt_pw3: Option<Vec<u8>> = tlv.find(Tag::from([0x86])).and_then(|v| match v {
57 Value::S(data) => Some(data.to_vec()),
58 _ => None,
59 });
60
61 let initial_hash_pw1: Option<Vec<u8>> =
62 tlv.find(Tag::from([0x87])).and_then(|v| match v {
63 Value::S(data) => Some(data.to_vec()),
64 _ => None,
65 });
66
67 let initial_hash_pw3: Option<Vec<u8>> =
68 tlv.find(Tag::from([0x88])).and_then(|v| match v {
69 Value::S(data) => Some(data.to_vec()),
70 _ => None,
71 });
72
73 Ok(Self {
74 kdf_algo,
75 hash_algo,
76 iter_count,
77 salt_pw1,
78 salt_rc,
79 salt_pw3,
80 initial_hash_pw1,
81 initial_hash_pw3,
82 })
83 } else {
84 Err(Error::ParseError("couldn't parse KDF DO".to_string()))
85 }
86 }
87}
88
89impl KdfDo {
90 pub fn kdf_algo(&self) -> u8 {
91 self.kdf_algo
92 }
93
94 pub fn hash_algo(&self) -> Option<u8> {
95 self.hash_algo
96 }
97
98 pub fn iter_count(&self) -> Option<u32> {
99 self.iter_count
100 }
101
102 pub fn salt_pw1(&self) -> Option<&[u8]> {
103 self.salt_pw1.as_deref()
104 }
105
106 pub fn salt_rc(&self) -> Option<&[u8]> {
107 self.salt_rc.as_deref()
108 }
109
110 pub fn salt_pw3(&self) -> Option<&[u8]> {
111 self.salt_pw3.as_deref()
112 }
113
114 pub fn initial_hash_pw1(&self) -> Option<&[u8]> {
115 self.initial_hash_pw1.as_deref()
116 }
117
118 pub fn initial_hash_pw3(&self) -> Option<&[u8]> {
119 self.initial_hash_pw3.as_deref()
120 }
121}