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