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