pub struct X509Certificate<'a> {
    pub tbs_certificate: TbsCertificate<'a>,
    pub signature_algorithm: AlgorithmIdentifier<'a>,
    pub signature_value: BitString<'a>,
}
Expand description

An X.509 v3 Certificate.

X.509 v3 certificates are defined in RFC5280, section 4.1. This object uses the same structure for content, so for ex the subject can be accessed using the path x509.tbs_certificate.subject.

X509Certificate also contains convenience methods to access the most common fields (subject, issuer, etc.). These are provided using Deref<Target = TbsCertificate>, so documentation for these methods can be found in the TbsCertificate object.

A X509Certificate is a zero-copy view over a buffer, so the lifetime is the same as the buffer containing the binary representation.

fn display_x509_info(x509: &X509Certificate<'_>) {
     let subject = x509.subject();
     let issuer = x509.issuer();
     println!("X.509 Subject: {}", subject);
     println!("X.509 Issuer: {}", issuer);
     println!("X.509 serial: {}", x509.tbs_certificate.raw_serial_as_string());
}

Fields§

§tbs_certificate: TbsCertificate<'a>§signature_algorithm: AlgorithmIdentifier<'a>§signature_value: BitString<'a>

Implementations§

source§

impl<'a> X509Certificate<'a>

source

