Struct x509_parser::extensions::X509Extension
source · pub struct X509Extension<'a> {
pub oid: Oid<'a>,
pub critical: bool,
pub value: &'a [u8],
/* private fields */
}
Expand description
X.509 version 3 extension
X.509 extensions allow adding attributes to objects like certificates or revocation lists.
Each extension in a certificate is designated as either critical or non-critical. A certificate using system MUST reject the certificate if it encounters a critical extension it does not recognize; however, a non-critical extension MAY be ignored if it is not recognized.
Each extension includes an OID and an ASN.1 structure. When an extension appears in a certificate, the OID appears as the field extnID and the corresponding ASN.1 encoded structure is the value of the octet string extnValue. A certificate MUST NOT include more than one instance of a particular extension.
When parsing an extension, the global extension structure (described above) is parsed,
and the object is returned if it succeeds.
During this step, it also attempts to parse the content of the extension, if known.
The returned object has a
X509Extension::parsed_extension()
method. The returned
enum is either a known extension, or the special value ParsedExtension::UnsupportedExtension
.
§Example
use x509_parser::prelude::FromDer;
use x509_parser::extensions::{X509Extension, ParsedExtension};
static DER: &[u8] = &[
0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xA3, 0x05, 0x2F, 0x18,
0x60, 0x50, 0xC2, 0x89, 0x0A, 0xDD, 0x2B, 0x21, 0x4F, 0xFF, 0x8E, 0x4E, 0xA8, 0x30, 0x31,
0x36 ];
let res = X509Extension::from_der(DER);
match res {
Ok((_rem, ext)) => {
println!("Extension OID: {}", ext.oid);
println!(" Critical: {}", ext.critical);
let parsed_ext = ext.parsed_extension();
assert!(!parsed_ext.unsupported());
assert!(parsed_ext.error().is_none());
if let ParsedExtension::SubjectKeyIdentifier(key_id) = parsed_ext {
assert!(key_id.0.len() > 0);
} else {
panic!("Extension has wrong type");
}
},
_ => panic!("x509 extension parsing failed: {:?}", res),
}
Fields§
§oid: Oid<'a>
OID describing the extension content
critical: bool
Boolean value describing the ‘critical’ attribute of the extension
An extension includes the boolean critical, with a default value of FALSE.
value: &'a [u8]
Raw content of the extension
Implementations§
source§impl<'a> X509Extension<'a>
impl<'a> X509Extension<'a>
sourcepub const fn new(
oid: Oid<'a>,
critical: bool,
value: &'a [u8],
parsed_extension: ParsedExtension<'a>
) -> X509Extension<'a>
pub const fn new( oid: Oid<'a>, critical: bool, value: &'a [u8], parsed_extension: ParsedExtension<'a> ) -> X509Extension<'a>
Creates a new extension with the provided values.
sourcepub fn parsed_extension(&self) -> &ParsedExtension<'a>
pub fn parsed_extension(&self) -> &ParsedExtension<'a>
Return the extension type or UnsupportedExtension
if the extension is not implemented.
Examples found in repository?
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
fn print_x509_extension(oid: &Oid, ext: &X509Extension, level: usize) {
match ext.parsed_extension() {
ParsedExtension::CRLNumber(num) => {
println!("{:indent$}X509v3 CRL Number: {}", "", num, indent = level);
}
ParsedExtension::ReasonCode(code) => {
println!(
"{:indent$}X509v3 CRL Reason Code: {}",
"",
code,
indent = level
);
}
ParsedExtension::InvalidityDate(date) => {
println!("{:indent$}Invalidity Date: {}", "", date, indent = level);
}
ParsedExtension::AuthorityKeyIdentifier(aki) => {
println!(
"{:indent$}X509v3 Authority Key Identifier:",
"",
indent = level
);
print_authority_key_identifier(aki, level + 2);
}
x => {
print!("{:indent$}{}:", "", format_oid(oid), indent = level);
print!(" Critical={}", ext.critical);
print!(" len={}", ext.value.len());
println!();
println!(" {:indent$}{:?}", "", x, indent = level);
}
}
}
More examples
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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
fn print_x509_extension(oid: &Oid, ext: &X509Extension) {
println!(
" [crit:{} l:{}] {}: ",
ext.critical,
ext.value.len(),
format_oid(oid)
);
match ext.parsed_extension() {
ParsedExtension::AuthorityKeyIdentifier(aki) => {
println!(" X509v3 Authority Key Identifier");
if let Some(key_id) = &aki.key_identifier {
println!(" Key Identifier: {:x}", key_id);
}
if let Some(issuer) = &aki.authority_cert_issuer {
for name in issuer {
println!(" Cert Issuer: {}", name);
}
}
if let Some(serial) = aki.authority_cert_serial {
println!(" Cert Serial: {}", format_serial(serial));
}
}
ParsedExtension::BasicConstraints(bc) => {
println!(" X509v3 CA: {}", bc.ca);
}
ParsedExtension::CRLDistributionPoints(points) => {
println!(" X509v3 CRL Distribution Points:");
for point in points.iter() {
if let Some(name) = &point.distribution_point {
println!(" Full Name: {:?}", name);
}
if let Some(reasons) = &point.reasons {
println!(" Reasons: {}", reasons);
}
if let Some(crl_issuer) = &point.crl_issuer {
print!(" CRL Issuer: ");
for gn in crl_issuer {
print!("{} ", generalname_to_string(gn));
}
println!();
}
println!();
}
}
ParsedExtension::KeyUsage(ku) => {
println!(" X509v3 Key Usage: {}", ku);
}
ParsedExtension::NSCertType(ty) => {
println!(" Netscape Cert Type: {}", ty);
}
ParsedExtension::SubjectAlternativeName(san) => {
for name in &san.general_names {
let s = match name {
GeneralName::DNSName(s) => {
format!("DNS:{}", s)
}
GeneralName::IPAddress(b) => {
let ip = match b.len() {
4 => {
let b = <[u8; 4]>::try_from(*b).unwrap();
let ip = Ipv4Addr::from(b);
format!("{}", ip)
}
16 => {
let b = <[u8; 16]>::try_from(*b).unwrap();
let ip = Ipv6Addr::from(b);
format!("{}", ip)
}
l => format!("invalid (len={})", l),
};
format!("IP Address:{}", ip)
}
_ => {
format!("{:?}", name)
}
};
println!(" X509v3 SAN: {}", s);
}
}
ParsedExtension::SubjectKeyIdentifier(id) => {
println!(" X509v3 Subject Key Identifier: {:x}", id);
}
x => println!(" {:?}", x),
}
}
Trait Implementations§
source§impl<'a> Clone for X509Extension<'a>
impl<'a> Clone for X509Extension<'a>
source§fn clone(&self) -> X509Extension<'a>
fn clone(&self) -> X509Extension<'a>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<'a> Debug for X509Extension<'a>
impl<'a> Debug for X509Extension<'a>
source§impl<'a> FromDer<'a, X509Error> for X509Extension<'a>
impl<'a> FromDer<'a, X509Error> for X509Extension<'a>
Extension ::= SEQUENCE { extnID OBJECT IDENTIFIER, critical BOOLEAN DEFAULT FALSE, extnValue OCTET STRING }
source§fn from_der(i: &'a [u8]) -> X509Result<'_, Self>
fn from_der(i: &'a [u8]) -> X509Result<'_, Self>
source§impl<'a> Parser<&'a [u8], X509Extension<'a>, X509Error> for X509ExtensionParser
impl<'a> Parser<&'a [u8], X509Extension<'a>, X509Error> for X509ExtensionParser
source§fn parse(
&mut self,
input: &'a [u8]
) -> IResult<&'a [u8], X509Extension<'a>, X509Error>
fn parse( &mut self, input: &'a [u8] ) -> IResult<&'a [u8], X509Extension<'a>, X509Error>
Result
containing
either the remaining input and the output value, or an errorsource§fn flat_map<G, H, O2>(self, g: G) -> FlatMap<Self, G, O>
fn flat_map<G, H, O2>(self, g: G) -> FlatMap<Self, G, O>
source§fn and_then<G, O2>(self, g: G) -> AndThen<Self, G, O>
fn and_then<G, O2>(self, g: G) -> AndThen<Self, G, O>
source§fn and<G, O2>(self, g: G) -> And<Self, G>
fn and<G, O2>(self, g: G) -> And<Self, G>
source§impl<'a> PartialEq for X509Extension<'a>
impl<'a> PartialEq for X509Extension<'a>
source§fn eq(&self, other: &X509Extension<'a>) -> bool
fn eq(&self, other: &X509Extension<'a>) -> bool
self
and other
values to be equal, and is used
by ==
.