1use anyhow::Result;
6use cryptoki::session::Session;
7
8use crate::util::attribute::{AttrData, AttributeError, AttributeMap, AttributeType, ObjectClass};
9use crate::util::helper;
10
11#[derive(Clone, Debug, Default)]
12pub struct ElementaryFile {
13 pub name: String,
14 pub application: Option<String>,
15 pub private: bool,
16}
17
18impl ElementaryFile {
19 pub fn new(name: String) -> Self {
20 Self {
21 name,
22 ..Default::default()
23 }
24 }
25
26 pub fn application(mut self, app: String) -> Self {
27 self.application = Some(app);
28 self
29 }
30
31 pub fn private(mut self, private: bool) -> Self {
32 self.private = private;
33 self
34 }
35
36 pub fn find(session: &Session, search: AttributeMap) -> Result<Vec<Self>> {
37 let mut search = search;
38 search.insert(
39 AttributeType::Class,
40 AttrData::ObjectClass(ObjectClass::Data),
41 );
42 let search = search.to_vec()?;
43 let attr = [
44 AttributeType::Label,
45 AttributeType::Application,
46 AttributeType::Private,
47 ];
48 let attr = attr
49 .iter()
50 .map(|&a| Ok(a.try_into()?))
51 .collect::<Result<Vec<cryptoki::object::AttributeType>>>()?;
52
53 let mut result = Vec::new();
54 for object in session.find_objects(&search)? {
55 let data = session.get_attributes(object, &attr)?;
56 let data = AttributeMap::from(data.as_slice());
57 result.push(Self {
58 name: data
59 .get(&AttributeType::Label)
60 .map(|x| x.try_string())
61 .transpose()?
62 .unwrap_or_else(|| String::from("<unnamed>")),
63 application: data
64 .get(&AttributeType::Application)
65 .map(|x| x.try_string())
66 .transpose()?,
67 private: data
68 .get(&AttributeType::Private)
69 .map(|x| x.try_into())
70 .transpose()?
71 .unwrap_or(false),
72 });
73 }
74 Ok(result)
75 }
76
77 pub fn list(session: &Session) -> Result<Vec<Self>> {
78 Self::find(session, AttributeMap::default())
79 }
80
81 pub fn exists(self, session: &Session) -> Result<bool> {
82 let mut attr = AttributeMap::default();
83 attr.insert(
84 AttributeType::Class,
85 AttrData::ObjectClass(ObjectClass::Data),
86 );
87 attr.insert(AttributeType::Label, AttrData::Str(self.name.clone()));
88 if let Some(app) = &self.application {
89 attr.insert(AttributeType::Application, AttrData::Str(app.clone()));
90 }
91 let attr = attr.to_vec()?;
92 let objects = session.find_objects(&attr)?;
93 Ok(!objects.is_empty())
94 }
95
96 pub fn read(self, session: &Session) -> Result<Vec<u8>> {
97 let mut attr = AttributeMap::default();
98 attr.insert(
99 AttributeType::Class,
100 AttrData::ObjectClass(ObjectClass::Data),
101 );
102 attr.insert(AttributeType::Label, AttrData::Str(self.name.clone()));
103 if let Some(app) = &self.application {
104 attr.insert(AttributeType::Application, AttrData::Str(app.clone()));
105 }
106 let attr = attr.to_vec()?;
107
108 let object = helper::find_one_object(session, &attr)?;
109 let data = AttributeMap::from_object(session, object)?;
110 let value = data
111 .get(&AttributeType::Value)
112 .ok_or(AttributeError::AttributeNotFound(AttributeType::Value))?;
113 let value = Vec::<u8>::try_from(value)?;
114 Ok(value)
115 }
116
117 pub fn write(self, session: &Session, data: &[u8]) -> Result<()> {
118 let mut attr = AttributeMap::default();
119 attr.insert(
120 AttributeType::Class,
121 AttrData::ObjectClass(ObjectClass::Data),
122 );
123 attr.insert(AttributeType::Label, AttrData::Str(self.name.clone()));
124 if let Some(application) = &self.application {
125 let mut val = application.clone();
128 val.push(0 as char);
129 attr.insert(AttributeType::Application, AttrData::Str(val));
130 }
131 attr.insert(AttributeType::Token, AttrData::from(true));
132 attr.insert(AttributeType::Private, AttrData::from(self.private));
133 attr.insert(AttributeType::Value, AttrData::from(data));
134 let attr = attr.to_vec()?;
135 session.create_object(&attr)?;
136 Ok(())
137 }
138}