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>

source

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.

source

pub fn parsed_extension(&self) -> &ParsedExtension<'a>

Return the extension type or UnsupportedExtension if the extension is not implemented.

Examples found in repository?
examples/print-crl.rs (line 37)
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
Hide additional examples
examples/print-cert.rs (line 53)
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>

source§

fn clone(&self) -> X509Extension<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for X509Extension<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

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>

Attempt to parse input bytes into a DER object (enforcing constraints)
source§

impl<'a> Parser<&'a [u8], X509Extension<'a>, X509Error> for X509ExtensionParser

source§

fn parse( &mut self, input: &'a [u8] ) -> IResult<&'a [u8], X509Extension<'a>, X509Error>

A parser takes in input type, and returns a Result containing either the remaining input and the output value, or an error
source§

fn map<G, O2>(self, g: G) -> Map<Self, G, O>
where G: Fn(O) -> O2, Self: Sized,

Maps a function over the result of a parser
source§

fn flat_map<G, H, O2>(self, g: G) -> FlatMap<Self, G, O>
where G: FnMut(O) -> H, H: Parser<I, O2, E>, Self: Sized,

Creates a second parser from the output of the first one, then apply over the rest of the input
source§

fn and_then<G, O2>(self, g: G) -> AndThen<Self, G, O>
where G: Parser<O, O2, E>, Self: Sized,

Applies a second parser over the output of the first one
source§

fn and<G, O2>(self, g: G) -> And<Self, G>
where G: Parser<I, O2, E>, Self: Sized,

Applies a second parser after the first one, return their results as a tuple
source§

fn or<G>(self, g: G) -> Or<Self, G>
where G: Parser<I, O, E>, Self: Sized,

Applies a second parser over the input if the first one failed
source§

fn into<O2, E2>(self) -> Into<Self, O, O2, E, E2>
where O2: From<O>, E2: From<E>, Self: Sized,

automatically converts the parser’s output and error values to another type, as long as they implement the From trait
source§

impl<'a> PartialEq for X509Extension<'a>

source§

fn eq(&self, other: &X509Extension<'a>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<'a> StructuralPartialEq for X509Extension<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for X509Extension<'a>

§

impl<'a> Send for X509Extension<'a>

§

impl<'a> Sync for X509Extension<'a>

§

impl<'a> Unpin for X509Extension<'a>

§

impl<'a> UnwindSafe for X509Extension<'a>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

source§

fn implicit( self, class: Class, constructed: bool, tag: u32 ) -> TaggedParser<'a, Implicit, Self, E>

source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.