structured_cms/timestamp/
carried.rs1use super::{ImprintOperand, Request, RequestFieldError, Token};
4use crate::{Error, ErrorCode};
5use structured_asn1::{Reader, memory::Work};
6use structured_pkix::Certificate;
7
8impl Token<'_> {
9 pub fn matches_cert_req(
18 &self,
19 requested: &Request<'_>,
20 selected: Option<&Certificate<'_>>,
21 token_parent: &Reader<'_>,
22 request_parent: &Reader<'_>,
23 ) -> Result<bool, RequestFieldError> {
24 self.signer()
25 .require_session(token_parent, "signedData.certificates")
26 .map_err(|source| RequestFieldError {
27 operand: ImprintOperand::Token,
28 source,
29 })?;
30 if !requested.same_session(request_parent) {
31 return Err(RequestFieldError {
32 operand: ImprintOperand::Requested,
33 source: Error::pkix(structured_pkix::Error::new(
34 structured_pkix::ErrorCode::ForeignReader,
35 "timeStampReq.certReq",
36 requested.span().start,
37 )),
38 });
39 }
40 let work = token_parent.execution();
41 let at = self
42 .message()
43 .certificate_field()
44 .map_or(self.message().span().start, |span| span.start);
45 let failure = |reason| RequestFieldError {
46 operand: ImprintOperand::Token,
47 source: Error::resource(reason, "signedData.certificates", at),
48 };
49 work.charge_work(1).map_err(failure)?;
50 if !requested.cert_req() {
51 return Ok(self.message().certificate_field().is_none());
52 }
53 let Some(selected) = selected else {
54 return Ok(false);
55 };
56 for carried in self.message().certificates() {
57 work.charge_work(1).map_err(failure)?;
58 let original = selected.as_bytes();
59 let written = carried.as_bytes();
60 if original.len() != written.len() {
61 continue;
62 }
63 let length = u64::try_from(original.len()).map_err(|_| RequestFieldError {
64 operand: ImprintOperand::Token,
65 source: Error::schema(ErrorCode::LengthOverflow, "signedData.certificates", at),
66 })?;
67 work.charge_work(length).map_err(failure)?;
68 if original == written {
69 return Ok(true);
70 }
71 }
72 Ok(false)
73 }
74}