structured_pkix/revocation.rs
1//! Original borrowed status targets shared by CRL and OCSP processing.
2
3use crate::{Certificate, Extensions, Name, Version};
4use structured_asn1::memory::{Execution, Work};
5use structured_asn1::{Integer, Parser, Span};
6
7/// Original certificate category, not a deployment policy.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum TargetKind {
10 /// A public-key certificate with its actual schema version.
11 PublicKey(Version),
12 /// An RFC5755 attribute certificate, without an invented public key or cA bit.
13 Attribute,
14}
15
16/// Written revocation scheme, independently of successful status evidence.
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum RevocationScheme {
19 /// Status sources may be processed; absent pointers are not an exemption.
20 Available,
21 /// RFC5755 ยง6 `NoRevAvail`, never CRL absence or positive OCSP evidence.
22 NoRevAvail,
23}
24
25/// Coherently associated original fields for the common status processors.
26///
27/// Implementations are trusted O(1) adapters: borrow original fields without
28/// parsing, allocation or normalization. Every field describes the same target.
29/// This does not authenticate it or its issuer. Deferred work retains the source
30/// ceiling and the current operation. The issuer/responder remains a real PKC;
31/// an AC does not acquire an artificial subject public key.
32///
33/// ```
34/// use structured_asn1::memory::Work;
35/// use structured_pkix::{Result, revocation::RevocationTarget,
36/// crl::{Authenticated, ScopeOutcome}};
37/// fn applicable<'a>(source: &Authenticated<'_, '_>, target: &impl RevocationTarget<'a>,
38/// work: &impl Work) -> Result<bool> {
39/// Ok(matches!(source.scope(target, work)?, ScopeOutcome::Applicable(_)))
40/// }
41/// ```
42pub trait RevocationTarget<'a> {
43 /// Original issuer DN.
44 fn issuer(&self) -> &Name<'a>;
45 /// Original arbitrary-width serial.
46 fn serial(&self) -> Integer<'a>;
47 /// Original extension catalogue, absent where the schema omitted it.
48 fn extensions(&self) -> Option<&Extensions<'a>>;
49 /// Actual schema category.
50 fn kind(&self) -> TargetKind;
51 /// Written scheme, never inferred from short validity or absent URLs.
52 fn revocation_scheme(&self) -> RevocationScheme;
53 /// Whole original encoding used to bind evidence contributors.
54 fn encoded(&self) -> &'a [u8];
55 /// Honest source enclosure for processing failures.
56 fn span(&self) -> Span;
57 /// Original parser for these fields, including deferred BER depth and limits.
58 fn source_parser(&self) -> &'a Parser;
59 /// Borrow the original source ceiling and current operation.
60 fn execution_in<'op, W: Work>(&'op self, work: &'op W) -> Execution<'op>
61 where
62 'a: 'op,
63 {
64 work.execution_for(self.source_parser())
65 }
66}
67
68impl<'a> RevocationTarget<'a> for Certificate<'a> {
69 fn source_parser(&self) -> &'a Parser {
70 self.tbs().signature().source_parser()
71 }
72 fn issuer(&self) -> &Name<'a> {
73 self.tbs().issuer()
74 }
75 fn serial(&self) -> Integer<'a> {
76 self.tbs().serial()
77 }
78 fn extensions(&self) -> Option<&Extensions<'a>> {
79 Some(self.tbs().extensions())
80 }
81 fn kind(&self) -> TargetKind {
82 TargetKind::PublicKey(self.tbs().version())
83 }
84 fn revocation_scheme(&self) -> RevocationScheme {
85 RevocationScheme::Available
86 }
87 fn encoded(&self) -> &'a [u8] {
88 self.as_bytes()
89 }
90 fn span(&self) -> Span {
91 Certificate::span(self)
92 }
93}