structured_pkix/extension.rs
1//! The extensions a certificate carries, kept whether or not they are
2//! understood.
3//!
4//! An extension marked critical says that a relying party which does not
5//! understand it must not use the certificate. That is a decision about a
6//! verdict, not about whether the bytes can be read, so an unknown critical
7//! extension is reported here rather than refused: the product has to be able
8//! to say what it found and why it stopped, and a parser that refused would
9//! leave nothing to say it with.
10//!
11//! Which identifiers count as understood is not fixed by this crate alone. A
12//! scheme knows extensions of its own, and says so by implementing
13//! [`Recognizer`]. What it supplies is a set of identifiers, never code and
14//! never a place to fetch anything from.
15
16use crate::access::{DistributionPoints, InfoAccess};
17use crate::constraints::{BasicConstraints, InhibitAnyPolicy, NameConstraints, PolicyConstraints};
18use crate::error::{CallbackError, CallbackResult, Error, ErrorCode, Located, Result, gate};
19use crate::general_name::{self, GeneralName};
20use crate::identifier::{AuthorityKeyIdentifier, SubjectKeyIdentifier};
21use crate::oid;
22use crate::policy::{CertificatePolicies, PolicyMappings};
23use crate::qualified::QcStatements;
24use crate::usage::{ExtendedKeyUsage, KeyUsage};
25use structured_asn1::memory::{Memory, MemoryError, OwnedVec};
26use structured_asn1::{Element, Oid, Parser, Reader, Span, Tag, universal};
27
28/// One extension: what it is, whether it must be understood, and its value.
29#[derive(Debug, Clone, Copy)]
30pub struct Extension<'a> {
31 kind: Oid<'a>,
32 critical: bool,
33 value: &'a [u8],
34 value_span: Span,
35 span: Span,
36 /// The parser the certificate was read with, kept so every later decode
37 /// of this value is charged to that one budget: a signature accepting an
38 /// unrelated parser would let repeated decodes reset the counters and
39 /// cost many times the caller's declared limit.
40 parser: &'a Parser,
41 /// Depth of the reader that produced extnValue; lazy decoding must not
42 /// reset the certificate's aggregate depth allowance.
43 outer: u32,
44}
45
46impl<'a> Extension<'a> {
47 /// Which extension this is.
48 #[must_use]
49 pub fn kind(self) -> Oid<'a> {
50 self.kind
51 }
52
53 /// Whether a relying party that does not understand this extension must
54 /// refuse the certificate.
55 #[must_use]
56 pub fn is_critical(self) -> bool {
57 self.critical
58 }
59
60 /// The value, still encoded: the contents of the octet string the
61 /// extension wraps it in, which is a structure of its own.
62 #[must_use]
63 pub fn value(self) -> &'a [u8] {
64 self.value
65 }
66
67 /// Where the extension sits in the document.
68 #[must_use]
69 pub fn span(self) -> Span {
70 self.span
71 }
72
73 /// A reader over the value using the current execution domain and the
74 /// original parser session's cumulative ceilings, offsets and depth.
75 ///
76 /// How a scheme reads an extension of its own. Sharing the budget is what
77 /// keeps a certificate carrying a hundred extensions from costing a
78 /// hundred times what the caller allowed, and the offsets a reader made
79 /// this way reports are offsets in the whole document. The wrapped value
80 /// sits below extnValue and retains the certificate's depth allowance.
81 pub fn reader(self, execution: &Memory) -> structured_asn1::Result<Reader<'a>> {
82 // Always DER: the value lives inside the certificate, which RFC 5280
83 // section 4.1 defines in DER, whatever encoding the envelope was
84 // read in. A caller that read a BER envelope must not have its
85 // leniency reach into the certificate's own structures.
86 self.parser.read_nested_in(
87 self.value,
88 self.value_span.start,
89 structured_asn1::Encoding::Der,
90 self.outer,
91 execution,
92 )
93 }
94
95 /// The parser the certificate was read with, whose budget every decode
96 /// of this extension shares.
97 #[must_use]
98 pub fn parser(self) -> &'a Parser {
99 self.parser
100 }
101}
102
103/// The extensions of one certificate, in the order it holds them.
104#[derive(Debug)]
105pub struct Extensions<'a> {
106 items: OwnedVec<Extension<'a>>,
107}
108
109impl<'a> Extensions<'a> {
110 /// Account retaining this collection's storage. Deferred decoding may
111 /// explicitly use a different current execution domain.
112 #[must_use]
113 pub fn memory(&self) -> &Memory {
114 self.items.memory()
115 }
116
117 pub(crate) fn empty(execution: &Memory) -> Self {
118 Self {
119 items: execution.vector(),
120 }
121 }
122 /// Every extension, in order.
123 pub fn iter(&self) -> impl Iterator<Item = &Extension<'a>> {
124 self.items.iter()
125 }
126
127 /// How many there are.
128 #[must_use]
129 pub fn len(&self) -> usize {
130 self.items.len()
131 }
132
133 /// Whether there are none.
134 #[must_use]
135 pub fn is_empty(&self) -> bool {
136 self.items.is_empty()
137 }
138
139 /// One extension by identifier. There is at most one of each: a
140 /// certificate carrying two copies is refused when it is read, because
141 /// which of them applies would have no answer.
142 pub fn get(&self, kind: Oid<'_>, execution: &Memory) -> Result<Option<&Extension<'a>>> {
143 for item in &self.items {
144 let work = item.kind.as_bytes().len().max(kind.as_bytes().len()) as u64;
145 execution
146 .charge_work(1 + work)
147 .map_err(|reason| Error::resource(reason, "extensions", item.span.start))?;
148 if item.kind == kind {
149 return Ok(Some(item));
150 }
151 }
152 Ok(None)
153 }
154
155 /// The critical extensions this run did not understand: the ones nobody
156 /// knows, and the ones this crate knows by identifier but whose values do
157 /// not parse.
158 ///
159 /// A non-empty answer is what blocks a verdict. Knowing the identifier is
160 /// not understanding the extension: a critical key usage whose value
161 /// never parsed was never understood, and filtering it out by identifier
162 /// alone would leave a validator seeing no blocker for a demand the
163 /// certificate marked as one. Extensions a `recognizer` claims are that
164 /// scheme's to decode and are taken at its word.
165 ///
166 /// The answer is returned rather than acted on, because what to do about
167 /// it belongs to the policy layer and the report has to name them. An
168 /// error is a spent budget and only that: it says this run gave up before
169 /// the question was answered, which must not be reported as a demand
170 /// nobody understood.
171 pub fn unhandled_critical<'r, E>(
172 &'r self,
173 recognizer: &impl Recognizer<Error = E>,
174 execution: &Memory,
175 ) -> CallbackResult<OwnedVec<&'r Extension<'a>>, E> {
176 let mut unhandled = execution.vector();
177 for item in self.criticals(execution) {
178 let item = item?;
179 if !self.understands(item, recognizer, execution)? {
180 unhandled
181 .try_push(item)
182 .map_err(|reason| Error::resource(reason, "extensions", item.span().start))?;
183 }
184 }
185 Ok(unhandled)
186 }
187
188 /// The critical extensions, in the order the certificate wrote them and
189 /// without reading any of their values.
190 ///
191 /// Separate from [`Self::understands`] because working out whether one
192 /// was understood decodes its value, and how much that value holds is a
193 /// document's to decide. A caller holding a budget charges for an entry
194 /// and then asks: the two joined into one step would decode before the
195 /// charge could refuse it, since asking for the next entry is what would
196 /// do the decoding.
197 /// Each metadata entry is admitted before testing its critical flag,
198 /// including skipped entries and a complete miss. A resource error is
199 /// yielded once, then iteration permanently ends without further charges.
200 ///
201 /// # Examples
202 /// ```no_run
203 /// use structured_asn1::memory::Memory;
204 /// use structured_pkix::{Certificate, Result};
205 /// fn has_critical(certificate: &Certificate<'_>, execution: &Memory) -> Result<bool> {
206 /// match certificate.tbs().extensions().criticals(execution).next() {
207 /// Some(item) => { item?; Ok(true) }
208 /// None => Ok(false),
209 /// }
210 /// }
211 /// ```
212 pub fn criticals<'r, 'e>(
213 &'r self,
214 execution: &'e Memory,
215 ) -> impl Iterator<Item = Result<&'r Extension<'a>>> + 'e
216 where
217 'r: 'e,
218 {
219 let mut entries = self.items.iter();
220 let mut failed = false;
221 core::iter::from_fn(move || {
222 if failed {
223 return None;
224 }
225 for item in entries.by_ref() {
226 if let Err(reason) = execution.charge_work(1) {
227 failed = true;
228 return Some(Err(Error::resource(
229 reason,
230 "extensions",
231 item.span().start,
232 )));
233 }
234 if item.critical {
235 return Some(Ok(item));
236 }
237 }
238 None
239 })
240 }
241
242 /// Whether this run understood one extension: this crate decodes it, or
243 /// a scheme claims it and it holds one complete value.
244 ///
245 /// Knowing the identifier is not understanding the extension: a critical
246 /// key usage whose value never parsed was never understood, and taking
247 /// it by identifier alone would leave a validator seeing no blocker for
248 /// a demand the certificate marked as one.
249 pub fn understands<E>(
250 &self,
251 item: &Extension<'a>,
252 recognizer: &impl Recognizer<Error = E>,
253 execution: &Memory,
254 ) -> CallbackResult<bool, E> {
255 let work = (item.kind.as_bytes().len() as u64)
256 .checked_mul(64)
257 .ok_or_else(|| {
258 Error::resource(MemoryError::WorkExceeded, "extensions", item.span.start)
259 })?;
260 execution
261 .charge_work(work)
262 .map_err(|reason| Error::resource(reason, "extensions", item.span.start))?;
263 if is_known(item.kind) {
264 return Self::decodes(item, recognizer, execution);
265 }
266 Ok(recognizer
267 .recognizes(item.kind, execution)
268 .map_err(CallbackError::Callback)?
269 && Self::holds_one_value(item, execution)?)
270 }
271
272 /// Whether the value of an extension this crate does not decode is one
273 /// complete DER value, all the way down.
274 ///
275 /// A scheme says which identifiers are its to decode. It never sees the
276 /// bytes, so its claim cannot be a statement about them, and "the
277 /// corresponding ASN.1 DER encoded structure is the value of the octet
278 /// string extnValue" (RFC 5280 4.1.2.9) is the one thing that can be
279 /// asked here: one structure, nothing after it, and every element under
280 /// it written the way the encoding writes it. Without this a critical
281 /// demand carrying bytes that are a value of no type would clear the
282 /// gate on an identifier alone.
283 fn holds_one_value(item: &Extension<'a>, execution: &Memory) -> Result<bool> {
284 const FIELD: &str = "extensions";
285 let read = || -> Result<()> {
286 let at = |code| Error::new(code, FIELD, item.value_span.start);
287 let mut reader = item.reader(execution).field(FIELD)?;
288 let element = reader
289 .next_element()
290 .field(FIELD)?
291 .ok_or_else(|| at(ErrorCode::MissingField))?;
292 crate::name::walk_der(&reader, &element, FIELD, crate::name::Strings::Checked)?;
293 if reader.is_empty() {
294 Ok(())
295 } else {
296 Err(at(ErrorCode::TrailingData))
297 }
298 };
299 Ok(gate(read())?.is_some())
300 }
301
302 /// Whether a known extension's value actually parses. An error is a spent
303 /// budget, never a malformed value.
304 fn decodes<E>(
305 item: &Extension<'a>,
306 recognizer: &impl Recognizer<Error = E>,
307 execution: &Memory,
308 ) -> CallbackResult<bool, E> {
309 let kind = item.kind;
310 Ok(if kind == oid::BASIC_CONSTRAINTS {
311 gate(BasicConstraints::read(item, execution))?.is_some()
312 } else if kind == oid::KEY_USAGE {
313 gate(KeyUsage::read(item, execution))?.is_some()
314 } else if kind == oid::EXT_KEY_USAGE {
315 gate(ExtendedKeyUsage::read(item, execution))?.is_some()
316 } else if kind == oid::SUBJECT_ALT_NAME || kind == oid::ISSUER_ALT_NAME {
317 // The names read for the report either way; understanding also
318 // asks that every other-name type be one somebody claims.
319 match gate(general_name::read_alternative(item, execution))? {
320 Some(names) => all(names.iter(), item, execution, |name| {
321 other_name_known(name, recognizer, execution)
322 })?,
323 None => false,
324 }
325 } else if kind == oid::SUBJECT_KEY_IDENTIFIER {
326 gate(SubjectKeyIdentifier::read(item, execution))?.is_some()
327 } else if kind == oid::AUTHORITY_KEY_IDENTIFIER {
328 // The issuer names inside are the identity the extension points
329 // at, so they answer the same other-name question.
330 match gate(AuthorityKeyIdentifier::read(item, execution))? {
331 Some(identifier) => all(identifier.issuer().iter(), item, execution, |name| {
332 other_name_known(name, recognizer, execution)
333 })?,
334 None => false,
335 }
336 } else if kind == oid::NAME_CONSTRAINTS {
337 match gate(NameConstraints::read(item, execution))? {
338 Some(constraints) => all(
339 constraints.permitted().iter().chain(constraints.excluded()),
340 item,
341 execution,
342 |subtree| {
343 // A constraint is understood only where a
344 // certificate's names can be matched against it. The
345 // X.400 and EDI forms are kept as opaque encoded
346 // bytes, and a registered identifier has no defined
347 // constraint-matching rule either, so a critical
348 // constraint built on any of them was not understood
349 // even though its structure parsed.
350 //
351 // An other-name is the same question asked of a
352 // scheme, and it is the constraint question and not
353 // the reading one: knowing what a name of that type
354 // says is not knowing which names sit inside a
355 // subtree of it.
356 Ok(match subtree.base() {
357 GeneralName::X400(_)
358 | GeneralName::EdiParty(_)
359 | GeneralName::RegisteredId(_) => false,
360 GeneralName::Other { type_id, .. } => recognizer
361 .recognizes_name_constraint(*type_id, execution)
362 .map_err(CallbackError::Callback)?,
363 _ => true,
364 })
365 },
366 )?,
367 None => false,
368 }
369 } else if kind == oid::CERTIFICATE_POLICIES {
370 // The list parsing keeps qualifiers encoded; understanding a
371 // critical policy extension includes interpreting them.
372 match gate(CertificatePolicies::read(item, execution))? {
373 Some(policies) => policies.understood(item.parser, execution)?,
374 None => false,
375 }
376 } else if kind == oid::POLICY_MAPPINGS {
377 gate(PolicyMappings::read(item, execution))?.is_some()
378 } else if kind == oid::POLICY_CONSTRAINTS {
379 gate(PolicyConstraints::read(item, execution))?.is_some()
380 } else if kind == oid::INHIBIT_ANY_POLICY {
381 gate(InhibitAnyPolicy::read(item, execution))?.is_some()
382 } else if kind == oid::AUTHORITY_INFO_ACCESS || kind == oid::SUBJECT_INFO_ACCESS {
383 // A description's meaning is its method identifier, and a known
384 // method does not vouch for its location: an other-name there
385 // whose type nobody claims is a location this run never
386 // interpreted, and a form outside the ones the method names is
387 // an endpoint it cannot use. Either way the accessor still
388 // reports it.
389 match gate(InfoAccess::read(item, execution))? {
390 Some(access) => all(
391 access.descriptions().iter(),
392 item,
393 execution,
394 |description| {
395 let method = description.method();
396 // Each extension defines its own methods: OCSP and the
397 // issuing certificates on the authority side (RFC 5280
398 // 4.2.2.1), the repository and the time-stamping service
399 // on the subject side (RFC 5280 4.2.2.2). A method
400 // carried by the other extension has no defined meaning
401 // there and was not understood.
402 let named = if kind == oid::AUTHORITY_INFO_ACCESS {
403 [oid::OCSP, oid::CA_ISSUERS].contains(&method)
404 } else {
405 [oid::TIME_STAMPING_ACCESS, oid::CA_REPOSITORY].contains(&method)
406 };
407 Ok((named
408 || recognizer
409 .recognizes_access_method(method, execution)
410 .map_err(CallbackError::Callback)?)
411 && other_name_known(description.location(), recognizer, execution)?
412 && (!named || method_location_fits(method, description.location())))
413 },
414 )?,
415 None => false,
416 }
417 } else if kind == oid::CRL_DISTRIBUTION_POINTS || kind == oid::FRESHEST_CRL {
418 // A point's names say where the revocation evidence is, and the
419 // issuer names who signs it: both answer the other-name question.
420 match gate(DistributionPoints::read(item, execution))? {
421 Some(points) => all(points.points().iter(), item, execution, |point| {
422 all(
423 point.full_name().iter().chain(point.issuer()),
424 item,
425 execution,
426 |name| other_name_known(name, recognizer, execution),
427 )
428 })?,
429 None => false,
430 }
431 } else if kind == oid::QC_STATEMENTS {
432 // The outer list parsing is not understanding: the statement
433 // payloads decode lazily, and a critical list whose statement
434 // carries garbage, or whose identifier nobody here knows, is a
435 // critical demand this run never understood, one level down from
436 // an unknown extension.
437 match gate(QcStatements::read(item, execution))? {
438 Some(statements) => statements.understood(recognizer, execution)?,
439 None => false,
440 }
441 } else {
442 // is_known and this list name the same identifiers; a mismatch is
443 // a bug, and claiming the value parsed would hide it.
444 false
445 })
446 }
447}
448
449/// Generates one typed accessor per extension: absent when the list does not
450/// carry the identifier, otherwise whatever the reader makes of the value.
451/// The table is the single place an accessor name, its identifier and its
452/// reader meet, so the three cannot drift apart.
453macro_rules! typed_accessors {
454 ($($(#[$doc:meta])* $name:ident, $oid:path => $reader:path, $result:ty;)+) => {
455 $(
456 $(#[$doc])*
457 pub fn $name(&self, execution: &Memory) -> Result<Option<$result>> {
458 match self.get($oid, execution)? {
459 Some(item) => $reader(item, execution).map(Some),
460 None => Ok(None),
461 }
462 }
463 )+
464 };
465}
466
467/// The extensions this crate reads into structures of their own.
468///
469/// Each is read when it is asked for rather than when the certificate is,
470/// because an extension that cannot be read is not a certificate that cannot
471/// be read. Lookup and decoding use the caller's current execution domain;
472/// the original parser's cumulative local ceilings still apply.
473impl<'a> Extensions<'a> {
474 typed_accessors! {
475 /// Whether this is a certification authority, and how deep a path
476 /// below it may go.
477 basic_constraints, oid::BASIC_CONSTRAINTS => BasicConstraints::read, BasicConstraints;
478 /// What the key may be used for.
479 key_usage, oid::KEY_USAGE => KeyUsage::read, KeyUsage<'a>;
480 /// The further purposes the key is named for.
481 extended_key_usage, oid::EXT_KEY_USAGE => ExtendedKeyUsage::read, ExtendedKeyUsage<'a>;
482 /// The further names for the subject.
483 subject_alt_name, oid::SUBJECT_ALT_NAME => general_name::read_alternative, OwnedVec<GeneralName<'a>>;
484 /// The further names for the issuer.
485 issuer_alt_name, oid::ISSUER_ALT_NAME => general_name::read_alternative, OwnedVec<GeneralName<'a>>;
486 /// The identifier for the key this certificate carries.
487 subject_key_identifier, oid::SUBJECT_KEY_IDENTIFIER => SubjectKeyIdentifier::read, SubjectKeyIdentifier<'a>;
488 /// The identifier for the key that signed it.
489 authority_key_identifier, oid::AUTHORITY_KEY_IDENTIFIER => AuthorityKeyIdentifier::read, AuthorityKeyIdentifier<'a>;
490 /// The name space this authority may certify within.
491 name_constraints, oid::NAME_CONSTRAINTS => NameConstraints::read, NameConstraints<'a>;
492 /// The policies the certificate was issued under.
493 certificate_policies, oid::CERTIFICATE_POLICIES => CertificatePolicies::read, CertificatePolicies<'a>;
494 /// The policies of one domain treated as equivalent to another's.
495 policy_mappings, oid::POLICY_MAPPINGS => PolicyMappings::read, PolicyMappings<'a>;
496 /// The limits on policy processing below this certificate.
497 policy_constraints, oid::POLICY_CONSTRAINTS => PolicyConstraints::read, PolicyConstraints;
498 /// After how many certificates the identifier standing for any policy
499 /// stops being accepted.
500 inhibit_any_policy, oid::INHIBIT_ANY_POLICY => InhibitAnyPolicy::read, InhibitAnyPolicy;
501 /// Where the issuer's certificate and status service are published.
502 authority_info_access, oid::AUTHORITY_INFO_ACCESS => InfoAccess::read, InfoAccess<'a>;
503 /// Where services belonging to the subject are published.
504 subject_info_access, oid::SUBJECT_INFO_ACCESS => InfoAccess::read, InfoAccess<'a>;
505 /// Where revocation lists covering this certificate are published.
506 crl_distribution_points, oid::CRL_DISTRIBUTION_POINTS => DistributionPoints::read, DistributionPoints<'a>;
507 /// Where the delta revocation list is published.
508 freshest_crl, oid::FRESHEST_CRL => DistributionPoints::read, DistributionPoints<'a>;
509 /// What the issuer claims about this being a qualified certificate.
510 qc_statements, oid::QC_STATEMENTS => QcStatements::read, QcStatements<'a>;
511 }
512}
513
514/// Whether a name is not an other-name, or is one whose type identifier a
515/// scheme claims. An other-name's value means what its type says, this crate
516/// names no such types itself, and a critical name extension carrying one
517/// nobody claims was not understood.
518/// Whether a location takes a form its access method names (RFC 5280
519/// 4.2.2.1 and 4.2.2.2): the status responder is reached by a URI; the
520/// issuing certificates and the repository publish over transfer protocols,
521/// a URI, or the directory, a directory name, and a mailbox names no
522/// publication location for them; the timestamping service adds the mailbox,
523/// host and address forms. A method a recognizer claims keeps its own forms.
524fn method_location_fits(method: Oid<'_>, location: &GeneralName<'_>) -> bool {
525 if method == oid::OCSP {
526 matches!(location, GeneralName::Uri(_))
527 } else if method == oid::CA_ISSUERS || method == oid::CA_REPOSITORY {
528 matches!(location, GeneralName::Uri(_) | GeneralName::Directory(_))
529 } else if method == oid::TIME_STAMPING_ACCESS {
530 matches!(
531 location,
532 GeneralName::Uri(_)
533 | GeneralName::Email(_)
534 | GeneralName::Dns(_)
535 | GeneralName::IpAddress(_)
536 )
537 } else {
538 true
539 }
540}
541
542pub(crate) fn other_name_known<E>(
543 name: &GeneralName<'_>,
544 recognizer: &impl Recognizer<Error = E>,
545 execution: &Memory,
546) -> CallbackResult<bool, E> {
547 match name {
548 GeneralName::Other { type_id, .. } => recognizer
549 .recognizes_other_name(*type_id, execution)
550 .map_err(CallbackError::Callback),
551 _ => Ok(true),
552 }
553}
554
555fn all<T, E>(
556 values: impl Iterator<Item = T>,
557 item: &Extension<'_>,
558 execution: &Memory,
559 mut understood: impl FnMut(T) -> CallbackResult<bool, E>,
560) -> CallbackResult<bool, E> {
561 for value in values {
562 execution
563 .charge_work(1)
564 .map_err(|reason| Error::resource(reason, "extensions", item.span.start))?;
565 if !understood(value)? {
566 return Ok(false);
567 }
568 }
569 Ok(true)
570}
571
572/// The identifiers a scheme understands, answered by the role an identifier
573/// plays: claiming an extension says nothing about interpreting an
574/// other-name or an access method that reuses the same identifier.
575///
576/// Data, not behaviour: an implementation answers whether an identifier is one
577/// it knows. It cannot decode anything, and nothing here gives it a way to
578/// reach the network. Each role defaults to no, the direction that blocks
579/// rather than vouches.
580pub trait Recognizer {
581 /// The original policy, provider or resource error of this implementation.
582 type Error;
583
584 /// Whether this scheme understands the extension.
585 fn recognizes(
586 &self,
587 kind: Oid<'_>,
588 execution: &Memory,
589 ) -> core::result::Result<bool, Self::Error>;
590
591 /// Whether this scheme can interpret an other-name of this type.
592 fn recognizes_other_name(
593 &self,
594 _type_id: Oid<'_>,
595 _execution: &Memory,
596 ) -> core::result::Result<bool, Self::Error> {
597 Ok(false)
598 }
599
600 /// Whether this scheme enforces a name constraint written over an
601 /// other-name of this type.
602 ///
603 /// A different question from reading one. Reading asks what a name of
604 /// this type says; a constraint asks whether a certificate's names fall
605 /// inside a subtree of it, which needs a containment rule the type's
606 /// reader never states. A scheme that reads the type and has no such
607 /// rule leaves the constraint enforced by nobody, so this role is
608 /// answered separately and defaults to no.
609 fn recognizes_name_constraint(
610 &self,
611 _type_id: Oid<'_>,
612 _execution: &Memory,
613 ) -> core::result::Result<bool, Self::Error> {
614 Ok(false)
615 }
616
617 /// Whether this scheme understands an information-access method, its
618 /// location forms included.
619 fn recognizes_access_method(
620 &self,
621 _method: Oid<'_>,
622 _execution: &Memory,
623 ) -> core::result::Result<bool, Self::Error> {
624 Ok(false)
625 }
626
627 /// Whether this scheme can interpret a qualified statement of this kind:
628 /// a national statement is knowledge a scheme carries, not this crate.
629 fn recognizes_statement(
630 &self,
631 _kind: Oid<'_>,
632 _execution: &Memory,
633 ) -> core::result::Result<bool, Self::Error> {
634 Ok(false)
635 }
636}
637
638/// Nothing beyond what this crate itself understands.
639impl Recognizer for () {
640 type Error = core::convert::Infallible;
641 fn recognizes(
642 &self,
643 _kind: Oid<'_>,
644 _execution: &Memory,
645 ) -> core::result::Result<bool, Self::Error> {
646 Ok(false)
647 }
648}
649
650impl Recognizer for [Oid<'_>] {
651 type Error = MemoryError;
652 fn recognizes(
653 &self,
654 kind: Oid<'_>,
655 execution: &Memory,
656 ) -> core::result::Result<bool, Self::Error> {
657 for candidate in self {
658 execution
659 .charge_work(1 + candidate.as_bytes().len().max(kind.as_bytes().len()) as u64)?;
660 if *candidate == kind {
661 return Ok(true);
662 }
663 }
664 Ok(false)
665 }
666}
667
668/// A scheme reached by reference answers exactly as it does directly.
669///
670/// Every role of the trait is forwarded, and a new role must be added here
671/// too: each default answers no, so a role left behind silently drops the
672/// scheme's knowledge for callers holding it behind a reference, which is
673/// how a generic wrapper and a `&dyn Recognizer` both arrive.
674impl<T: Recognizer + ?Sized> Recognizer for &T {
675 type Error = T::Error;
676 fn recognizes(
677 &self,
678 kind: Oid<'_>,
679 execution: &Memory,
680 ) -> core::result::Result<bool, Self::Error> {
681 (*self).recognizes(kind, execution)
682 }
683
684 fn recognizes_other_name(
685 &self,
686 type_id: Oid<'_>,
687 execution: &Memory,
688 ) -> core::result::Result<bool, Self::Error> {
689 (*self).recognizes_other_name(type_id, execution)
690 }
691
692 fn recognizes_name_constraint(
693 &self,
694 type_id: Oid<'_>,
695 execution: &Memory,
696 ) -> core::result::Result<bool, Self::Error> {
697 (*self).recognizes_name_constraint(type_id, execution)
698 }
699
700 fn recognizes_access_method(
701 &self,
702 method: Oid<'_>,
703 execution: &Memory,
704 ) -> core::result::Result<bool, Self::Error> {
705 (*self).recognizes_access_method(method, execution)
706 }
707
708 fn recognizes_statement(
709 &self,
710 kind: Oid<'_>,
711 execution: &Memory,
712 ) -> core::result::Result<bool, Self::Error> {
713 (*self).recognizes_statement(kind, execution)
714 }
715}
716
717/// Whether this crate reads the extension into a structure of its own.
718#[must_use]
719pub fn is_known(kind: Oid<'_>) -> bool {
720 [
721 oid::BASIC_CONSTRAINTS,
722 oid::KEY_USAGE,
723 oid::EXT_KEY_USAGE,
724 oid::SUBJECT_ALT_NAME,
725 oid::ISSUER_ALT_NAME,
726 oid::SUBJECT_KEY_IDENTIFIER,
727 oid::AUTHORITY_KEY_IDENTIFIER,
728 oid::NAME_CONSTRAINTS,
729 oid::CERTIFICATE_POLICIES,
730 oid::POLICY_MAPPINGS,
731 oid::POLICY_CONSTRAINTS,
732 oid::INHIBIT_ANY_POLICY,
733 oid::AUTHORITY_INFO_ACCESS,
734 oid::SUBJECT_INFO_ACCESS,
735 oid::CRL_DISTRIBUTION_POINTS,
736 oid::FRESHEST_CRL,
737 oid::QC_STATEMENTS,
738 ]
739 .contains(&kind)
740}
741
742/// A reader over the members of the one sequence an extension's value holds,
743/// which is the shape of most of them.
744pub(crate) fn sequence<'a>(
745 extension: &Extension<'a>,
746 field: &'static str,
747 execution: &Memory,
748) -> Result<Reader<'a>> {
749 let fail = |code| Error::new(code, field, extension.span().start);
750
751 let mut reader = extension.reader(execution).field(field)?;
752 let element = reader
753 .next_element()
754 .field(field)?
755 .ok_or_else(|| fail(ErrorCode::MissingField))?;
756 if element.tag() != Tag::constructed(universal::SEQUENCE) {
757 return Err(fail(ErrorCode::Encoding(
758 structured_asn1::ErrorCode::UnexpectedTag,
759 )));
760 }
761 // A value holding a second structure after the first is two answers to
762 // what the extension says.
763 if !reader.is_empty() {
764 return Err(fail(ErrorCode::TrailingData));
765 }
766
767 reader.enter(&element).field(field)
768}
769
770/// The number and construction of a context-specific tag, and `None` for a
771/// tag of any other class.
772///
773/// The fields these schemas tag by position are context-specific, and a match
774/// on number and construction alone would read an APPLICATION or PRIVATE tag
775/// with the same number as the field it is not.
776pub(crate) fn context_of(tag: Tag) -> Option<(u32, bool)> {
777 // A number this reader does not name is not a field any schema wrote.
778 (tag.class() == structured_asn1::Class::ContextSpecific)
779 .then(|| tag.number().map(|number| (number, tag.is_constructed())))
780 .flatten()
781}
782
783/// Reads the extensions from the element the schema wraps them in. The
784/// parent reader's parser is kept with each extension, so every later decode
785/// of its value is charged to the budget the certificate was read with, and
786/// no other parser can be handed in beside the reader.
787pub(crate) fn read<'a>(
788 parent: &Reader<'a>,
789 element: &Element<'a>,
790 field: &'static str,
791) -> Result<Extensions<'a>> {
792 let parser = parent.parser();
793 let fail = |code| Error::new(code, field, element.span().start);
794
795 if element.tag() != Tag::constructed(universal::SEQUENCE) {
796 return Err(fail(ErrorCode::Encoding(
797 structured_asn1::ErrorCode::UnexpectedTag,
798 )));
799 }
800
801 let mut sequence = parent.enter(element).field(field)?;
802 let mut items = parent.memory().vector();
803 // A set rather than a scan of what came before: a certificate can carry
804 // tens of thousands of extensions within the parse budget, and a per-item
805 // scan of the list would be quadratic work the budget never sees.
806 let mut kinds = parent.memory().map::<Oid<'a>, ()>();
807
808 while let Some(entry) = sequence.next_element().field(field)? {
809 let at = |code| Error::new(code, field, entry.span().start);
810
811 if entry.tag() != Tag::constructed(universal::SEQUENCE) {
812 return Err(at(ErrorCode::Encoding(
813 structured_asn1::ErrorCode::UnexpectedTag,
814 )));
815 }
816
817 let mut inside = sequence.enter(&entry).field(field)?;
818 let kind = inside.read_oid().field(field)?;
819
820 let mut next = inside.next_element().field(field)?;
821 let critical = match next {
822 Some(flag) if flag.tag() == Tag::primitive(universal::BOOLEAN) => {
823 let value = inside.boolean(&flag).field(field)?;
824 // The flag defaults to false, and DER requires a default to
825 // be omitted: writing it out is a second spelling of the
826 // absent flag, and two spellings of one value is what DER
827 // exists to refuse. BER has no such rule, and issuers write
828 // it, so there the spelled-out default reads as itself.
829 if !value && inside.encoding().is_der() {
830 return Err(Error::new(
831 ErrorCode::MalformedValue,
832 field,
833 flag.span().start,
834 ));
835 }
836 next = inside.next_element().field(field)?;
837 value
838 }
839 // Absent means false, which is what most extensions leave it at.
840 _ => false,
841 };
842
843 let value = next.ok_or_else(|| at(ErrorCode::MissingField))?;
844 if value.tag() != Tag::primitive(universal::OCTET_STRING) {
845 return Err(Error::new(
846 ErrorCode::Encoding(structured_asn1::ErrorCode::UnexpectedTag),
847 field,
848 value.span().start,
849 ));
850 }
851 if !inside.is_empty() {
852 return Err(at(ErrorCode::TrailingData));
853 }
854
855 // Two copies of one extension leave no answer to which applies, and a
856 // reader that took the first would disagree with one that took the
857 // last about what the certificate says.
858 if kinds
859 .try_insert(kind, ())
860 .map_err(|reason| Error::resource(reason, field, entry.span().start))?
861 .is_some()
862 {
863 return Err(at(ErrorCode::DuplicateExtension));
864 }
865
866 items
867 .try_push(Extension {
868 kind,
869 critical,
870 value: value.contents(),
871 value_span: value.contents_span(),
872 span: entry.span(),
873 parser,
874 outer: inside.depth(),
875 })
876 .map_err(|reason| Error::resource(reason, field, entry.span().start))?;
877 }
878
879 // The schema requires at least one, and an empty sequence is a structure
880 // that says nothing while claiming to.
881 if items.is_empty() {
882 return Err(fail(ErrorCode::EmptySequence));
883 }
884
885 Ok(Extensions { items })
886}
887
888#[cfg(test)]
889mod tests;