structured_pkix/ocsp/
lookup.rs1use super::{BasicResponse, CertId, CertMatch, SignedResponse, SingleResponse};
4use crate::algorithm::digest::AsnDigest;
5use crate::error::{CallbackResult, Error};
6use crate::{Certificate, revocation::RevocationTarget};
7use structured_asn1::memory::Work;
8
9#[derive(Debug, Clone, Copy)]
11pub enum Lookup<'r, 'a> {
12 Missing,
14 Found(&'r SingleResponse<'a>),
17 Ambiguous {
20 first: &'r SingleResponse<'a>,
22 second: &'r SingleResponse<'a>,
24 },
25 UnsupportedHash(&'r SingleResponse<'a>),
27 MalformedHashWidth(&'r SingleResponse<'a>),
29 MalformedHashAlgorithm(&'r SingleResponse<'a>),
31}
32
33impl<'r, 'a> SignedResponse<'r, 'a> {
34 pub fn find<'t, 'd, T: RevocationTarget<'t>, D: AsnDigest<'d> + ?Sized, E: Work>(
40 self,
41 target: &T,
42 issuer: &Certificate<'_>,
43 digest: &'d D,
44 execution: &E,
45 ) -> CallbackResult<Lookup<'r, 'a>, D::Error> {
46 locate(self.response(), execution, |id| {
47 id.matches(target, issuer, digest, execution)
48 })
49 }
50
51 pub fn find_id<'d, D: AsnDigest<'d> + ?Sized, E: Work>(
55 self,
56 requested: &CertId<'_>,
57 digest: &'d D,
58 execution: &E,
59 ) -> CallbackResult<Lookup<'r, 'a>, D::Error> {
60 locate(self.response(), execution, |id| {
61 id.matches_id(requested, digest, execution)
62 })
63 }
64}
65
66fn locate<'r, 'a, E, W: Work>(
67 original: &'r BasicResponse<'a>,
68 execution: &W,
69 mut compare: impl FnMut(CertId<'a>) -> CallbackResult<CertMatch, E>,
70) -> CallbackResult<Lookup<'r, 'a>, E> {
71 let execution = &original.signature_algorithm().query_in(execution);
72 let mut first = None;
73 for response in original.responses() {
74 execution.charge_work(1).map_err(|reason| {
75 Error::resource(reason, "ocspResponse.responses", response.span().start)
76 })?;
77 match compare(response.id())? {
78 CertMatch::Differs => {}
79 CertMatch::UnsupportedHash => return Ok(Lookup::UnsupportedHash(response)),
80 CertMatch::MalformedHashWidth => return Ok(Lookup::MalformedHashWidth(response)),
81 CertMatch::MalformedHashAlgorithm => {
82 return Ok(Lookup::MalformedHashAlgorithm(response));
83 }
84 CertMatch::Matches => match first {
85 None => first = Some(response),
86 Some(first) => {
87 return Ok(Lookup::Ambiguous {
88 first,
89 second: response,
90 });
91 }
92 },
93 }
94 }
95 Ok(match first {
96 Some(response) => Lookup::Found(response),
97 None => Lookup::Missing,
98 })
99}