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