structured_cms/timestamp/
response.rs1use super::Token;
9use crate::{Error, ErrorCode, Result, signer::required};
10use structured_asn1::memory::{OwnedVec, Work};
11use structured_asn1::{Element, Encoding, Parser, Reader, Span, Tag, universal};
12
13mod check;
14pub use check::CheckedResponse;
15
16const FIELD: &str = "timeStampResp";
17const STATUS: &str = "pkiStatusInfo";
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21#[repr(u8)]
22pub enum Status {
23 Granted = 0,
25 GrantedWithMods = 1,
27 Rejection = 2,
29 Waiting = 3,
31 RevocationWarning = 4,
33 RevocationNotification = 5,
35}
36impl Status {
37 #[must_use]
39 pub fn granted(self) -> bool {
40 matches!(self, Self::Granted | Self::GrantedWithMods)
41 }
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46#[repr(u8)]
47pub enum Failure {
48 BadAlgorithm = 0,
50 BadRequest = 2,
52 BadDataFormat = 5,
54 TimeNotAvailable = 14,
56 UnacceptedPolicy = 15,
58 UnacceptedExtension = 16,
60 AdditionalInformationUnavailable = 17,
62 SystemFailure = 25,
64}
65
66#[derive(Debug, Clone, Copy)]
68pub struct FailureInfo<'a> {
69 element: Element<'a>,
70 flags: u32,
71}
72impl<'a> FailureInfo<'a> {
73 #[must_use]
75 pub fn contains(self, reason: Failure) -> bool {
76 self.flags & (1u32 << reason as u8) != 0
77 }
78 #[must_use]
80 pub fn element(self) -> Element<'a> {
81 self.element
82 }
83 fn read(parent: &Reader<'a>, element: Element<'a>) -> Result<Self> {
84 const FIELD: &str = "pkiStatusInfo.failInfo";
85 const KNOWN: u32 = (1 << Failure::BadAlgorithm as u8)
86 | (1 << Failure::BadRequest as u8)
87 | (1 << Failure::BadDataFormat as u8)
88 | (1 << Failure::TimeNotAvailable as u8)
89 | (1 << Failure::UnacceptedPolicy as u8)
90 | (1 << Failure::UnacceptedExtension as u8)
91 | (1 << Failure::AdditionalInformationUnavailable as u8)
92 | (1 << Failure::SystemFailure as u8);
93 tag(&element, Tag::primitive(universal::BIT_STRING), FIELD)?;
94 let bits = parent
95 .bit_string(&element)
96 .map_err(|e| Error::encoding(e, FIELD))?;
97 let bytes = bits.as_bytes();
98 parent
99 .charge(1 + bytes.len() as u64)
100 .map_err(|e| Error::encoding(e, FIELD))?;
101 if let Some(last) = bytes.last()
105 && (*last == 0 || last.trailing_zeros() != u32::from(bits.unused_bits()))
106 {
107 return Err(Error::schema(
108 ErrorCode::MalformedValue,
109 FIELD,
110 element.span().start,
111 ));
112 }
113 if bytes.len() > 4 {
114 return Err(Error::schema(
115 ErrorCode::UnknownField,
116 FIELD,
117 element.span().start,
118 ));
119 }
120 let mut flags = 0u32;
121 for (index, byte) in bytes.iter().enumerate() {
122 flags |= u32::from(byte.reverse_bits()) << (index * 8);
123 }
124 if flags & !KNOWN != 0 {
127 return Err(Error::schema(
128 ErrorCode::UnknownField,
129 FIELD,
130 element.span().start,
131 ));
132 }
133 Ok(Self { element, flags })
134 }
135}
136
137#[derive(Debug, Clone, Copy)]
139pub struct StatusText<'a> {
140 value: &'a str,
141 span: Span,
142}
143impl<'a> StatusText<'a> {
144 #[must_use]
146 pub fn as_str(self) -> &'a str {
147 self.value
148 }
149 #[must_use]
151 pub fn span(self) -> Span {
152 self.span
153 }
154}
155
156#[derive(Debug)]
158pub struct StatusInfo<'a> {
159 status: Status,
160 text: Option<OwnedVec<StatusText<'a>>>,
161 failure: Option<FailureInfo<'a>>,
162 span: Span,
163}
164impl<'a> StatusInfo<'a> {
165 #[must_use]
167 pub fn status(&self) -> Status {
168 self.status
169 }
170 #[must_use]
172 pub fn text(&self) -> Option<&[StatusText<'a>]> {
173 self.text.as_deref()
174 }
175 #[must_use]
177 pub fn failure(&self) -> Option<FailureInfo<'a>> {
178 self.failure
179 }
180 #[must_use]
182 pub fn span(&self) -> Span {
183 self.span
184 }
185 fn read(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
186 tag(element, Tag::constructed(universal::SEQUENCE), STATUS)?;
187 let mut inside = parent
188 .enter(element)
189 .map_err(|e| Error::encoding(e, STATUS))?;
190 let status_element = required(&mut inside, "pkiStatusInfo.status")?;
191 tag(
192 &status_element,
193 Tag::primitive(universal::INTEGER),
194 "pkiStatusInfo.status",
195 )?;
196 let status = inside
197 .integer(&status_element)
198 .map_err(|e| Error::encoding(e, "pkiStatusInfo.status"))?;
199 let status = match status.as_u64() {
200 Some(0) => Status::Granted,
201 Some(1) => Status::GrantedWithMods,
202 Some(2) => Status::Rejection,
203 Some(3) => Status::Waiting,
204 Some(4) => Status::RevocationWarning,
205 Some(5) => Status::RevocationNotification,
206 _ => {
207 return Err(Error::schema(
208 ErrorCode::MalformedValue,
209 "pkiStatusInfo.status",
210 status_element.span().start,
211 ));
212 }
213 };
214 let mut next = inside
215 .next_element()
216 .map_err(|e| Error::encoding(e, STATUS))?;
217 let text = if let Some(element) = next
218 .as_ref()
219 .filter(|e| e.tag() == Tag::constructed(universal::SEQUENCE))
220 {
221 let values = read_text(&inside, element)?;
222 next = inside
223 .next_element()
224 .map_err(|e| Error::encoding(e, STATUS))?;
225 Some(values)
226 } else {
227 None
228 };
229 let failure = next
230 .map(|element| FailureInfo::read(&inside, element))
231 .transpose()?;
232 end(&inside, STATUS)?;
233 Ok(Self {
234 status,
235 text,
236 failure,
237 span: element.span(),
238 })
239 }
240}
241
242#[derive(Debug)]
257pub struct Response<'a> {
258 status: StatusInfo<'a>,
259 token: Option<OriginalToken<'a>>,
260 element: Element<'a>,
261 parser: &'a Parser,
262 token_depth: u32,
263}
264
265#[derive(Debug)]
266struct OriginalToken<'a> {
267 value: Token<'a>,
268 element: Element<'a>,
269}
270impl<'a> Response<'a> {
271 pub fn read(parent: &mut Reader<'a>) -> Result<Self> {
273 let element = parent
274 .expect(Tag::constructed(universal::SEQUENCE))
275 .map_err(|e| Error::encoding(e, FIELD))?;
276 end(parent, FIELD)?;
277 Self::read_element(parent, &element)
278 }
279 pub fn read_element(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
282 let mut strict = parent
283 .reread(element, Encoding::Der)
284 .map_err(|e| Error::encoding(e, FIELD))?;
285 let element = strict
286 .expect(Tag::constructed(universal::SEQUENCE))
287 .map_err(|e| Error::encoding(e, FIELD))?;
288 structured_pkix::der::conforms(&strict, &element, FIELD).map_err(Error::pkix)?;
289 let mut inside = strict
290 .enter(&element)
291 .map_err(|e| Error::encoding(e, FIELD))?;
292 let status_element = required(&mut inside, STATUS)?;
293 let status = StatusInfo::read(&inside, &status_element)?;
294 let token_element = inside
295 .next_element()
296 .map_err(|e| Error::encoding(e, FIELD))?;
297 end(&inside, FIELD)?;
298 if status.status.granted() != token_element.is_some() {
301 return Err(Error::schema(
302 ErrorCode::MalformedValue,
303 FIELD,
304 element.span().start,
305 ));
306 }
307 let token = token_element
308 .as_ref()
309 .map(|element| {
310 let mut reader = inside
311 .reread(element, Encoding::Der)
312 .map_err(|e| Error::encoding(e, FIELD))?;
313 Token::read_from(&mut reader).map(|value| OriginalToken {
314 value,
315 element: *element,
316 })
317 })
318 .transpose()?;
319 Ok(Self {
320 status,
321 token,
322 element,
323 parser: parent.parser(),
324 token_depth: inside.depth(),
325 })
326 }
327 #[must_use]
329 pub fn status(&self) -> &StatusInfo<'a> {
330 &self.status
331 }
332 #[must_use]
334 pub fn token(&self) -> Option<&Token<'a>> {
335 self.token.as_ref().map(|token| &token.value)
336 }
337 #[must_use]
339 pub fn element(&self) -> &Element<'a> {
340 &self.element
341 }
342 pub fn token_reader_in<'op>(&self, query: &Reader<'op>) -> Result<Option<Reader<'op>>>
345 where
346 'a: 'op,
347 {
348 self.token_in(query)
349 .map(|value| value.map(|(_, reader)| reader))
350 }
351
352 fn token_in<'op>(&self, query: &Reader<'op>) -> Result<Option<(&Token<'a>, Reader<'op>)>>
353 where
354 'a: 'op,
355 {
356 query
357 .execution()
358 .execution_for(self.parser)
359 .charge_work(1)
360 .map_err(|e| Error::resource(e, FIELD, self.element.span().start))?;
361 self.token
362 .as_ref()
363 .map(|token| {
364 self.parser
365 .read_query_in(
366 query,
367 token.element.as_bytes(),
368 token.element.span().start,
369 Encoding::Der,
370 self.token_depth,
371 )
372 .map(|reader| (&token.value, reader))
373 .map_err(|e| Error::encoding(e, FIELD))
374 })
375 .transpose()
376 }
377}
378
379fn read_text<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<OwnedVec<StatusText<'a>>> {
380 const FIELD: &str = "pkiStatusInfo.statusString";
381 let mut inside = parent
382 .enter(element)
383 .map_err(|e| Error::encoding(e, FIELD))?;
384 let work = parent.execution();
385 let mut text = work.vector();
386 while let Some(element) = inside
387 .next_element()
388 .map_err(|e| Error::encoding(e, FIELD))?
389 {
390 tag(&element, Tag::primitive(universal::UTF8_STRING), FIELD)?;
391 inside
392 .charge(element.contents().len() as u64)
393 .map_err(|e| Error::encoding(e, FIELD))?;
394 let value = core::str::from_utf8(element.contents())
395 .map_err(|_| Error::schema(ErrorCode::MalformedValue, FIELD, element.span().start))?;
396 text.try_push(StatusText {
397 value,
398 span: element.span(),
399 })
400 .map_err(|e| Error::resource(e, FIELD, element.span().start))?;
401 }
402 if text.is_empty() {
405 return Err(Error::schema(
406 ErrorCode::MissingField,
407 FIELD,
408 element.span().start,
409 ));
410 }
411 Ok(text.into_owned())
412}
413fn tag(element: &Element<'_>, expected: Tag, field: &'static str) -> Result<()> {
414 if element.tag() == expected {
415 Ok(())
416 } else {
417 Err(Error::schema(
418 ErrorCode::UnexpectedTag,
419 field,
420 element.span().start,
421 ))
422 }
423}
424fn end(parent: &Reader<'_>, field: &'static str) -> Result<()> {
425 if parent.is_empty() {
426 Ok(())
427 } else {
428 Err(Error::schema(
429 ErrorCode::TrailingData,
430 field,
431 parent.offset(),
432 ))
433 }
434}