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
94
95
96
97
//! Custom X.509 extension transport.
//!
//! These helpers encode and extract opaque DER payloads carried in custom
//! certificate extensions. The crate owns only the extension *structure* —
//! encoding bytes into an extension and reading them back out by OID. It does
//! not interpret the payload: the meaning of the bytes is the consumer's
//! concern.
//!
//! Extensions are created non-critical so that generic X.509 parsers, which
//! do not recognise the custom OID, still accept certificates that carry them.
use Oid;
use ;
use crate;
/// The rcgen extension type produced by [`encode_extension`] and consumed by
/// [`crate::ca::CertificateAuthority::issue_certificate`].
pub use CustomExtension;
/// Private-enterprise OID arc reserved for lys custom extensions.
///
/// Rooted at the IANA Private Enterprise Numbers arc (`1.3.6.1.4.1`). The
/// final component, `66364`, is the Private Enterprise Number IANA assigned
/// to lys — permanent, publicly registered, and never renumbered: extensions
/// are signed under OIDs beneath this arc, so changing it would invalidate
/// every certificate ever issued. Consumers append their own sub-components
/// to this arc to distinguish individual extension kinds.
pub const LYS_OID_ARC: & = &;
/// Encodes an opaque DER payload into a non-critical custom X.509 extension.
///
/// The returned extension carries `payload_bytes` verbatim under `oid`. The
/// payload is treated as opaque transport — no structure is imposed on or
/// read from it here. Criticality is set to `false` so parsers that do not
/// recognise `oid` will not reject the certificate.
/// Extracts the opaque payload of a custom extension identified by `oid`.
///
/// Parses `cert_der`, then looks up the extension by OID, rejecting
/// certificates that carry the same OID more than once. Returns the raw
/// extension value bytes unchanged, or `None` when the certificate does not
/// carry an extension with that OID.
///
/// # The returned payload is UNAUTHENTICATED
///
/// This function performs **no signature check and no issuer check**. It
/// parses bytes out of a certificate that anybody can construct, and the
/// extensions it reads are non-critical, so a parser that does not recognise
/// the OID accepts the certificate regardless of what the payload says.
///
/// Capability claims read this way are therefore **claims, not permissions**.
/// They become trustworthy only once
/// [`verify_certificate_chain`](crate::ca::verify_certificate_chain) — or
/// [`verify_certificate_chain_at`](crate::ca::verify_certificate_chain_at)
/// for an explicit instant — has succeeded against the public key of an
/// issuer you already trust. Verifying the certificate *after* acting on a
/// payload read from it is not equivalent, and treating the return value of
/// this function as an authorisation decision is a privilege-escalation bug:
/// the caller chooses the certificate, so the caller chooses the claims.
///
/// The CLI's `lys inspect cert` models the intended discipline — it prints
/// these payloads under an explicit `UNVERIFIED CLAIMS` marker naming the
/// command that does verify.
///
/// # Errors
///
/// Returns [`TrustError::CertificateParsing`] if `cert_der` is not a valid
/// certificate, `oid` is not a well-formed object identifier, or the
/// certificate carries the OID more than once.