structured_cms/timestamp/
request_fields.rs1use super::{ImprintOperand, Request, TokenInfo};
4use crate::{Error, Result};
5use structured_asn1::{Reader, memory::Work};
6
7#[derive(Debug)]
9pub struct RequestFieldError {
10 pub operand: ImprintOperand,
12 pub source: Error,
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub struct RequestFields {
19 pub nonce: Option<bool>,
21 pub policy: Option<bool>,
23}
24
25impl TokenInfo<'_> {
26 pub fn matches_request_fields(
34 &self,
35 requested: &Request<'_>,
36 token_parent: &Reader<'_>,
37 requested_parent: &Reader<'_>,
38 ) -> core::result::Result<RequestFields, RequestFieldError> {
39 self.imprint()
40 .require_session(token_parent)
41 .map_err(|source| RequestFieldError {
42 operand: ImprintOperand::Token,
43 source,
44 })?;
45 requested
46 .imprint()
47 .require_session(requested_parent)
48 .map_err(|source| RequestFieldError {
49 operand: ImprintOperand::Requested,
50 source,
51 })?;
52 token_parent
53 .execution()
54 .charge_work(3)
55 .map_err(|reason| RequestFieldError {
56 operand: ImprintOperand::Token,
57 source: Error::resource(reason, "tstInfo", self.span().start),
58 })?;
59 let compare = |left: &[u8], right: &[u8], field, at| {
60 same(left, right, token_parent, field, at).map_err(|source| RequestFieldError {
61 operand: ImprintOperand::Token,
62 source,
63 })
64 };
65 let nonce = match requested.nonce() {
66 None => None,
67 Some(asked) => Some(match self.nonce() {
68 None => false,
69 Some(written) => compare(
70 written.value().as_bytes(),
71 asked.as_bytes(),
72 "tstInfo.nonce",
73 written.element().span().start,
74 )?,
75 }),
76 };
77 let policy = match requested.policy() {
78 None => None,
79 Some(asked) => Some(compare(
80 self.policy().as_bytes(),
81 asked.as_bytes(),
82 "tstInfo.policy",
83 self.span().start,
84 )?),
85 };
86 Ok(RequestFields { nonce, policy })
87 }
88}
89
90fn same(
91 left: &[u8],
92 right: &[u8],
93 parent: &Reader<'_>,
94 field: &'static str,
95 at: u64,
96) -> Result<bool> {
97 parent
98 .execution()
99 .charge_work(1 + left.len().min(right.len()) as u64)
100 .map_err(|reason| Error::resource(reason, field, at))?;
101 Ok(left == right)
102}