x509_info/extensions/
locations.rs1use crate::{
2 extensions::general_name, names::inspect_attribute, GeneralName, NameAttribute, OidNames,
3};
4use x509_parser::extensions as backend;
5
6#[derive(Clone, Debug, PartialEq, Eq)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize))]
10#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
11#[non_exhaustive]
12pub struct AuthorityKeyIdentifier {
13 pub key_identifier_hex: Option<String>,
15 pub authority_cert_issuer: Option<Vec<GeneralName>>,
17 pub authority_cert_serial_hex: Option<String>,
19}
20
21#[derive(Clone, Debug, PartialEq, Eq)]
23#[cfg_attr(feature = "serde", derive(serde::Serialize))]
24#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
25#[non_exhaustive]
26pub struct AccessDescription {
27 pub method_oid: String,
29 pub method_name: Option<String>,
31 pub location: GeneralName,
33}
34
35#[derive(Clone, Debug, PartialEq, Eq)]
37#[cfg_attr(feature = "serde", derive(serde::Serialize))]
38#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
39#[cfg_attr(
40 feature = "serde",
41 serde(tag = "kind", content = "value", rename_all = "snake_case")
42)]
43#[non_exhaustive]
44pub enum DistributionPointName {
45 FullName(Vec<GeneralName>),
47 RelativeName(Vec<NameAttribute>),
49}
50
51#[derive(Clone, Debug, PartialEq, Eq)]
53#[cfg_attr(feature = "serde", derive(serde::Serialize))]
54#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
55#[non_exhaustive]
56pub struct DistributionPoint {
57 pub name: Option<DistributionPointName>,
59 pub reason_flags: Option<u16>,
64 pub crl_issuer: Option<Vec<GeneralName>>,
66}
67
68pub(crate) fn access(
69 items: &[backend::AccessDescription<'_>],
70 names: &OidNames,
71) -> Vec<AccessDescription> {
72 items
73 .iter()
74 .map(|item| {
75 let method_oid = item.access_method.to_id_string();
76 AccessDescription {
77 method_name: names.get(&method_oid).map(str::to_owned),
78 method_oid,
79 location: general_name(&item.access_location, names),
80 }
81 })
82 .collect()
83}
84
85pub(crate) fn distribution(bytes: &[u8], names: &OidNames) -> Option<Vec<DistributionPoint>> {
86 use x509_cert::{
87 der::{Decode, Encode},
88 ext::pkix::{name::DistributionPointName as B, CrlDistributionPoints},
89 };
90 use x509_parser::prelude::FromDer;
91 let points = CrlDistributionPoints::from_der(bytes).ok()?;
92 if points.0.is_empty() {
93 return None;
94 }
95 points
96 .0
97 .iter()
98 .map(|p| {
99 let name = match p.distribution_point.as_ref() {
100 Some(B::FullName(list)) => {
101 Some(DistributionPointName::FullName(crypto_names(list, names)?))
102 }
103 Some(B::NameRelativeToCRLIssuer(rdn)) => {
104 let der = rdn.to_der().ok()?;
105 let (rest, rdn) =
106 x509_parser::x509::RelativeDistinguishedName::from_der(&der).ok()?;
107 if !rest.is_empty() {
108 return None;
109 }
110 Some(DistributionPointName::RelativeName(
111 rdn.iter().map(|a| inspect_attribute(a, names)).collect(),
112 ))
113 }
114 None => None,
115 };
116 Some(DistributionPoint {
117 name,
118 reason_flags: p.reasons.map(|r| r.bits()),
119 crl_issuer: match &p.crl_issuer {
120 Some(list) => Some(crypto_names(list, names)?),
121 None => None,
122 },
123 })
124 })
125 .collect()
126}
127
128fn crypto_names(
129 list: &[x509_cert::ext::pkix::name::GeneralName],
130 names: &OidNames,
131) -> Option<Vec<GeneralName>> {
132 use x509_cert::der::Encode;
133 use x509_parser::prelude::FromDer;
134 list.iter()
135 .map(|item| {
136 let der = item.to_der().ok()?;
139 let (rest, name) = backend::GeneralName::from_der(&der).ok()?;
140 if !rest.is_empty() {
141 return None;
142 }
143 Some(general_name(&name, names))
144 })
145 .collect()
146}