structured_cms/timestamp/
tsa.rs1use super::record;
4use crate::{Error, ErrorCode, Result};
5use structured_asn1::memory::{OwnedVec, Work};
6use structured_asn1::{Element, Reader, Span};
7use structured_pkix::general_name::{self, GeneralName};
8
9const FIELD: &str = "tstInfo.tsa";
10
11#[derive(Debug)]
14pub struct TsaReading<'a> {
15 wrapper: Element<'a>,
16 element: Option<Element<'a>>,
17 name: Option<GeneralName<'a>>,
18}
19
20impl<'a> TsaReading<'a> {
21 pub(super) fn read<W: Work>(
22 parent: &Reader<'a>,
23 wrapper: &Element<'a>,
24 faults: &mut OwnedVec<Error, W>,
25 ) -> Result<Self> {
26 let mut inside = parent
27 .enter(wrapper)
28 .map_err(|error| Error::encoding(error, FIELD))?;
29 let first = match inside
30 .next_element()
31 .map_err(|error| Error::encoding(error, FIELD))
32 {
33 Ok(Some(first)) => first,
34 Ok(None) => {
35 record(
36 faults,
37 Error::schema(ErrorCode::MissingField, FIELD, wrapper.span().start),
38 )?;
39 return Ok(Self {
40 wrapper: *wrapper,
41 element: None,
42 name: None,
43 });
44 }
45 Err(error) => {
46 record(faults, error)?;
47 return Ok(Self {
48 wrapper: *wrapper,
49 element: None,
50 name: None,
51 });
52 }
53 };
54 let reading = match general_name::read(&inside, &first, FIELD).map_err(Error::pkix) {
55 Ok(name) => Ok(name),
56 Err(error) if error.is_terminal() => return Err(error),
57 Err(error) => Err(error),
58 };
59 let mut duplicate = None;
60 while let Some(extra) = inside
61 .next_element()
62 .map_err(|error| Error::encoding(error, FIELD))?
63 {
64 let at = extra.span().start;
65 inside
66 .execution()
67 .charge_work(1 + first.as_bytes().len().min(extra.as_bytes().len()) as u64)
68 .map_err(|reason| Error::resource(reason, FIELD, at))?;
69 if first.as_bytes() != extra.as_bytes() && !same_name(&inside, &reading, &extra)? {
70 return Err(Error::schema(ErrorCode::TrailingData, FIELD, at));
71 }
72 duplicate.get_or_insert(at);
73 }
74 if let Some(at) = duplicate {
75 record(faults, Error::schema(ErrorCode::DuplicateField, FIELD, at))?;
76 }
77 let name = match reading {
78 Ok(name) => Some(name),
79 Err(error) => {
80 record(faults, error)?;
81 None
82 }
83 };
84 Ok(Self {
85 wrapper: *wrapper,
86 element: Some(first),
87 name,
88 })
89 }
90
91 #[must_use]
93 pub fn span(&self) -> Span {
94 self.wrapper.span()
95 }
96 #[must_use]
98 pub fn element(&self) -> Option<&Element<'a>> {
99 self.element.as_ref()
100 }
101 #[must_use]
103 pub fn name(&self) -> Option<&GeneralName<'a>> {
104 self.name.as_ref()
105 }
106}
107
108fn same_name(
109 parent: &Reader<'_>,
110 first: &Result<GeneralName<'_>>,
111 extra: &Element<'_>,
112) -> Result<bool> {
113 let Ok(first) = first else {
114 return Ok(false);
115 };
116 let other = match general_name::read(parent, extra, FIELD).map_err(Error::pkix) {
117 Ok(other) => other,
118 Err(error) if error.is_terminal() => return Err(error),
119 Err(_) => return Ok(false),
120 };
121 general_name::matches(parent, first, &other, extra.span().start, FIELD).map_err(Error::pkix)
122}