structured_cms/timestamp/
imprint.rs1use super::record;
4use crate::{Error, ErrorCode, Octets, Result};
5use structured_asn1::memory::{OwnedVec, Work};
6use structured_asn1::{Element, Oid, Reader, Span, Tag, universal};
7use structured_pkix::AlgorithmIdentifier;
8
9#[derive(Debug, Clone, Copy)]
10pub(super) struct ImprintFields {
11 pub enclosing: &'static str,
12 pub algorithm: &'static str,
13 pub hashed: &'static str,
14}
15
16const TOKEN: ImprintFields = ImprintFields {
17 enclosing: "tstInfo.messageImprint",
18 algorithm: "tstInfo.messageImprint.hashAlgorithm",
19 hashed: "tstInfo.messageImprint.hashedMessage",
20};
21
22#[derive(Debug)]
24pub enum HashAlgorithmReading<'a> {
25 Identifier(AlgorithmIdentifier<'a>),
27 Malformed {
29 element: Element<'a>,
31 kind: Option<Oid<'a>>,
33 },
34}
35
36#[derive(Debug)]
39pub struct MessageImprint<'a> {
40 algorithm: HashAlgorithmReading<'a>,
41 hashed: Octets<'a>,
42 faults: OwnedVec<Error>,
43 span: Span,
44 fields: ImprintFields,
45}
46
47impl<'a> MessageImprint<'a> {
48 pub fn read(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
58 Self::read_fields(parent, element, TOKEN)
59 }
60
61 pub(super) fn read_fields(
62 parent: &Reader<'a>,
63 element: &Element<'a>,
64 fields: ImprintFields,
65 ) -> Result<Self> {
66 if element.tag() != Tag::constructed(universal::SEQUENCE) {
67 return Err(Error::schema(
68 ErrorCode::UnexpectedTag,
69 fields.enclosing,
70 element.span().start,
71 ));
72 }
73 let mut inside = parent
74 .enter(element)
75 .map_err(|error| Error::encoding(error, fields.enclosing))?;
76 let written = crate::signer::required(&mut inside, fields.algorithm)?;
77 let execution = parent.execution();
78 let mut faults = execution.vector();
79 let algorithm = if written.tag() == Tag::constructed(universal::SEQUENCE) {
80 match structured_pkix::algorithm::read(&inside, &written, fields.algorithm)
81 .map_err(Error::pkix)
82 {
83 Ok(identifier) => HashAlgorithmReading::Identifier(identifier),
84 Err(error) if error.is_terminal() => return Err(error),
85 Err(error) => {
86 record(&mut faults, error)?;
87 HashAlgorithmReading::Malformed {
88 element: written,
89 kind: None,
90 }
91 }
92 }
93 } else {
94 let kind = if written.tag() == Tag::primitive(universal::OID) {
95 match inside
96 .oid(&written)
97 .map_err(|error| Error::encoding(error, fields.algorithm))
98 {
99 Ok(kind) => Some(kind),
100 Err(error) if error.is_terminal() => return Err(error),
101 Err(error) => {
102 record(&mut faults, error)?;
103 None
104 }
105 }
106 } else {
107 None
108 };
109 record(
110 &mut faults,
111 Error::schema(
112 ErrorCode::MalformedValue,
113 fields.algorithm,
114 written.span().start,
115 ),
116 )?;
117 HashAlgorithmReading::Malformed {
118 element: written,
119 kind,
120 }
121 };
122 let hashed = crate::signer::required(&mut inside, fields.hashed)?;
123 let hashed = Octets::read(&inside, &hashed, fields.hashed)?;
124 if !inside.is_empty() {
125 record(
126 &mut faults,
127 Error::schema(ErrorCode::TrailingData, fields.enclosing, inside.offset()),
128 )?;
129 }
130 Ok(Self {
131 algorithm,
132 hashed,
133 faults: faults.into_owned(),
134 span: element.span(),
135 fields,
136 })
137 }
138
139 #[must_use]
141 pub fn algorithm(&self) -> &HashAlgorithmReading<'a> {
142 &self.algorithm
143 }
144 #[must_use]
146 pub fn hashed(&self) -> &Octets<'a> {
147 &self.hashed
148 }
149 #[must_use]
151 pub fn span(&self) -> Span {
152 self.span
153 }
154 #[must_use]
156 pub fn faults(&self) -> &[Error] {
157 &self.faults
158 }
159 pub(super) fn fields(&self) -> ImprintFields {
160 self.fields
161 }
162}