1use crate::error::{Lib3mfError, Result};
2use crate::model::crypto::*;
3use crate::parser::xml_parser::{XmlParser, get_attribute};
4use quick_xml::events::Event;
5use std::io::BufRead;
6
7pub fn parse_signature<R: BufRead>(parser: &mut XmlParser<R>) -> Result<Signature> {
9 let mut signature = Signature::default();
10
11 loop {
12 let evt_info = match parser.read_next_event()? {
14 Event::Start(e) => Some((e.local_name().as_ref().to_vec(), e.name().as_ref().to_vec())),
15 Event::End(e) if e.local_name().as_ref() == b"Signature" => return Ok(signature),
16 Event::Eof => {
17 return Err(Lib3mfError::Validation(
18 "Unexpected EOF in Signature".to_string(),
19 ));
20 }
21 _ => None,
22 };
23
24 if let Some((local_name, raw_name)) = evt_info {
25 match local_name.as_slice() {
26 b"SignedInfo" => {
27 signature.signed_info = parse_signed_info(parser)?;
28 }
29 b"SignatureValue" => {
30 let val = parser.read_text_content()?;
31 signature.signature_value = SignatureValue { value: val };
32 }
33 b"KeyInfo" => {
34 signature.key_info = Some(parse_key_info(parser)?);
35 }
36 _ => {
37 parser.read_to_end(&raw_name)?;
38 }
39 }
40 }
41 }
42}
43
44fn parse_signed_info<R: BufRead>(parser: &mut XmlParser<R>) -> Result<SignedInfo> {
45 let mut info = SignedInfo::default();
46
47 loop {
48 let evt_info = match parser.read_next_event()? {
49 Event::Start(e) => {
50 let alg = get_attribute(&e, b"Algorithm").map(|s| s.into_owned());
51 let uri = get_attribute(&e, b"URI").map(|s| s.into_owned());
52 Some((
53 e.local_name().as_ref().to_vec(),
54 e.name().as_ref().to_vec(),
55 alg,
56 uri,
57 false,
58 ))
59 }
60 Event::Empty(e) => {
61 let alg = get_attribute(&e, b"Algorithm").map(|s| s.into_owned());
62 let uri = get_attribute(&e, b"URI").map(|s| s.into_owned());
63 Some((
64 e.local_name().as_ref().to_vec(),
65 e.name().as_ref().to_vec(),
66 alg,
67 uri,
68 true,
69 ))
70 }
71 Event::End(e) if e.local_name().as_ref() == b"SignedInfo" => return Ok(info),
72 Event::Eof => {
73 return Err(Lib3mfError::Validation(
74 "Unexpected EOF in SignedInfo".to_string(),
75 ));
76 }
77 _ => None,
78 };
79
80 if let Some((local_name, raw_name, alg, uri, is_empty)) = evt_info {
81 match local_name.as_slice() {
82 b"CanonicalizationMethod" => {
83 info.canonicalization_method = CanonicalizationMethod {
84 algorithm: alg.unwrap_or_default(),
85 };
86 if !is_empty {
87 parser.read_to_end(&raw_name)?;
88 }
89 }
90 b"SignatureMethod" => {
91 info.signature_method = SignatureMethod {
92 algorithm: alg.unwrap_or_default(),
93 };
94 if !is_empty {
95 parser.read_to_end(&raw_name)?;
96 }
97 }
98 b"Reference" => {
99 if !is_empty {
102 let r = parse_reference_content(parser, uri.unwrap_or_default())?;
108 info.references.push(r);
109 } else {
110 let r = Reference {
112 uri: uri.unwrap_or_default(),
113 ..Default::default()
114 };
115 info.references.push(r);
116 }
117 }
118 _ => {
119 if !is_empty {
120 parser.read_to_end(&raw_name)?;
121 }
122 }
123 }
124 }
125 }
126}
127
128fn parse_reference_content<R: BufRead>(
130 parser: &mut XmlParser<R>,
131 uri: String,
132) -> Result<Reference> {
133 let mut r = Reference {
134 uri,
135 ..Default::default()
136 };
137
138 loop {
139 let evt_info = match parser.read_next_event()? {
140 Event::Start(e) => {
141 let alg = get_attribute(&e, b"Algorithm").map(|s| s.into_owned());
142 Some((
143 e.local_name().as_ref().to_vec(),
144 e.name().as_ref().to_vec(),
145 alg,
146 false,
147 ))
148 }
149 Event::Empty(e) => {
150 let alg = get_attribute(&e, b"Algorithm").map(|s| s.into_owned());
151 Some((
152 e.local_name().as_ref().to_vec(),
153 e.name().as_ref().to_vec(),
154 alg,
155 true,
156 ))
157 }
158 Event::End(e) if e.local_name().as_ref() == b"Reference" => return Ok(r),
159 Event::Eof => {
160 return Err(Lib3mfError::Validation(
161 "Unexpected EOF in Reference".to_string(),
162 ));
163 }
164 _ => None,
165 };
166
167 if let Some((local_name, raw_name, alg, is_empty)) = evt_info {
168 match local_name.as_slice() {
169 b"DigestMethod" => {
170 r.digest_method = DigestMethod {
171 algorithm: alg.unwrap_or_default(),
172 };
173 if !is_empty {
174 parser.read_to_end(&raw_name)?;
175 }
176 }
177 b"DigestValue" => {
178 if !is_empty {
180 let val = parser.read_text_content()?;
181 r.digest_value = DigestValue { value: val };
182 }
183 }
184 b"Transforms" => {
185 if !is_empty {
186 let transforms = parse_transforms_content(parser)?;
187 r.transforms = Some(transforms);
188 }
189 }
190 _ => {
191 if !is_empty {
192 parser.read_to_end(&raw_name)?;
193 }
194 }
195 }
196 }
197 }
198}
199
200fn parse_transforms_content<R: BufRead>(parser: &mut XmlParser<R>) -> Result<Vec<Transform>> {
201 let mut transforms = Vec::new();
202 loop {
203 let evt_info = match parser.read_next_event()? {
204 Event::Start(e) => {
205 let alg = get_attribute(&e, b"Algorithm").map(|s| s.into_owned());
206 Some((
207 e.local_name().as_ref().to_vec(),
208 e.name().as_ref().to_vec(),
209 alg,
210 false,
211 ))
212 }
213 Event::Empty(e) => {
214 let alg = get_attribute(&e, b"Algorithm").map(|s| s.into_owned());
215 Some((
216 e.local_name().as_ref().to_vec(),
217 e.name().as_ref().to_vec(),
218 alg,
219 true,
220 ))
221 }
222 Event::End(e) if e.local_name().as_ref() == b"Transforms" => return Ok(transforms),
223 Event::Eof => {
224 return Err(Lib3mfError::Validation(
225 "Unexpected EOF in Transforms".to_string(),
226 ));
227 }
228 _ => None,
229 };
230
231 if let Some((local_name, raw_name, alg, is_empty)) = evt_info {
232 match local_name.as_slice() {
233 b"Transform" => {
234 transforms.push(Transform {
235 algorithm: alg.unwrap_or_default(),
236 });
237 if !is_empty {
238 parser.read_to_end(&raw_name)?;
239 }
240 }
241 _ => {
242 if !is_empty {
243 parser.read_to_end(&raw_name)?;
244 }
245 }
246 }
247 }
248 }
249}
250
251fn parse_key_info<R: BufRead>(parser: &mut XmlParser<R>) -> Result<KeyInfo> {
252 let mut info = KeyInfo::default();
253
254 loop {
255 let evt_info = match parser.read_next_event()? {
256 Event::Start(e) => Some((e.local_name().as_ref().to_vec(), e.name().as_ref().to_vec())),
257 Event::End(e) if e.local_name().as_ref() == b"KeyInfo" => return Ok(info),
258 Event::Eof => {
259 return Err(Lib3mfError::Validation(
260 "Unexpected EOF in KeyInfo".to_string(),
261 ));
262 }
263 _ => None,
264 };
265
266 if let Some((local_name, raw_name)) = evt_info {
267 match local_name.as_slice() {
268 b"KeyName" => {
269 let val = parser.read_text_content()?;
270 info.key_name = Some(val);
271 }
272 b"KeyValue" => {
273 info.key_value = Some(parse_key_value(parser)?);
274 }
275 b"X509Data" => {
276 info.x509_data = Some(parse_x509_data(parser)?);
277 }
278 _ => {
279 parser.read_to_end(&raw_name)?;
280 }
281 }
282 }
283 }
284}
285
286fn parse_x509_data<R: BufRead>(parser: &mut XmlParser<R>) -> Result<X509Data> {
287 let mut data = X509Data::default();
288 loop {
289 let evt_info = match parser.read_next_event()? {
290 Event::Start(e) => Some((e.local_name().as_ref().to_vec(), e.name().as_ref().to_vec())),
291 Event::End(e) if e.local_name().as_ref() == b"X509Data" => return Ok(data),
292 Event::Eof => {
293 return Err(Lib3mfError::Validation(
294 "Unexpected EOF in X509Data".to_string(),
295 ));
296 }
297 _ => None,
298 };
299
300 if let Some((local_name, raw_name)) = evt_info {
301 match local_name.as_slice() {
302 b"X509Certificate" => {
303 let val = parser.read_text_content()?;
305 let cleaned = val.chars().filter(|c| !c.is_whitespace()).collect();
307 data.certificate = Some(cleaned);
308 }
309 _ => {
310 parser.read_to_end(&raw_name)?;
311 }
312 }
313 }
314 }
315}
316
317fn parse_key_value<R: BufRead>(parser: &mut XmlParser<R>) -> Result<KeyValue> {
318 let mut val = KeyValue::default();
319 loop {
320 let evt_info = match parser.read_next_event()? {
321 Event::Start(e) => Some((e.local_name().as_ref().to_vec(), e.name().as_ref().to_vec())),
322 Event::End(e) if e.local_name().as_ref() == b"KeyValue" => return Ok(val),
323 Event::Eof => {
324 return Err(Lib3mfError::Validation(
325 "Unexpected EOF in KeyValue".to_string(),
326 ));
327 }
328 _ => None,
329 };
330
331 if let Some((local_name, raw_name)) = evt_info {
332 match local_name.as_slice() {
333 b"RSAKeyValue" => {
334 val.rsa_key_value = Some(parse_rsa_key_value(parser)?);
335 }
336 _ => {
337 parser.read_to_end(&raw_name)?;
338 }
339 }
340 }
341 }
342}
343
344fn parse_rsa_key_value<R: BufRead>(parser: &mut XmlParser<R>) -> Result<RSAKeyValue> {
345 let mut modulus = String::new();
346 let mut exponent = String::new();
347
348 loop {
349 let evt_info = match parser.read_next_event()? {
350 Event::Start(e) => Some((e.local_name().as_ref().to_vec(), e.name().as_ref().to_vec())),
351 Event::End(e) if e.local_name().as_ref() == b"RSAKeyValue" => {
352 return Ok(RSAKeyValue { modulus, exponent });
353 }
354 Event::Eof => {
355 return Err(Lib3mfError::Validation(
356 "Unexpected EOF in RSAKeyValue".to_string(),
357 ));
358 }
359 _ => None,
360 };
361
362 if let Some((local_name, raw_name)) = evt_info {
363 match local_name.as_slice() {
364 b"Modulus" => modulus = parser.read_text_content()?,
365 b"Exponent" => exponent = parser.read_text_content()?,
366 _ => {
367 parser.read_to_end(&raw_name)?;
368 }
369 }
370 }
371 }
372}