1use crate::attribute::Attribute;
13use crate::signer::required;
14use crate::{Error, ErrorCode, Result};
15use structured_asn1::memory::{OwnedVec, SortError, Work};
16use structured_asn1::{
17 BitString, Element, Integer, Oid, Parser, Reader, ScopedReader, Tag, universal,
18};
19use structured_pkix::general_name::{self, GeneralName};
20use structured_pkix::signature::SignatureValue;
21use structured_pkix::{AlgorithmIdentifier, Extensions, Time};
22
23const FIELD: &str = "attributeCertificate";
24const INFO: &str = "attributeCertificate.acinfo";
25
26pub mod clearance;
27pub mod controls;
28pub mod encrypted;
29pub mod ietf;
30pub mod proxy;
31pub mod role;
32pub mod service;
33pub mod target;
34pub mod validation;
35fn sequence() -> Tag {
36 Tag::constructed(universal::SEQUENCE)
37}
38
39#[derive(Debug)]
41pub struct IssuerSerial<'a> {
42 pub issuer: OwnedVec<GeneralName<'a>>,
44 pub serial: Integer<'a>,
46 pub issuer_uid: Option<BitString<'a>>,
48}
49
50#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub enum DigestedObject {
53 PublicKey,
55 PublicKeyCertificate,
57 Other,
59}
60
61#[derive(Debug)]
63pub struct ObjectDigestInfo<'a> {
64 pub object_type: DigestedObject,
66 pub other_type: Option<Oid<'a>>,
68 pub algorithm: AlgorithmIdentifier<'a>,
70 pub digest: BitString<'a>,
72}
73
74#[derive(Debug)]
77pub struct Holder<'a> {
78 pub base_certificate: Option<IssuerSerial<'a>>,
80 pub entity_names: Option<OwnedVec<GeneralName<'a>>>,
82 pub object_digest: Option<ObjectDigestInfo<'a>>,
84}
85
86#[derive(Debug)]
88pub struct Issuer<'a> {
89 pub form: IssuerForm,
91 pub names: Option<OwnedVec<GeneralName<'a>>>,
93 pub base_certificate: Option<IssuerSerial<'a>>,
95 pub object_digest: Option<ObjectDigestInfo<'a>>,
97}
98
99#[derive(Debug, Clone, Copy, PartialEq, Eq)]
101pub enum IssuerForm {
102 V1,
104 V2,
106}
107
108#[derive(Debug)]
110pub struct Information<'a> {
111 pub holder: Holder<'a>,
113 pub issuer: Issuer<'a>,
115 pub signature: AlgorithmIdentifier<'a>,
117 pub serial: Integer<'a>,
119 pub not_before: Time,
121 pub not_after: Time,
123 pub attributes: OwnedVec<Attribute<'a>>,
125 pub issuer_uid: Option<BitString<'a>>,
127 pub extensions: Option<Extensions<'a>>,
129}
130
131#[derive(Debug)]
133pub struct AttributeCertificate<'a> {
134 parser: &'a Parser,
135 information: Information<'a>,
136 algorithm: AlgorithmIdentifier<'a>,
137 signature: SignatureValue<'a>,
138 signed: Element<'a>,
139 element: Element<'a>,
140}
141
142impl<'a> AttributeCertificate<'a> {
143 pub fn read(parent: &mut Reader<'a>) -> Result<Self> {
147 let element = required(parent, FIELD)?;
148 let value = Self::read_element(parent, &element)?;
149 end(parent, FIELD)?;
150 Ok(value)
151 }
152
153 pub fn read_element(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
155 tag(element, sequence(), FIELD)?;
156 Self::fields(parent, element)
157 }
158
159 pub fn read_implicit(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
163 tag(element, Tag::context(true, 2), FIELD)?;
164 Self::fields(parent, element)
165 }
166
167 fn fields(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
168 let mut inside = parent
169 .enter(element)
170 .map_err(|e| Error::encoding(e, FIELD))?;
171 let signed = required(&mut inside, INFO)?;
172 tag(&signed, sequence(), INFO)?;
173 let mut der = inside
177 .reread(&signed, structured_asn1::Encoding::Der)
178 .map_err(|e| Error::encoding(e, INFO))?;
179 let signed_der = required(&mut der, INFO)?;
180 let information = information(&der, &signed_der)?;
181 let encoded_algorithm = required(&mut inside, "attributeCertificate.signatureAlgorithm")?;
182 let algorithm = algorithm(
183 &inside,
184 &encoded_algorithm,
185 "attributeCertificate.signatureAlgorithm",
186 )?;
187 let signature = SignatureValue::read(&mut inside, "attributeCertificate.signatureValue")
188 .map_err(Error::pkix)?;
189 end(&inside, FIELD)?;
190 Ok(Self {
191 parser: parent.parser(),
192 information,
193 algorithm,
194 signature,
195 signed,
196 element: *element,
197 })
198 }
199
200 #[must_use]
202 pub fn information(&self) -> &Information<'a> {
203 &self.information
204 }
205
206 pub fn target_information<W: Work>(
211 &self,
212 work: &W,
213 ) -> Result<Option<target::TargetInformation<'a>>> {
214 let execution = work.execution_for(self.parser);
215 execution
216 .charge_work(1)
217 .map_err(|e| Error::resource(e, target::FIELD, self.element.span().start))?;
218 let Some(extensions) = &self.information.extensions else {
219 return Ok(None);
220 };
221 extensions
222 .get(target::IDENTIFIER, &execution)
223 .map_err(Error::pkix)?
224 .map(|extension| target::TargetInformation::read(extension, &execution))
225 .transpose()
226 }
227
228 #[must_use]
230 pub fn signed_bytes(&self) -> &'a [u8] {
231 self.signed.as_bytes()
232 }
233
234 #[must_use]
236 pub fn signed_element(&self) -> Element<'a> {
237 self.signed
238 }
239
240 #[must_use]
242 pub fn signature_algorithm(&self) -> AlgorithmIdentifier<'a> {
243 self.algorithm
244 }
245
246 #[must_use]
248 pub fn signature_value(&self) -> SignatureValue<'a> {
249 self.signature
250 }
251
252 #[must_use]
254 pub fn element(&self) -> Element<'a> {
255 self.element
256 }
257}
258
259fn information<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<Information<'a>> {
260 let mut inside = parent
261 .enter(element)
262 .map_err(|e| Error::encoding(e, INFO))?;
263 let version = integer(&mut inside, "attributeCertificate.version")?;
264 if version.as_u64() != Some(1) {
265 return Err(Error::schema(
266 ErrorCode::UnsupportedVersion,
267 "attributeCertificate.version",
268 element.contents_span().start,
269 ));
270 }
271 let holder_element = required(&mut inside, "attributeCertificate.holder")?;
272 tag(&holder_element, sequence(), "attributeCertificate.holder")?;
273 let holder = holder(&inside, &holder_element)?;
274 let issuer_element = required(&mut inside, "attributeCertificate.issuer")?;
275 let issuer = match issuer_element.tag() {
276 t if t == sequence() => Issuer {
277 form: IssuerForm::V1,
278 names: Some(names(
279 &inside,
280 &issuer_element,
281 "attributeCertificate.issuer",
282 )?),
283 base_certificate: None,
284 object_digest: None,
285 },
286 t if t == Tag::context(true, 0) => v2_form(&inside, &issuer_element)?,
287 _ => {
288 return Err(Error::schema(
289 ErrorCode::UnexpectedTag,
290 "attributeCertificate.issuer",
291 issuer_element.span().start,
292 ));
293 }
294 };
295 let signature_element = required(&mut inside, "attributeCertificate.acinfo.signature")?;
296 let signature = algorithm(
297 &inside,
298 &signature_element,
299 "attributeCertificate.acinfo.signature",
300 )?;
301 let serial = integer(&mut inside, "attributeCertificate.serialNumber")?;
302 let validity = required(&mut inside, "attributeCertificate.validity")?;
303 tag(&validity, sequence(), "attributeCertificate.validity")?;
304 let mut times = inside
305 .enter(&validity)
306 .map_err(|e| Error::encoding(e, "attributeCertificate.validity"))?;
307 let not_before = time(&mut times, "attributeCertificate.notBeforeTime")?;
308 let not_after = time(&mut times, "attributeCertificate.notAfterTime")?;
309 end(×, "attributeCertificate.validity")?;
310 let attribute_element = required(&mut inside, "attributeCertificate.attributes")?;
311 let attributes = attributes(&inside, &attribute_element)?;
312 let mut next = inside
313 .next_element()
314 .map_err(|e| Error::encoding(e, INFO))?;
315 let issuer_uid = optional_bits(
316 &mut inside,
317 &mut next,
318 "attributeCertificate.issuerUniqueID",
319 )?;
320 let extensions = match next {
321 Some(value) => {
322 tag(&value, sequence(), "attributeCertificate.extensions")?;
323 Some(
324 Extensions::read_element(&inside, &value, "attributeCertificate.extensions")
325 .map_err(Error::pkix)?,
326 )
327 }
328 None => None,
329 };
330 end(&inside, INFO)?;
331 Ok(Information {
332 holder,
333 issuer,
334 signature,
335 serial,
336 not_before,
337 not_after,
338 attributes,
339 issuer_uid,
340 extensions,
341 })
342}
343
344fn holder<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<Holder<'a>> {
345 let field = "attributeCertificate.holder";
346 let mut inside = parent
347 .enter(element)
348 .map_err(|e| Error::encoding(e, field))?;
349 let mut next = inside
350 .next_element()
351 .map_err(|e| Error::encoding(e, field))?;
352 let base_certificate = optional(&mut inside, &mut next, Tag::context(true, 0), field)?
353 .map(|e| issuer_serial(&inside, &e, field))
354 .transpose()?;
355 let entity_names = optional(&mut inside, &mut next, Tag::context(true, 1), field)?
356 .map(|e| names(&inside, &e, field))
357 .transpose()?;
358 let object_digest = optional(&mut inside, &mut next, Tag::context(true, 2), field)?
359 .map(|e| object_digest(&inside, &e, field))
360 .transpose()?;
361 no_pending(next, field)?;
362 Ok(Holder {
363 base_certificate,
364 entity_names,
365 object_digest,
366 })
367}
368
369fn v2_form<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<Issuer<'a>> {
370 let field = "attributeCertificate.issuer";
371 let mut inside = parent
372 .enter(element)
373 .map_err(|e| Error::encoding(e, field))?;
374 let mut next = inside
375 .next_element()
376 .map_err(|e| Error::encoding(e, field))?;
377 let names = optional(&mut inside, &mut next, sequence(), field)?
378 .map(|e| names(&inside, &e, field))
379 .transpose()?;
380 let base_certificate = optional(&mut inside, &mut next, Tag::context(true, 0), field)?
381 .map(|e| issuer_serial(&inside, &e, field))
382 .transpose()?;
383 let object_digest = optional(&mut inside, &mut next, Tag::context(true, 1), field)?
384 .map(|e| object_digest(&inside, &e, field))
385 .transpose()?;
386 no_pending(next, field)?;
387 Ok(Issuer {
388 form: IssuerForm::V2,
389 names,
390 base_certificate,
391 object_digest,
392 })
393}
394
395fn issuer_serial<'a>(
396 parent: &ScopedReader<'a, '_>,
397 element: &Element<'a>,
398 field: &'static str,
399) -> Result<IssuerSerial<'a>> {
400 let mut inside = parent
401 .enter(element)
402 .map_err(|e| Error::encoding(e, field))?;
403 let name_element = required(&mut inside, field)?;
404 tag(&name_element, sequence(), field)?;
405 let issuer = names(&inside, &name_element, field)?;
406 let serial = integer(&mut inside, field)?;
407 let mut next = inside
408 .next_element()
409 .map_err(|e| Error::encoding(e, field))?;
410 let issuer_uid = optional_bits(&mut inside, &mut next, field)?;
411 no_pending(next, field)?;
412 Ok(IssuerSerial {
413 issuer,
414 serial,
415 issuer_uid,
416 })
417}
418
419fn object_digest<'a>(
420 parent: &ScopedReader<'a, '_>,
421 element: &Element<'a>,
422 field: &'static str,
423) -> Result<ObjectDigestInfo<'a>> {
424 let mut inside = parent
425 .enter(element)
426 .map_err(|e| Error::encoding(e, field))?;
427 let object = required(&mut inside, field)?;
428 tag(&object, Tag::primitive(10), field)?; let number = inside
430 .integer(&object)
431 .map_err(|e| Error::encoding(e, field))?;
432 let object_type = match number.as_u64() {
433 Some(0) => DigestedObject::PublicKey,
434 Some(1) => DigestedObject::PublicKeyCertificate,
435 Some(2) => DigestedObject::Other,
436 _ => {
437 return Err(Error::schema(
438 ErrorCode::MalformedValue,
439 field,
440 object.span().start,
441 ));
442 }
443 };
444 let mut next = inside
445 .next_element()
446 .map_err(|e| Error::encoding(e, field))?;
447 let other_type = optional(
448 &mut inside,
449 &mut next,
450 Tag::primitive(universal::OID),
451 field,
452 )?
453 .map(|e| inside.oid(&e).map_err(|e| Error::encoding(e, field)))
454 .transpose()?;
455 let algorithm_element =
456 next.ok_or_else(|| Error::schema(ErrorCode::MissingField, field, inside.offset()))?;
457 let algorithm = algorithm(&inside, &algorithm_element, field)?;
458 let digest_element = required(&mut inside, field)?;
459 tag(
460 &digest_element,
461 Tag::primitive(universal::BIT_STRING),
462 field,
463 )?;
464 let digest = inside
465 .bit_string(&digest_element)
466 .map_err(|e| Error::encoding(e, field))?;
467 end(&inside, field)?;
468 Ok(ObjectDigestInfo {
469 object_type,
470 other_type,
471 algorithm,
472 digest,
473 })
474}
475
476fn names<'a>(
477 parent: &ScopedReader<'a, '_>,
478 element: &Element<'a>,
479 field: &'static str,
480) -> Result<OwnedVec<GeneralName<'a>>> {
481 let mut inside = parent
482 .enter(element)
483 .map_err(|e| Error::encoding(e, field))?;
484 let execution = parent.execution();
485 let mut names = execution.vector();
486 while let Some(value) = inside
487 .next_element()
488 .map_err(|e| Error::encoding(e, field))?
489 {
490 names
491 .try_reserve(1)
492 .map_err(|e| Error::resource(e, field, value.span().start))?;
493 names
494 .try_push(general_name::read(&inside, &value, field).map_err(Error::pkix)?)
495 .map_err(|e| Error::resource(e, field, value.span().start))?;
496 }
497 if names.is_empty() {
498 return Err(Error::schema(
499 ErrorCode::MissingField,
500 field,
501 element.contents_span().start,
502 ));
503 }
504 Ok(names.into_owned())
505}
506
507fn attributes<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<OwnedVec<Attribute<'a>>> {
508 const FIELD: &str = "attributeCertificate.attributes";
509 tag(element, sequence(), FIELD)?;
510 let mut inside = parent
511 .enter(element)
512 .map_err(|e| Error::encoding(e, FIELD))?;
513 let execution = parent.execution();
514 let mut attributes = execution.vector();
515 let mut order = execution.vector();
516 while let Some(value) = inside
517 .next_element()
518 .map_err(|e| Error::encoding(e, FIELD))?
519 {
520 attributes
521 .try_reserve(1)
522 .map_err(|e| Error::resource(e, FIELD, value.span().start))?;
523 let attribute = Attribute::read(&inside, &value, FIELD)?;
524 if attribute.values().is_empty() {
525 return Err(Error::schema(
526 ErrorCode::AttributeCardinality,
527 FIELD,
528 value.span().start,
529 ));
530 }
531 order
532 .try_push((attribute.kind(), attribute.span().start))
533 .map_err(|e| Error::resource(e, FIELD, value.span().start))?;
534 attributes
535 .try_push(attribute)
536 .map_err(|e| Error::resource(e, FIELD, value.span().start))?;
537 }
538 if attributes.is_empty() {
539 return Err(Error::schema(
540 ErrorCode::EmptyAttributes,
541 FIELD,
542 element.span().start,
543 ));
544 }
545 let refusal = |e| Error::resource(e, FIELD, element.span().start);
548 order
549 .try_sort_unstable_by(|(left, _), (right, _)| {
550 execution.charge_work(left.as_bytes().len().min(right.as_bytes().len()) as u64)?;
551 Ok::<_, structured_asn1::memory::MemoryError>(left.as_bytes().cmp(right.as_bytes()))
552 })
553 .map_err(|e| match e {
554 SortError::Resource(e) | SortError::Comparison(e) => refusal(e),
555 })?;
556 for pair in order.windows(2) {
557 execution
558 .charge_work(pair[0].0.as_bytes().len().min(pair[1].0.as_bytes().len()) as u64 + 1)
559 .map_err(refusal)?;
560 if pair[0].0 == pair[1].0 {
561 return Err(Error::schema(
562 ErrorCode::DuplicateAttribute,
563 FIELD,
564 pair[1].1,
565 ));
566 }
567 }
568 Ok(attributes.into_owned())
569}
570
571fn integer<'a>(parent: &mut ScopedReader<'a, '_>, field: &'static str) -> Result<Integer<'a>> {
572 let value = parent
573 .expect(Tag::primitive(universal::INTEGER))
574 .map_err(|e| Error::encoding(e, field))?;
575 parent
576 .integer(&value)
577 .map_err(|e| Error::encoding(e, field))
578}
579
580fn time(parent: &mut Reader<'_>, field: &'static str) -> Result<Time> {
581 let value = parent
582 .expect(Tag::primitive(universal::GENERALIZED_TIME))
583 .map_err(|e| Error::encoding(e, field))?;
584 Time::read(parent, &value, field).map_err(Error::pkix)
585}
586
587fn algorithm<'a>(
588 parent: &ScopedReader<'a, '_>,
589 element: &Element<'a>,
590 field: &'static str,
591) -> Result<AlgorithmIdentifier<'a>> {
592 structured_pkix::algorithm::read(parent, element, field).map_err(Error::pkix)
593}
594
595fn optional<'a>(
596 parent: &mut ScopedReader<'a, '_>,
597 next: &mut Option<Element<'a>>,
598 expected: Tag,
599 field: &'static str,
600) -> Result<Option<Element<'a>>> {
601 if next.as_ref().is_some_and(|e| e.tag() == expected) {
602 let selected = next.take();
603 *next = parent
604 .next_element()
605 .map_err(|e| Error::encoding(e, field))?;
606 Ok(selected)
607 } else {
608 Ok(None)
609 }
610}
611
612fn optional_bits<'a>(
613 parent: &mut ScopedReader<'a, '_>,
614 next: &mut Option<Element<'a>>,
615 field: &'static str,
616) -> Result<Option<BitString<'a>>> {
617 optional(parent, next, Tag::primitive(universal::BIT_STRING), field)?
618 .map(|e| parent.bit_string(&e).map_err(|e| Error::encoding(e, field)))
619 .transpose()
620}
621
622fn no_pending(next: Option<Element<'_>>, field: &'static str) -> Result<()> {
623 match next {
624 Some(value) => Err(Error::schema(
625 ErrorCode::TrailingData,
626 field,
627 value.span().start,
628 )),
629 None => Ok(()),
630 }
631}
632
633fn tag(element: &Element<'_>, expected: Tag, field: &'static str) -> Result<()> {
634 if element.tag() == expected {
635 Ok(())
636 } else {
637 Err(Error::schema(
638 ErrorCode::UnexpectedTag,
639 field,
640 element.span().start,
641 ))
642 }
643}
644
645fn end(parent: &ScopedReader<'_, '_>, field: &'static str) -> Result<()> {
646 if parent.is_empty() {
647 Ok(())
648 } else {
649 Err(Error::schema(
650 ErrorCode::TrailingData,
651 field,
652 parent.offset(),
653 ))
654 }
655}