pub fn verify_signature( &self, public_key: Option<&SubjectPublicKeyInfo<'_>> ) -> Result<(), X509Error>

Available on crate feature verify only.

Verify the cryptographic signature of this certificate

public_key is the public key of the signer. For a self-signed certificate, (for ex. a public root certificate authority), this is the key from the certificate, so you can use None.

For a leaf certificate, this is the public key of the certificate that signed it. It is usually an intermediate authority.

Not all algorithms are supported, this function is limited to what ring supports.

Examples found in repository?
examples/print-cert.rs (line 214)
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
fn print_x509_info(x509: &X509Certificate) -> io::Result<()> {
    let version = x509.version();
    if version.0 < 3 {
        println!("  Version: {}", version);
    } else {
        println!("  Version: INVALID({})", version.0);
    }
    println!("  Serial: {}", x509.tbs_certificate.raw_serial_as_string());
    println!("  Subject: {}", x509.subject());
    println!("  Issuer: {}", x509.issuer());
    println!("  Validity:");
    println!("    NotBefore: {}", x509.validity().not_before);
    println!("    NotAfter:  {}", x509.validity().not_after);
    println!("    is_valid:  {}", x509.validity().is_valid());
    println!("  Subject Public Key Info:");
    print_x509_ski(x509.public_key());
    print_x509_signature_algorithm(&x509.signature_algorithm, 4);

    println!("  Signature Value:");
    for l in format_number_to_hex_with_colon(&x509.signature_value.data, 16) {
        println!("      {}", l);
    }
    println!("  Extensions:");
    for ext in x509.extensions() {
        print_x509_extension(&ext.oid, ext);
    }
    println!();
    print!("Structure validation status: ");
    #[cfg(feature = "validate")]
    {
        let mut logger = VecLogger::default();
        // structure validation status
        let ok = X509StructureValidator
            .chain(X509CertificateValidator)
            .validate(x509, &mut logger);
        if ok {
            println!("Ok");
        } else {
            println!("FAIL");
        }
        for warning in logger.warnings() {
            println!("  [W] {}", warning);
        }
        for error in logger.errors() {
            println!("  [E] {}", error);
        }
        println!();
        if VALIDATE_ERRORS_FATAL && !logger.errors().is_empty() {
            return Err(io::Error::new(io::ErrorKind::Other, "validation failed"));
        }
    }
    #[cfg(not(feature = "validate"))]
    {
        println!("Unknown (feature 'validate' not enabled)");
    }
    #[cfg(feature = "verify")]
    {
        print!("Signature verification: ");
        if x509.subject() == x509.issuer() {
            if x509.verify_signature(None).is_ok() {
                println!("OK");
                println!("  [I] certificate is self-signed");
            } else if x509.subject() == x509.issuer() {
                println!("FAIL");
                println!("  [W] certificate looks self-signed, but signature verification failed");
            }
        } else {
            // if subject is different from issuer, we cannot verify certificate without the public key of the issuer
            println!("N/A");
        }
    }
    Ok(())
}

Methods from Deref<Target = TbsCertificate<'a>>§

source

pub fn version(&self) -> X509Version

Get the version of the encoded certificate

Examples found in repository?
examples/print-cert.rs (line 156)
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
fn print_x509_info(x509: &X509Certificate) -> io::Result<()> {
    let version = x509.version();
    if version.0 < 3 {
        println!("  Version: {}", version);
    } else {
        println!("  Version: INVALID({})", version.0);
    }
    println!("  Serial: {}", x509.tbs_certificate.raw_serial_as_string());
    println!("  Subject: {}", x509.subject());
    println!("  Issuer: {}", x509.issuer());
    println!("  Validity:");
    println!("    NotBefore: {}", x509.validity().not_before);
    println!("    NotAfter:  {}", x509.validity().not_after);
    println!("    is_valid:  {}", x509.validity().is_valid());
    println!("  Subject Public Key Info:");
    print_x509_ski(x509.public_key());
    print_x509_signature_algorithm(&x509.signature_algorithm, 4);

    println!("  Signature Value:");
    for l in format_number_to_hex_with_colon(&x509.signature_value.data, 16) {
        println!("      {}", l);
    }
    println!("  Extensions:");
    for ext in x509.extensions() {
        print_x509_extension(&ext.oid, ext);
    }
    println!();
    print!("Structure validation status: ");
    #[cfg(feature = "validate")]
    {
        let mut logger = VecLogger::default();
        // structure validation status
        let ok = X509StructureValidator
            .chain(X509CertificateValidator)
            .validate(x509, &mut logger);
        if ok {
            println!("Ok");
        } else {
            println!("FAIL");
        }
        for warning in logger.warnings() {
            println!("  [W] {}", warning);
        }
        for error in logger.errors() {
            println!("  [E] {}", error);
        }
        println!();
        if VALIDATE_ERRORS_FATAL && !logger.errors().is_empty() {
            return Err(io::Error::new(io::ErrorKind::Other, "validation failed"));
        }
    }
    #[cfg(not(feature = "validate"))]
    {
        println!("Unknown (feature 'validate' not enabled)");
    }
    #[cfg(feature = "verify")]
    {
        print!("Signature verification: ");
        if x509.subject() == x509.issuer() {
            if x509.verify_signature(None).is_ok() {
                println!("OK");
                println!("  [I] certificate is self-signed");
            } else if x509.subject() == x509.issuer() {
                println!("FAIL");
                println!("  [W] certificate looks self-signed, but signature verification failed");
            }
        } else {
            // if subject is different from issuer, we cannot verify certificate without the public key of the issuer
            println!("N/A");
        }
    }
    Ok(())
}
source

pub fn subject(&self) -> &X509Name<'_>

Get the certificate subject.

Examples found in repository?
examples/print-cert.rs (line 163)
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
fn print_x509_info(x509: &X509Certificate) -> io::Result<()> {
    let version = x509.version();
    if version.0 < 3 {
        println!("  Version: {}", version);
    } else {
        println!("  Version: INVALID({})", version.0);
    }
    println!("  Serial: {}", x509.tbs_certificate.raw_serial_as_string());
    println!("  Subject: {}", x509.subject());
    println!("  Issuer: {}", x509.issuer());
    println!("  Validity:");
    println!("    NotBefore: {}", x509.validity().not_before);
    println!("    NotAfter:  {}", x509.validity().not_after);
    println!("    is_valid:  {}", x509.validity().is_valid());
    println!("  Subject Public Key Info:");
    print_x509_ski(x509.public_key());
    print_x509_signature_algorithm(&x509.signature_algorithm, 4);

    println!("  Signature Value:");
    for l in format_number_to_hex_with_colon(&x509.signature_value.data, 16) {
        println!("      {}", l);
    }
    println!("  Extensions:");
    for ext in x509.extensions() {
        print_x509_extension(&ext.oid, ext);
    }
    println!();
    print!("Structure validation status: ");
    #[cfg(feature = "validate")]
    {
        let mut logger = VecLogger::default();
        // structure validation status
        let ok = X509StructureValidator
            .chain(X509CertificateValidator)
            .validate(x509, &mut logger);
        if ok {
            println!("Ok");
        } else {
            println!("FAIL");
        }
        for warning in logger.warnings() {
            println!("  [W] {}", warning);
        }
        for error in logger.errors() {
            println!("  [E] {}", error);
        }
        println!();
        if VALIDATE_ERRORS_FATAL && !logger.errors().is_empty() {
            return Err(io::Error::new(io::ErrorKind::Other, "validation failed"));
        }
    }
    #[cfg(not(feature = "validate"))]
    {
        println!("Unknown (feature 'validate' not enabled)");
    }
    #[cfg(feature = "verify")]
    {
        print!("Signature verification: ");
        if x509.subject() == x509.issuer() {
            if x509.verify_signature(None).is_ok() {
                println!("OK");
                println!("  [I] certificate is self-signed");
            } else if x509.subject() == x509.issuer() {
                println!("FAIL");
                println!("  [W] certificate looks self-signed, but signature verification failed");
            }
        } else {
            // if subject is different from issuer, we cannot verify certificate without the public key of the issuer
            println!("N/A");
        }
    }
    Ok(())
}
source

pub fn issuer(&self) -> &X509Name<'_>

Get the certificate issuer.

Examples found in repository?
examples/print-cert.rs (line 164)
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
fn print_x509_info(x509: &X509Certificate) -> io::Result<()> {
    let version = x509.version();
    if version.0 < 3 {
        println!("  Version: {}", version);
    } else {
        println!("  Version: INVALID({})", version.0);
    }
    println!("  Serial: {}", x509.tbs_certificate.raw_serial_as_string());
    println!("  Subject: {}", x509.subject());
    println!("  Issuer: {}", x509.issuer());
    println!("  Validity:");
    println!("    NotBefore: {}", x509.validity().not_before);
    println!("    NotAfter:  {}", x509.validity().not_after);
    println!("    is_valid:  {}", x509.validity().is_valid());
    println!("  Subject Public Key Info:");
    print_x509_ski(x509.public_key());
    print_x509_signature_algorithm(&x509.signature_algorithm, 4);

    println!("  Signature Value:");
    for l in format_number_to_hex_with_colon(&x509.signature_value.data, 16) {
        println!("      {}", l);
    }
    println!("  Extensions:");
    for ext in x509.extensions() {
        print_x509_extension(&ext.oid, ext);
    }
    println!();
    print!("Structure validation status: ");
    #[cfg(feature = "validate")]
    {
        let mut logger = VecLogger::default();
        // structure validation status
        let ok = X509StructureValidator
            .chain(X509CertificateValidator)
            .validate(x509, &mut logger);
        if ok {
            println!("Ok");
        } else {
            println!("FAIL");
        }
        for warning in logger.warnings() {
            println!("  [W] {}", warning);
        }
        for error in logger.errors() {
            println!("  [E] {}", error);
        }
        println!();
        if VALIDATE_ERRORS_FATAL && !logger.errors().is_empty() {
            return Err(io::Error::new(io::ErrorKind::Other, "validation failed"));
        }
    }
    #[cfg(not(feature = "validate"))]
    {
        println!("Unknown (feature 'validate' not enabled)");
    }
    #[cfg(feature = "verify")]
    {
        print!("Signature verification: ");
        if x509.subject() == x509.issuer() {
            if x509.verify_signature(None).is_ok() {
                println!("OK");
                println!("  [I] certificate is self-signed");
            } else if x509.subject() == x509.issuer() {
                println!("FAIL");
                println!("  [W] certificate looks self-signed, but signature verification failed");
            }
        } else {
            // if subject is different from issuer, we cannot verify certificate without the public key of the issuer
            println!("N/A");
        }
    }
    Ok(())
}
source

pub fn validity(&self) -> &Validity

Get the certificate validity.

Examples found in repository?
examples/print-cert.rs (line 166)
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
fn print_x509_info(x509: &X509Certificate) -> io::Result<()> {
    let version = x509.version();
    if version.0 < 3 {
        println!("  Version: {}", version);
    } else {
        println!("  Version: INVALID({})", version.0);
    }
    println!("  Serial: {}", x509.tbs_certificate.raw_serial_as_string());
    println!("  Subject: {}", x509.subject());
    println!("  Issuer: {}", x509.issuer());
    println!("  Validity:");
    println!("    NotBefore: {}", x509.validity().not_before);
    println!("    NotAfter:  {}", x509.validity().not_after);
    println!("    is_valid:  {}", x509.validity().is_valid());
    println!("  Subject Public Key Info:");
    print_x509_ski(x509.public_key());
    print_x509_signature_algorithm(&x509.signature_algorithm, 4);

    println!("  Signature Value:");
    for l in format_number_to_hex_with_colon(&x509.signature_value.data, 16) {
        println!("      {}", l);
    }
    println!("  Extensions:");
    for ext in x509.extensions() {
        print_x509_extension(&ext.oid, ext);
    }
    println!();
    print!("Structure validation status: ");
    #[cfg(feature = "validate")]
    {
        let mut logger = VecLogger::default();
        // structure validation status
        let ok = X509StructureValidator
            .chain(X509CertificateValidator)
            .validate(x509, &mut logger);
        if ok {
            println!("Ok");
        } else {
            println!("FAIL");
        }
        for warning in logger.warnings() {
            println!("  [W] {}", warning);
        }
        for error in logger.errors() {
            println!("  [E] {}", error);
        }
        println!();
        if VALIDATE_ERRORS_FATAL && !logger.errors().is_empty() {
            return Err(io::Error::new(io::ErrorKind::Other, "validation failed"));
        }
    }
    #[cfg(not(feature = "validate"))]
    {
        println!("Unknown (feature 'validate' not enabled)");
    }
    #[cfg(feature = "verify")]
    {
        print!("Signature verification: ");
        if x509.subject() == x509.issuer() {
            if x509.verify_signature(None).is_ok() {
                println!("OK");
                println!("  [I] certificate is self-signed");
            } else if x509.subject() == x509.issuer() {
                println!("FAIL");
                println!("  [W] certificate looks self-signed, but signature verification failed");
            }
        } else {
            // if subject is different from issuer, we cannot verify certificate without the public key of the issuer
            println!("N/A");
        }
    }
    Ok(())
}
source

pub fn public_key(&self) -> &SubjectPublicKeyInfo<'_>

Get the certificate public key information.

Examples found in repository?
examples/print-cert.rs (line 170)
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
fn print_x509_info(x509: &X509Certificate) -> io::Result<()> {
    let version = x509.version();
    if version.0 < 3 {
        println!("  Version: {}", version);
    } else {
        println!("  Version: INVALID({})", version.0);
    }
    println!("  Serial: {}", x509.tbs_certificate.raw_serial_as_string());
    println!("  Subject: {}", x509.subject());
    println!("  Issuer: {}", x509.issuer());
    println!("  Validity:");
    println!("    NotBefore: {}", x509.validity().not_before);
    println!("    NotAfter:  {}", x509.validity().not_after);
    println!("    is_valid:  {}", x509.validity().is_valid());
    println!("  Subject Public Key Info:");
    print_x509_ski(x509.public_key());
    print_x509_signature_algorithm(&x509.signature_algorithm, 4);

    println!("  Signature Value:");
    for l in format_number_to_hex_with_colon(&x509.signature_value.data, 16) {
        println!("      {}", l);
    }
    println!("  Extensions:");
    for ext in x509.extensions() {
        print_x509_extension(&ext.oid, ext);
    }
    println!();
    print!("Structure validation status: ");
    #[cfg(feature = "validate")]
    {
        let mut logger = VecLogger::default();
        // structure validation status
        let ok = X509StructureValidator
            .chain(X509CertificateValidator)
            .validate(x509, &mut logger);
        if ok {
            println!("Ok");
        } else {
            println!("FAIL");
        }
        for warning in logger.warnings() {
            println!("  [W] {}", warning);
        }
        for error in logger.errors() {
            println!("  [E] {}", error);
        }
        println!();
        if VALIDATE_ERRORS_FATAL && !logger.errors().is_empty() {
            return Err(io::Error::new(io::ErrorKind::Other, "validation failed"));
        }
    }
    #[cfg(not(feature = "validate"))]
    {
        println!("Unknown (feature 'validate' not enabled)");
    }
    #[cfg(feature = "verify")]
    {
        print!("Signature verification: ");
        if x509.subject() == x509.issuer() {
            if x509.verify_signature(None).is_ok() {
                println!("OK");
                println!("  [I] certificate is self-signed");
            } else if x509.subject() == x509.issuer() {
                println!("FAIL");
                println!("  [W] certificate looks self-signed, but signature verification failed");
            }
        } else {
            // if subject is different from issuer, we cannot verify certificate without the public key of the issuer
            println!("N/A");
        }
    }
    Ok(())
}
source

pub fn extensions(&self) -> &[X509Extension<'a>]

Returns the certificate extensions

Examples found in repository?
examples/print-cert.rs (line 178)
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
fn print_x509_info(x509: &X509Certificate) -> io::Result<()> {
    let version = x509.version();
    if version.0 < 3 {
        println!("  Version: {}", version);
    } else {
        println!("  Version: INVALID({})", version.0);
    }
    println!("  Serial: {}", x509.tbs_certificate.raw_serial_as_string());
    println!("  Subject: {}", x509.subject());
    println!("  Issuer: {}", x509.issuer());
    println!("  Validity:");
    println!("    NotBefore: {}", x509.validity().not_before);
    println!("    NotAfter:  {}", x509.validity().not_after);
    println!("    is_valid:  {}", x509.validity().is_valid());
    println!("  Subject Public Key Info:");
    print_x509_ski(x509.public_key());
    print_x509_signature_algorithm(&x509.signature_algorithm, 4);

    println!("  Signature Value:");
    for l in format_number_to_hex_with_colon(&x509.signature_value.data, 16) {
        println!("      {}", l);
    }
    println!("  Extensions:");
    for ext in x509.extensions() {
        print_x509_extension(&ext.oid, ext);
    }
    println!();
    print!("Structure validation status: ");
    #[cfg(feature = "validate")]
    {
        let mut logger = VecLogger::default();
        // structure validation status
        let ok = X509StructureValidator
            .chain(X509CertificateValidator)
            .validate(x509, &mut logger);
        if ok {
            println!("Ok");
        } else {
            println!("FAIL");
        }
        for warning in logger.warnings() {
            println!("  [W] {}", warning);
        }
        for error in logger.errors() {
            println!("  [E] {}", error);
        }
        println!();
        if VALIDATE_ERRORS_FATAL && !logger.errors().is_empty() {
            return Err(io::Error::new(io::ErrorKind::Other, "validation failed"));
        }
    }
    #[cfg(not(feature = "validate"))]
    {
        println!("Unknown (feature 'validate' not enabled)");
    }
    #[cfg(feature = "verify")]
    {
        print!("Signature verification: ");
        if x509.subject() == x509.issuer() {
            if x509.verify_signature(None).is_ok() {
                println!("OK");
                println!("  [I] certificate is self-signed");
            } else if x509.subject() == x509.issuer() {
                println!("FAIL");
                println!("  [W] certificate looks self-signed, but signature verification failed");
            }
        } else {
            // if subject is different from issuer, we cannot verify certificate without the public key of the issuer
            println!("N/A");
        }
    }
    Ok(())
}
source

pub fn iter_extensions(&self) -> impl Iterator<Item = &X509Extension<'a>>

Returns an iterator over the certificate extensions

source

pub fn get_extension_unique( &self, oid: &Oid<'_> ) -> Result<Option<&X509Extension<'a>>, X509Error>

Searches for an extension with the given Oid.

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error DuplicateExtensions if the extension is present twice or more.

source

pub fn find_extension(&self, oid: &Oid<'_>) -> Option<&X509Extension<'a>>

👎Deprecated since 0.13.0: Do not use this function (duplicate extensions are not checked), use get_extension_unique

Searches for an extension with the given Oid.

§Duplicate extensions

Note: if there are several extensions with the same Oid, the first one is returned, masking other values.

RFC5280 forbids having duplicate extensions, but does not specify how errors should be handled.

Because of this, the find_extension method is not safe and should not be used! The get_extension_unique method checks for duplicate extensions and should be preferred.

source

pub fn extensions_map( &self ) -> Result<HashMap<Oid<'_>, &X509Extension<'a>>, X509Error>

Builds and returns a map of extensions.

If an extension is present twice, this will fail and return DuplicateExtensions.

source

pub fn basic_constraints( &self ) -> Result<Option<BasicExtension<&BasicConstraints>>, X509Error>

Attempt to get the certificate Basic Constraints extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is present twice or more.

source

pub fn key_usage(&self) -> Result<Option<BasicExtension<&KeyUsage>>, X509Error>

Attempt to get the certificate Key Usage extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

source

pub fn extended_key_usage( &self ) -> Result<Option<BasicExtension<&ExtendedKeyUsage<'_>>>, X509Error>

Attempt to get the certificate Extended Key Usage extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

source

pub fn policy_constraints( &self ) -> Result<Option<BasicExtension<&PolicyConstraints>>, X509Error>

Attempt to get the certificate Policy Constraints extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

source

pub fn inhibit_anypolicy( &self ) -> Result<Option<BasicExtension<&InhibitAnyPolicy>>, X509Error>

Attempt to get the certificate Policy Constraints extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

source

pub fn policy_mappings( &self ) -> Result<Option<BasicExtension<&PolicyMappings<'_>>>, X509Error>

Attempt to get the certificate Policy Mappings extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

source

pub fn subject_alternative_name( &self ) -> Result<Option<BasicExtension<&SubjectAlternativeName<'a>>>, X509Error>

Attempt to get the certificate Subject Alternative Name extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

source

pub fn name_constraints( &self ) -> Result<Option<BasicExtension<&NameConstraints<'_>>>, X509Error>

Attempt to get the certificate Name Constraints extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

source

pub fn is_ca(&self) -> bool

Returns true if certificate has basicConstraints CA:true

source

pub fn raw_serial(&self) -> &'a [u8]

Get the raw bytes of the certificate serial number

source

pub fn raw_serial_as_string(&self) -> String

Get a formatted string of the certificate serial number, separated by ‘:’

Examples found in repository?
examples/print-cert.rs (line 162)
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
fn print_x509_info(x509: &X509Certificate) -> io::Result<()> {
    let version = x509.version();
    if version.0 < 3 {
        println!("  Version: {}", version);
    } else {
        println!("  Version: INVALID({})", version.0);
    }
    println!("  Serial: {}", x509.tbs_certificate.raw_serial_as_string());
    println!("  Subject: {}", x509.subject());
    println!("  Issuer: {}", x509.issuer());
    println!("  Validity:");
    println!("    NotBefore: {}", x509.validity().not_before);
    println!("    NotAfter:  {}", x509.validity().not_after);
    println!("    is_valid:  {}", x509.validity().is_valid());
    println!("  Subject Public Key Info:");
    print_x509_ski(x509.public_key());
    print_x509_signature_algorithm(&x509.signature_algorithm, 4);

    println!("  Signature Value:");
    for l in format_number_to_hex_with_colon(&x509.signature_value.data, 16) {
        println!("      {}", l);
    }
    println!("  Extensions:");
    for ext in x509.extensions() {
        print_x509_extension(&ext.oid, ext);
    }
    println!();
    print!("Structure validation status: ");
    #[cfg(feature = "validate")]
    {
        let mut logger = VecLogger::default();
        // structure validation status
        let ok = X509StructureValidator
            .chain(X509CertificateValidator)
            .validate(x509, &mut logger);
        if ok {
            println!("Ok");
        } else {
            println!("FAIL");
        }
        for warning in logger.warnings() {
            println!("  [W] {}", warning);
        }
        for error in logger.errors() {
            println!("  [E] {}", error);
        }
        println!();
        if VALIDATE_ERRORS_FATAL && !logger.errors().is_empty() {
            return Err(io::Error::new(io::ErrorKind::Other, "validation failed"));
        }
    }
    #[cfg(not(feature = "validate"))]
    {
        println!("Unknown (feature 'validate' not enabled)");
    }
    #[cfg(feature = "verify")]
    {
        print!("Signature verification: ");
        if x509.subject() == x509.issuer() {
            if x509.verify_signature(None).is_ok() {
                println!("OK");
                println!("  [I] certificate is self-signed");
            } else if x509.subject() == x509.issuer() {
                println!("FAIL");
                println!("  [W] certificate looks self-signed, but signature verification failed");
            }
        } else {
            // if subject is different from issuer, we cannot verify certificate without the public key of the issuer
            println!("N/A");
        }
    }
    Ok(())
}

Trait Implementations§

source§

impl<'a> Clone for X509Certificate<'a>

source§

fn clone(&self) -> X509Certificate<'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 X509Certificate<'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 X509Certificate<'a>

source§

fn from_der(i: &'a [u8]) -> X509Result<'_, Self>

Parse a DER-encoded X.509 Certificate, and return the remaining of the input and the built object.

The returned object uses zero-copy, and so has the same lifetime as the input.

Note that only parsing is done, not validation.

Certificate  ::=  SEQUENCE  {
        tbsCertificate       TBSCertificate,
        signatureAlgorithm   AlgorithmIdentifier,
        signatureValue       BIT STRING  }
§Example

To parse a certificate and print the subject and issuer:

let res = parse_x509_certificate(DER);
match res {
    Ok((_rem, x509)) => {
        let subject = x509.subject();
        let issuer = x509.issuer();
        println!("X.509 Subject: {}", subject);
        println!("X.509 Issuer: {}", issuer);
    },
    _ => panic!("x509 parsing failed: {:?}", res),
}
source§

impl<'a> Parser<&'a [u8], X509Certificate<'a>, X509Error> for X509CertificateParser

source§

fn parse( &mut self, input: &'a [u8] ) -> IResult<&'a [u8], X509Certificate<'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 X509Certificate<'a>

source§

fn eq(&self, other: &X509Certificate<'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 Validate for X509Certificate<'_>

Available on crate feature validate only.
source§

fn validate<W, E>(&self, warn: W, err: E) -> bool
where W: FnMut(&str), E: FnMut(&str),

👎Deprecated since 0.13.0: please use X509StructureValidator instead
Attempts to validate current item. Read more
source§

fn validate_to_vec(&self) -> (bool, Vec<String>, Vec<String>)

👎Deprecated since 0.13.0: please use X509StructureValidator instead
Attempts to validate current item, storing warning and errors in Vec. Read more
source§

impl<'a> Deref for X509Certificate<'a>

§

type Target = TbsCertificate<'a>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<'a> StructuralPartialEq for X509Certificate<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for X509Certificate<'a>

§

impl<'a> Send for X509Certificate<'a>

§

impl<'a> Sync for X509Certificate<'a>

§

impl<'a> Unpin for X509Certificate<'a>

§

impl<'a> UnwindSafe for X509Certificate<'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.