structured_cms/
content.rs1use crate::{Error, ErrorCode, Octets, Result};
4use structured_asn1::{Element, Oid, Reader, Span, Tag, universal};
5
6#[derive(Debug)]
12pub struct ContentInfo<'a> {
13 kind: Oid<'a>,
14 content: Element<'a>,
15 wrapper: Element<'a>,
16 span: Span,
17}
18
19impl<'a> ContentInfo<'a> {
20 pub fn read(reader: &mut Reader<'a>) -> Result<(Self, Reader<'a>)> {
27 let outer = reader
28 .expect(Tag::constructed(universal::SEQUENCE))
29 .map_err(|error| Error::encoding(error, "contentInfo"))?;
30 let result = Self::read_element(reader, &outer)?;
31 if !reader.is_empty() {
32 return Err(Error::schema(
33 ErrorCode::TrailingData,
34 "contentInfo",
35 reader.offset(),
36 ));
37 }
38 Ok(result)
39 }
40
41 pub fn read_element(parent: &Reader<'a>, element: &Element<'a>) -> Result<(Self, Reader<'a>)> {
46 const FIELD: &str = "contentInfo";
47 if element.tag() != Tag::constructed(universal::SEQUENCE) {
48 return Err(Error::schema(
49 ErrorCode::UnexpectedTag,
50 FIELD,
51 element.span().start,
52 ));
53 }
54 let mut inside = parent
55 .enter(element)
56 .map_err(|error| Error::encoding(error, FIELD))?;
57 let kind = inside
58 .read_oid()
59 .map_err(|error| Error::encoding(error, "contentInfo.contentType"))?;
60 let wrapper = inside
65 .expect(Tag::context(true, 0))
66 .map_err(|error| Error::encoding(error, "contentInfo.content"))?;
67 let mut explicit = inside
68 .enter(&wrapper)
69 .map_err(|error| Error::encoding(error, "contentInfo.content"))?;
70 let content = explicit
71 .next_element()
72 .map_err(|error| Error::encoding(error, "contentInfo.content"))?
73 .ok_or_else(|| {
74 Error::schema(
75 ErrorCode::MissingField,
76 "contentInfo.content",
77 wrapper.span().start,
78 )
79 })?;
80 if !explicit.is_empty() {
81 return Err(Error::schema(
82 ErrorCode::TrailingData,
83 "contentInfo.content",
84 explicit.offset(),
85 ));
86 }
87 if !inside.is_empty() {
88 return Err(Error::schema(
89 ErrorCode::TrailingData,
90 FIELD,
91 inside.offset(),
92 ));
93 }
94 Ok((
95 Self {
96 kind,
97 content,
98 wrapper,
99 span: element.span(),
100 },
101 explicit,
102 ))
103 }
104
105 #[must_use]
107 pub fn kind(&self) -> Oid<'a> {
108 self.kind
109 }
110 #[must_use]
113 pub fn content_wrapper(&self) -> Element<'a> {
114 self.wrapper
115 }
116
117 #[must_use]
119 pub fn content(&self) -> &Element<'a> {
120 &self.content
121 }
122
123 #[must_use]
125 pub fn span(&self) -> Span {
126 self.span
127 }
128}
129
130#[derive(Debug)]
132pub struct Encapsulated<'a> {
133 kind: Oid<'a>,
134 kind_encoding: &'a [u8],
135 content: Option<Octets<'a>>,
136 span: Span,
137}
138
139impl<'a> Encapsulated<'a> {
140 pub fn read(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
145 const FIELD: &str = "signedData.encapContentInfo";
146 const KIND: &str = "signedData.encapContentInfo.eContentType";
147 if element.tag() != Tag::constructed(universal::SEQUENCE) {
148 return Err(Error::schema(
149 ErrorCode::UnexpectedTag,
150 FIELD,
151 element.span().start,
152 ));
153 }
154 let mut inside = parent
155 .enter(element)
156 .map_err(|error| Error::encoding(error, FIELD))?;
157 let kind_element = inside
158 .expect(Tag::primitive(universal::OID))
159 .map_err(|error| Error::encoding(error, KIND))?;
160 let kind = inside
161 .oid(&kind_element)
162 .map_err(|error| Error::encoding(error, KIND))?;
163 let content = if let Some(wrapper) = inside
164 .next_element()
165 .map_err(|error| Error::encoding(error, FIELD))?
166 {
167 const CONTENT: &str = "signedData.encapContentInfo.eContent";
168 if wrapper.tag() != Tag::context(true, 0) {
169 return Err(Error::schema(
170 ErrorCode::UnexpectedTag,
171 CONTENT,
172 wrapper.span().start,
173 ));
174 }
175 let mut explicit = inside
176 .enter(&wrapper)
177 .map_err(|error| Error::encoding(error, CONTENT))?;
178 let octets = explicit
179 .next_element()
180 .map_err(|error| Error::encoding(error, CONTENT))?
181 .ok_or_else(|| {
182 Error::schema(ErrorCode::MissingField, CONTENT, wrapper.span().start)
183 })?;
184 let content = Octets::read(&explicit, &octets, CONTENT)?;
185 if !explicit.is_empty() {
186 return Err(Error::schema(
187 ErrorCode::TrailingData,
188 CONTENT,
189 explicit.offset(),
190 ));
191 }
192 Some(content)
193 } else {
194 None
195 };
196 if !inside.is_empty() {
197 return Err(Error::schema(
198 ErrorCode::TrailingData,
199 FIELD,
200 inside.offset(),
201 ));
202 }
203 Ok(Self {
204 kind,
205 kind_encoding: kind_element.as_bytes(),
206 content,
207 span: element.span(),
208 })
209 }
210
211 #[must_use]
213 pub fn kind(&self) -> Oid<'a> {
214 self.kind
215 }
216
217 #[must_use]
219 pub fn kind_encoding(&self) -> &'a [u8] {
220 self.kind_encoding
221 }
222
223 #[must_use]
225 pub fn content(&self) -> Option<&Octets<'a>> {
226 self.content.as_ref()
227 }
228
229 #[must_use]
231 pub fn is_detached(&self) -> bool {
232 self.content.is_none()
233 }
234
235 #[must_use]
237 pub fn span(&self) -> Span {
238 self.span
239 }
240}