lib3mf_core/parser/
secure_content_parser.rs1use crate::error::{Lib3mfError, Result};
2use crate::model::{AccessRight, Consumer, KeyStore, ResourceDataGroup};
3use crate::parser::xml_parser::{XmlParser, get_attribute};
4use base64::prelude::*;
5use quick_xml::events::Event;
6use std::borrow::Cow;
7use std::io::BufRead;
8
9pub fn parse_keystore_content<R: BufRead>(
10 parser: &mut XmlParser<R>,
11 uuid: uuid::Uuid,
12) -> Result<KeyStore> {
13 let mut store = KeyStore {
14 uuid,
15 ..Default::default()
16 };
17
18 loop {
19 match parser.read_next_event()? {
20 Event::Start(e) => {
21 let local_name = e.local_name();
22 match local_name.as_ref() {
23 b"consumer" => {
24 let id = get_attribute(&e, b"consumerid")
25 .ok_or(Lib3mfError::Validation("Missing consumerid".to_string()))?
26 .into_owned();
27 let key_id = get_attribute(&e, b"keyid").map(|s: Cow<str>| s.into_owned());
28 let key_value =
29 get_attribute(&e, b"keyvalue").map(|s: Cow<str>| s.into_owned());
30
31 store.consumers.push(Consumer {
32 id,
33 key_id,
34 key_value,
35 });
36
37 let end_tag = e.name().as_ref().to_vec();
38 parser.read_to_end(&end_tag)?;
39 }
40 b"resourcedatagroup" => {
41 let key_uuid_str = get_attribute(&e, b"keyuuid")
42 .ok_or(Lib3mfError::Validation("Missing keyuuid".to_string()))?;
43 let key_uuid = uuid::Uuid::parse_str(&key_uuid_str).map_err(|_| {
44 Lib3mfError::Validation(format!("Invalid keyuuid: {}", key_uuid_str))
45 })?;
46 let group = parse_resource_data_group(parser, key_uuid)?;
47 store.resource_data_groups.push(group);
48 }
49 _ => {
50 let end_tag = e.name().as_ref().to_vec();
51 parser.read_to_end(&end_tag)?;
52 }
53 }
54 }
55 Event::End(e) if e.local_name().as_ref() == b"keystore" => break,
56 Event::Eof => {
57 return Err(Lib3mfError::Validation(
58 "Unexpected EOF in keystore".to_string(),
59 ));
60 }
61 _ => {}
62 }
63 }
64 Ok(store)
65}
66
67fn parse_resource_data_group<R: BufRead>(
68 parser: &mut XmlParser<R>,
69 key_uuid: uuid::Uuid,
70) -> Result<ResourceDataGroup> {
71 let mut group = ResourceDataGroup {
72 key_uuid,
73 access_rights: Vec::new(),
74 };
75
76 loop {
77 match parser.read_next_event()? {
78 Event::Start(e) => {
79 match e.local_name().as_ref() {
80 b"accessright" => {
81 let consumer_id = get_attribute(&e, b"consumerid")
82 .ok_or(Lib3mfError::Validation("Missing consumerid".to_string()))?
83 .into_owned();
84 let (wrapped_key, algorithm) = parse_access_right_content(parser)?;
86
87 group.access_rights.push(AccessRight {
88 consumer_id,
89 algorithm,
90 wrapped_key,
91 });
92 }
93 _ => {
94 let end_tag = e.name().as_ref().to_vec();
95 parser.read_to_end(&end_tag)?;
96 }
97 }
98 }
99 Event::End(e) if e.local_name().as_ref() == b"resourcedatagroup" => break,
100 Event::Eof => {
101 return Err(Lib3mfError::Validation(
102 "Unexpected EOF in resourcedatagroup".to_string(),
103 ));
104 }
105 _ => {}
106 }
107 }
108 Ok(group)
109}
110
111fn parse_access_right_content<R: BufRead>(parser: &mut XmlParser<R>) -> Result<(Vec<u8>, String)> {
112 let mut wrapped_key = Vec::new();
113 let mut algorithm = "RSA-OAEP".to_string(); loop {
116 match parser.read_next_event()? {
117 Event::Start(e) => {
118 match e.local_name().as_ref() {
119 b"wrappedkey" => {
120 if let Some(alg) = get_attribute(&e, b"encryptionalgorithm") {
122 algorithm = alg.into_owned();
123 }
124
125 let text = parser.read_text_content()?;
126 wrapped_key = BASE64_STANDARD.decode(text.as_bytes()).map_err(|e| {
128 Lib3mfError::Validation(format!("Invalid base64 wrapped key: {}", e))
129 })?;
130 }
131 _ => {
132 let end_tag = e.name().as_ref().to_vec();
133 parser.read_to_end(&end_tag)?;
134 }
135 }
136 }
137 Event::End(e) if e.local_name().as_ref() == b"accessright" => break,
138 Event::Eof => {
139 return Err(Lib3mfError::Validation(
140 "Unexpected EOF in accessright".to_string(),
141 ));
142 }
143 _ => {}
144 }
145 }
146 Ok((wrapped_key, algorithm))
147}