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]
341 pub fn token_element(&self) -> Option<&Element<'a>> {
342 self.token.as_ref().map(|token| &token.element)
343 }
344 #[must_use]
346 pub fn element(&self) -> &Element<'a> {
347 &self.element
348 }
349 pub fn token_reader_in<'op>(&self, query: &Reader<'op>) -> Result<Option<Reader<'op>>>
352 where
353 'a: 'op,
354 {
355 self.token_in(query)
356 .map(|value| value.map(|(_, reader)| reader))
357 }
358
359 fn token_in<'op>(&self, query: &Reader<'op>) -> Result<Option<(&Token<'a>, Reader<'op>)>>
360 where
361 'a: 'op,
362 {
363 query
364 .execution()
365 .execution_for(self.parser)
366 .charge_work(1)
367 .map_err(|e| Error::resource(e, FIELD, self.element.span().start))?;
368 self.token
369 .as_ref()
370 .map(|token| {
371 self.parser
372 .read_query_in(
373 query,
374 token.element.as_bytes(),
375 token.element.span().start,
376 Encoding::Der,
377 self.token_depth,
378 )
379 .map(|reader| (&token.value, reader))
380 .map_err(|e| Error::encoding(e, FIELD))
381 })
382 .transpose()
383 }
384}
385
386fn read_text<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<OwnedVec<StatusText<'a>>> {
387 const FIELD: &str = "pkiStatusInfo.statusString";
388 let mut inside = parent
389 .enter(element)
390 .map_err(|e| Error::encoding(e, FIELD))?;
391 let work = parent.execution();
392 let mut text = work.vector();
393 while let Some(element) = inside
394 .next_element()
395 .map_err(|e| Error::encoding(e, FIELD))?
396 {
397 tag(&element, Tag::primitive(universal::UTF8_STRING), FIELD)?;
398 inside
399 .charge(element.contents().len() as u64)
400 .map_err(|e| Error::encoding(e, FIELD))?;
401 let value = core::str::from_utf8(element.contents())
402 .map_err(|_| Error::schema(ErrorCode::MalformedValue, FIELD, element.span().start))?;
403 text.try_push(StatusText {
404 value,
405 span: element.span(),
406 })
407 .map_err(|e| Error::resource(e, FIELD, element.span().start))?;
408 }
409 if text.is_empty() {
412 return Err(Error::schema(
413 ErrorCode::MissingField,
414 FIELD,
415 element.span().start,
416 ));
417 }
418 Ok(text.into_owned())
419}
420fn tag(element: &Element<'_>, expected: Tag, field: &'static str) -> Result<()> {
421 if element.tag() == expected {
422 Ok(())
423 } else {
424 Err(Error::schema(
425 ErrorCode::UnexpectedTag,
426 field,
427 element.span().start,
428 ))
429 }
430}
431fn end(parent: &Reader<'_>, field: &'static str) -> Result<()> {
432 if parent.is_empty() {
433 Ok(())
434 } else {
435 Err(Error::schema(
436 ErrorCode::TrailingData,
437 field,
438 parent.offset(),
439 ))
440 }
441}