From 7632ba6e56812f8a56410730c439bbd83b10783c Mon Sep 17 00:00:00 2001 From: Jack Rickard Date: Fri, 17 Mar 2023 18:19:28 +0000 Subject: [PATCH 1/4] Add issuer_name and reason_code to X509RevokedRef --- openssl-sys/src/handwritten/asn1.rs | 4 ++ openssl-sys/src/handwritten/types.rs | 1 + openssl-sys/src/x509v3.rs | 11 ++++ openssl/src/asn1.rs | 26 ++++++++ openssl/src/x509/mod.rs | 93 +++++++++++++++++++++++++++- 5 files changed, 133 insertions(+), 2 deletions(-) diff --git a/openssl-sys/src/handwritten/asn1.rs b/openssl-sys/src/handwritten/asn1.rs index 7163a69d5e..f1bcc73f34 100644 --- a/openssl-sys/src/handwritten/asn1.rs +++ b/openssl-sys/src/handwritten/asn1.rs @@ -51,6 +51,10 @@ extern "C" { pub fn ASN1_TIME_set_string(s: *mut ASN1_TIME, str: *const c_char) -> c_int; #[cfg(ossl111)] pub fn ASN1_TIME_set_string_X509(s: *mut ASN1_TIME, str: *const c_char) -> c_int; + + pub fn ASN1_ENUMERATED_free(a: *mut ASN1_ENUMERATED); + #[cfg(ossl110)] + pub fn ASN1_ENUMERATED_get_int64(pr: *mut i64, a: *const ASN1_ENUMERATED) -> c_int; } const_ptr_api! { diff --git a/openssl-sys/src/handwritten/types.rs b/openssl-sys/src/handwritten/types.rs index b229a37597..3351ceabc4 100644 --- a/openssl-sys/src/handwritten/types.rs +++ b/openssl-sys/src/handwritten/types.rs @@ -4,6 +4,7 @@ use libc::*; use super::super::*; pub enum ASN1_INTEGER {} +pub enum ASN1_ENUMERATED {} pub enum ASN1_GENERALIZEDTIME {} pub enum ASN1_STRING {} pub enum ASN1_BIT_STRING {} diff --git a/openssl-sys/src/x509v3.rs b/openssl-sys/src/x509v3.rs index 5ae4439083..d2ff53489e 100644 --- a/openssl-sys/src/x509v3.rs +++ b/openssl-sys/src/x509v3.rs @@ -91,3 +91,14 @@ pub const X509_PURPOSE_OCSP_HELPER: c_int = 8; pub const X509_PURPOSE_TIMESTAMP_SIGN: c_int = 9; pub const X509_PURPOSE_MIN: c_int = 1; pub const X509_PURPOSE_MAX: c_int = 9; + +pub const CRL_REASON_UNSPECIFIED: c_int = 0; +pub const CRL_REASON_KEY_COMPROMISE: c_int = 1; +pub const CRL_REASON_CA_COMPROMISE: c_int = 2; +pub const CRL_REASON_AFFILIATION_CHANGED: c_int = 3; +pub const CRL_REASON_SUPERSEDED: c_int = 4; +pub const CRL_REASON_CESSATION_OF_OPERATION: c_int = 5; +pub const CRL_REASON_CERTIFICATE_HOLD: c_int = 6; +pub const CRL_REASON_REMOVE_FROM_CRL: c_int = 8; +pub const CRL_REASON_PRIVILEGE_WITHDRAWN: c_int = 9; +pub const CRL_REASON_AA_COMPROMISE: c_int = 10; diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs index c0178c7e65..db752ad9f1 100644 --- a/openssl/src/asn1.rs +++ b/openssl/src/asn1.rs @@ -666,6 +666,32 @@ cfg_if! { } } +foreign_type_and_impl_send_sync! { + type CType = ffi::ASN1_ENUMERATED; + fn drop = ffi::ASN1_ENUMERATED_free; + + /// An ASN.1 enumerated. + pub struct Asn1Enumerated; + /// A reference to an [`Asn1Enumerated`]. + pub struct Asn1EnumeratedRef; +} + +impl Asn1EnumeratedRef { + /// Get the value, if it fits in the required bounds. + #[corresponds(ASN1_ENUMERATED_get)] + #[cfg(ossl110)] + pub fn get_i64(&self) -> Result { + let mut crl_reason = 0; + unsafe { + cvt(ffi::ASN1_ENUMERATED_get_int64( + &mut crl_reason, + self.as_ptr(), + ))?; + } + Ok(crl_reason) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 5b55918750..e628e64a6d 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -24,8 +24,8 @@ use std::slice; use std::str; use crate::asn1::{ - Asn1BitStringRef, Asn1IntegerRef, Asn1Object, Asn1ObjectRef, Asn1StringRef, Asn1TimeRef, - Asn1Type, + Asn1BitStringRef, Asn1Enumerated, Asn1IntegerRef, Asn1Object, Asn1ObjectRef, Asn1StringRef, + Asn1TimeRef, Asn1Type, }; use crate::bio::MemBioSlice; use crate::conf::ConfRef; @@ -1481,6 +1481,37 @@ impl X509ReqRef { } } +/// The reason that a certificate was revoked. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct CrlReason(i64); + +#[allow(missing_docs)] // no need to document the constants +impl CrlReason { + pub const UNSPECIFIED: CrlReason = CrlReason(ffi::CRL_REASON_UNSPECIFIED as i64); + pub const KEY_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_KEY_COMPROMISE as i64); + pub const CA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_CA_COMPROMISE as i64); + pub const AFFILIATION_CHANGED: CrlReason = + CrlReason(ffi::CRL_REASON_AFFILIATION_CHANGED as i64); + pub const SUPERSEDED: CrlReason = CrlReason(ffi::CRL_REASON_SUPERSEDED as i64); + pub const CESSATION_OF_OPERATION: CrlReason = + CrlReason(ffi::CRL_REASON_CESSATION_OF_OPERATION as i64); + pub const CERTIFICATE_HOLD: CrlReason = CrlReason(ffi::CRL_REASON_CERTIFICATE_HOLD as i64); + pub const REMOVE_FROM_CRL: CrlReason = CrlReason(ffi::CRL_REASON_REMOVE_FROM_CRL as i64); + pub const PRIVILEGE_WITHDRAWN: CrlReason = + CrlReason(ffi::CRL_REASON_PRIVILEGE_WITHDRAWN as i64); + pub const AA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_AA_COMPROMISE as i64); + + /// Constructs an `CrlReason` from a raw OpenSSL value. + pub fn from_raw(value: i64) -> Self { + CrlReason(value) + } + + /// Returns the raw OpenSSL value represented by this type. + pub fn as_raw(&self) -> i64 { + self.0 + } +} + foreign_type_and_impl_send_sync! { type CType = ffi::X509_REVOKED; fn drop = ffi::X509_REVOKED_free; @@ -1513,6 +1544,13 @@ impl X509RevokedRef { ffi::i2d_X509_REVOKED } + /// Copies the entry to a new `X509Revoked`. + #[corresponds(X509_NAME_dup)] + #[cfg(any(boringssl, ossl110, libressl270))] + pub fn to_owned(&self) -> Result { + unsafe { cvt_p(ffi::X509_REVOKED_dup(self.as_ptr())).map(|n| X509Revoked::from_ptr(n)) } + } + /// Get the date that the certificate was revoked #[corresponds(X509_REVOKED_get0_revocationDate)] pub fn revocation_date(&self) -> &Asn1TimeRef { @@ -1532,6 +1570,46 @@ impl X509RevokedRef { Asn1IntegerRef::from_ptr(r as *mut _) } } + + /// Get the issuer name of the revoked certificate + #[corresponds(X509_REVOKED_get_ext_d2i)] + pub fn issuer_name(&self) -> Option> { + // SAFETY: self.as_ptr() is a valid pointer to an X509_REVOKED. + unsafe { + let issuer_names = ffi::X509_REVOKED_get_ext_d2i( + self.as_ptr() as *const _, + // NID_certificate_issuer is a X509_REVOKED extension that + // returns a GENERAL_NAMES, which is a Stack + ffi::NID_certificate_issuer, + // Only one instance of the extension is permissable + ptr::null_mut(), + // Don't care if the extension is critical + ptr::null_mut(), + ); + Stack::from_ptr_opt(issuer_names as *mut _) + } + } + + /// Get the reason that the certificate was revoked + #[corresponds(X509_REVOKED_get_ext_d2i)] + #[cfg(ossl110)] + pub fn reason_code(&self) -> Option> { + let reason_code = unsafe { + // The return value may be NULL if the extension wasn't found or + // there were multiple, and we require only one. + Asn1Enumerated::from_ptr_opt(ffi::X509_REVOKED_get_ext_d2i( + // self.as_ptr() is a valid pointer to a X509_REVOKED + self.as_ptr() as *const _, + // NID_crl_reason is an X509_REVOKED extension that is an ASN1_ENUMERATED + ffi::NID_crl_reason, + // Only one instance of the extension is permissable + ptr::null_mut(), + // Don't care if the extension is critical + ptr::null_mut(), + ) as *mut _) + }?; + Some(reason_code.get_i64().map(CrlReason::from_raw)) + } } foreign_type_and_impl_send_sync! { @@ -1872,6 +1950,17 @@ impl GeneralNameRef { self.ia5_string(ffi::GEN_EMAIL) } + /// Returns the contents of this `GeneralName` if it is a `directoryName`. + pub fn directory_name(&self) -> Option<&X509NameRef> { + unsafe { + if (*self.as_ptr()).type_ != ffi::GEN_DIRNAME { + return None; + } + + Some(X509NameRef::from_const_ptr((*self.as_ptr()).d as *const _)) + } + } + /// Returns the contents of this `GeneralName` if it is a `dNSName`. pub fn dnsname(&self) -> Option<&str> { self.ia5_string(ffi::GEN_DNS) From 30aa4085e71c85637d6b1a9f9c4107e977a4a3d6 Mon Sep 17 00:00:00 2001 From: Jack Rickard Date: Mon, 27 Mar 2023 17:52:14 +0100 Subject: [PATCH 2/4] Expose X509_REVOKED_get_ext_d2i more directly --- openssl/src/asn1.rs | 2 +- openssl/src/nid.rs | 4 +- openssl/src/x509/mod.rs | 125 ++++++++++++++++++++++++---------------- 3 files changed, 78 insertions(+), 53 deletions(-) diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs index db752ad9f1..8599539add 100644 --- a/openssl/src/asn1.rs +++ b/openssl/src/asn1.rs @@ -678,7 +678,7 @@ foreign_type_and_impl_send_sync! { impl Asn1EnumeratedRef { /// Get the value, if it fits in the required bounds. - #[corresponds(ASN1_ENUMERATED_get)] + #[corresponds(ASN1_ENUMERATED_get_int64)] #[cfg(ossl110)] pub fn get_i64(&self) -> Result { let mut crl_reason = 0; diff --git a/openssl/src/nid.rs b/openssl/src/nid.rs index e4562a1c27..81b74d342f 100644 --- a/openssl/src/nid.rs +++ b/openssl/src/nid.rs @@ -51,13 +51,13 @@ pub struct Nid(c_int); #[allow(non_snake_case)] impl Nid { /// Create a `Nid` from an integer representation. - pub fn from_raw(raw: c_int) -> Nid { + pub const fn from_raw(raw: c_int) -> Nid { Nid(raw) } /// Return the integer representation of a `Nid`. #[allow(clippy::trivially_copy_pass_by_ref)] - pub fn as_raw(&self) -> c_int { + pub const fn as_raw(&self) -> c_int { self.0 } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index e628e64a6d..decb005efd 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -50,6 +50,15 @@ pub mod store; #[cfg(test)] mod tests; +/// A type of X509 extension. +/// +/// # Safety +/// The value of NID and Output must match those in OpenSSL so that +pub unsafe trait ExtensionType { + const NID: Nid; + type Output: ForeignType; +} + foreign_type_and_impl_send_sync! { type CType = ffi::X509_STORE_CTX; fn drop = ffi::X509_STORE_CTX_free; @@ -1483,31 +1492,28 @@ impl X509ReqRef { /// The reason that a certificate was revoked. #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct CrlReason(i64); +pub struct CrlReason(c_int); #[allow(missing_docs)] // no need to document the constants impl CrlReason { - pub const UNSPECIFIED: CrlReason = CrlReason(ffi::CRL_REASON_UNSPECIFIED as i64); - pub const KEY_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_KEY_COMPROMISE as i64); - pub const CA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_CA_COMPROMISE as i64); - pub const AFFILIATION_CHANGED: CrlReason = - CrlReason(ffi::CRL_REASON_AFFILIATION_CHANGED as i64); - pub const SUPERSEDED: CrlReason = CrlReason(ffi::CRL_REASON_SUPERSEDED as i64); - pub const CESSATION_OF_OPERATION: CrlReason = - CrlReason(ffi::CRL_REASON_CESSATION_OF_OPERATION as i64); - pub const CERTIFICATE_HOLD: CrlReason = CrlReason(ffi::CRL_REASON_CERTIFICATE_HOLD as i64); - pub const REMOVE_FROM_CRL: CrlReason = CrlReason(ffi::CRL_REASON_REMOVE_FROM_CRL as i64); - pub const PRIVILEGE_WITHDRAWN: CrlReason = - CrlReason(ffi::CRL_REASON_PRIVILEGE_WITHDRAWN as i64); - pub const AA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_AA_COMPROMISE as i64); + pub const UNSPECIFIED: CrlReason = CrlReason(ffi::CRL_REASON_UNSPECIFIED); + pub const KEY_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_KEY_COMPROMISE); + pub const CA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_CA_COMPROMISE); + pub const AFFILIATION_CHANGED: CrlReason = CrlReason(ffi::CRL_REASON_AFFILIATION_CHANGED); + pub const SUPERSEDED: CrlReason = CrlReason(ffi::CRL_REASON_SUPERSEDED); + pub const CESSATION_OF_OPERATION: CrlReason = CrlReason(ffi::CRL_REASON_CESSATION_OF_OPERATION); + pub const CERTIFICATE_HOLD: CrlReason = CrlReason(ffi::CRL_REASON_CERTIFICATE_HOLD); + pub const REMOVE_FROM_CRL: CrlReason = CrlReason(ffi::CRL_REASON_REMOVE_FROM_CRL); + pub const PRIVILEGE_WITHDRAWN: CrlReason = CrlReason(ffi::CRL_REASON_PRIVILEGE_WITHDRAWN); + pub const AA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_AA_COMPROMISE); /// Constructs an `CrlReason` from a raw OpenSSL value. - pub fn from_raw(value: i64) -> Self { + pub const fn from_raw(value: c_int) -> Self { CrlReason(value) } /// Returns the raw OpenSSL value represented by this type. - pub fn as_raw(&self) -> i64 { + pub const fn as_raw(&self) -> c_int { self.0 } } @@ -1571,45 +1577,59 @@ impl X509RevokedRef { } } - /// Get the issuer name of the revoked certificate + /// Get the criticality and value of an extension. + /// + /// This returns None if the extension is not present or occurs multiple times. #[corresponds(X509_REVOKED_get_ext_d2i)] - pub fn issuer_name(&self) -> Option> { - // SAFETY: self.as_ptr() is a valid pointer to an X509_REVOKED. - unsafe { - let issuer_names = ffi::X509_REVOKED_get_ext_d2i( - self.as_ptr() as *const _, - // NID_certificate_issuer is a X509_REVOKED extension that - // returns a GENERAL_NAMES, which is a Stack - ffi::NID_certificate_issuer, - // Only one instance of the extension is permissable - ptr::null_mut(), - // Don't care if the extension is critical + pub fn extension(&self) -> Result, ErrorStack> { + let mut critical = -1; + let out = unsafe { + // SAFETY: self.as_ptr() is a valid pointer to an X509_REVOKED. + let ext = ffi::X509_REVOKED_get_ext_d2i( + self.as_ptr(), + T::NID.as_raw(), + &mut critical as *mut _, ptr::null_mut(), ); - Stack::from_ptr_opt(issuer_names as *mut _) + // SAFETY: Extensions's contract promises that the type returned by + // OpenSSL here is T::Output. + T::Output::from_ptr_opt(ext as *mut _) + }; + match (critical, out) { + (0, Some(out)) => Ok(Some((false, out))), + (1, Some(out)) => Ok(Some((true, out))), + // -1 means the extension wasn't found, -2 means multiple were found. + (-1 | -2, _) => Ok(None), + // A critical value of 0 or 1 suggests success, but a null pointer + // was returned so something went wrong. + (0 | 1, None) => Err(ErrorStack::get()), + (..=-3 | 2.., _) => panic!("OpenSSL should only return -2, -1, 0, or 1 for an extension's criticality but it returned {}", critical), } } +} - /// Get the reason that the certificate was revoked - #[corresponds(X509_REVOKED_get_ext_d2i)] - #[cfg(ossl110)] - pub fn reason_code(&self) -> Option> { - let reason_code = unsafe { - // The return value may be NULL if the extension wasn't found or - // there were multiple, and we require only one. - Asn1Enumerated::from_ptr_opt(ffi::X509_REVOKED_get_ext_d2i( - // self.as_ptr() is a valid pointer to a X509_REVOKED - self.as_ptr() as *const _, - // NID_crl_reason is an X509_REVOKED extension that is an ASN1_ENUMERATED - ffi::NID_crl_reason, - // Only one instance of the extension is permissable - ptr::null_mut(), - // Don't care if the extension is critical - ptr::null_mut(), - ) as *mut _) - }?; - Some(reason_code.get_i64().map(CrlReason::from_raw)) - } +/// The CRL entry extension identifying the reason for revocation see [`CrlReason`], +/// this is as defined in RFC 5280 Section 5.3.1. +pub enum ReasonCode {} + +// SAFETY: CertificateIssuer is defined to be a stack of GeneralName in the RFC +// and in OpenSSL. +unsafe impl ExtensionType for ReasonCode { + const NID: Nid = Nid::from_raw(ffi::NID_crl_reason); + + type Output = Asn1Enumerated; +} + +/// The CRL entry extension identifying the issuer of a certificate used in +/// indirect CRLs, as defined in RFC 5280 Section 5.3.3. +pub enum CertificateIssuer {} + +// SAFETY: CertificateIssuer is defined to be a stack of GeneralName in the RFC +// and in OpenSSL. +unsafe impl ExtensionType for CertificateIssuer { + const NID: Nid = Nid::from_raw(ffi::NID_certificate_issuer); + + type Output = Stack; } foreign_type_and_impl_send_sync! { @@ -1957,7 +1977,12 @@ impl GeneralNameRef { return None; } - Some(X509NameRef::from_const_ptr((*self.as_ptr()).d as *const _)) + #[cfg(boringssl)] + let d = (*self.as_ptr()).d.ptr; + #[cfg(not(boringssl))] + let d = (*self.as_ptr()).d; + + Some(X509NameRef::from_const_ptr(d as *const _)) } } From 3b25d11504f8547637b591fa4360df78cc6c2ac1 Mon Sep 17 00:00:00 2001 From: Jack Rickard Date: Mon, 27 Mar 2023 18:40:19 +0100 Subject: [PATCH 3/4] Use range pattern compatible with MSRV --- openssl/src/x509/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index decb005efd..a6ead63a2e 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -1603,7 +1603,7 @@ impl X509RevokedRef { // A critical value of 0 or 1 suggests success, but a null pointer // was returned so something went wrong. (0 | 1, None) => Err(ErrorStack::get()), - (..=-3 | 2.., _) => panic!("OpenSSL should only return -2, -1, 0, or 1 for an extension's criticality but it returned {}", critical), + (c_int::MIN..=-2 | 2.., _) => panic!("OpenSSL should only return -2, -1, 0, or 1 for an extension's criticality but it returned {}", critical), } } } From 95680c816c55b617d2f5949cf2aedd060082840d Mon Sep 17 00:00:00 2001 From: Jack Rickard Date: Tue, 28 Mar 2023 12:08:27 +0100 Subject: [PATCH 4/4] Add test for CRL entry extensions --- openssl/src/x509/mod.rs | 1 + openssl/src/x509/tests.rs | 42 +++++++++++++++++++++++++++++-- openssl/test/entry_extensions.crl | 10 ++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 openssl/test/entry_extensions.crl diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index a6ead63a2e..e30dd80730 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -54,6 +54,7 @@ mod tests; /// /// # Safety /// The value of NID and Output must match those in OpenSSL so that +/// `Output::from_ptr_opt(*_get_ext_d2i(*, NID, ...))` is valid. pub unsafe trait ExtensionType { const NID: Nid; type Output: ForeignType; diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 57734f2665..7fb383631f 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -18,12 +18,12 @@ use crate::x509::store::X509Lookup; use crate::x509::store::X509StoreBuilder; #[cfg(any(ossl102, libressl261))] use crate::x509::verify::{X509VerifyFlags, X509VerifyParam}; -#[cfg(ossl110)] -use crate::x509::X509Builder; #[cfg(ossl102)] use crate::x509::X509PurposeId; #[cfg(any(ossl102, libressl261))] use crate::x509::X509PurposeRef; +#[cfg(ossl110)] +use crate::x509::{CrlReason, X509Builder}; use crate::x509::{ CrlStatus, X509Crl, X509Extension, X509Name, X509Req, X509StoreContext, X509VerifyResult, X509, }; @@ -31,6 +31,8 @@ use hex::{self, FromHex}; #[cfg(any(ossl102, libressl261))] use libc::time_t; +use super::{CertificateIssuer, ReasonCode}; + fn pkey() -> PKey { let rsa = Rsa::generate(2048).unwrap(); PKey::from_rsa(rsa).unwrap() @@ -611,6 +613,42 @@ fn test_load_crl() { ); } +#[test] +fn test_crl_entry_extensions() { + let crl = include_bytes!("../../test/entry_extensions.crl"); + let crl = X509Crl::from_pem(crl).unwrap(); + + let revoked_certs = crl.get_revoked().unwrap(); + let entry = &revoked_certs[0]; + + let (critical, issuer) = entry + .extension::() + .unwrap() + .expect("Certificate issuer extension should be present"); + assert!(critical, "Certificate issuer extension is critical"); + assert_eq!(issuer.len(), 1, "Certificate issuer should have one entry"); + let issuer = issuer[0] + .directory_name() + .expect("Issuer should be a directory name"); + assert_eq!( + format!("{:?}", issuer), + r#"[countryName = "GB", commonName = "Test CA"]"# + ); + + // reason_code can't be inspected without ossl110 + #[allow(unused_variables)] + let (critical, reason_code) = entry + .extension::() + .unwrap() + .expect("Reason code extension should be present"); + assert!(!critical, "Reason code extension is not critical"); + #[cfg(ossl110)] + assert_eq!( + CrlReason::KEY_COMPROMISE, + CrlReason::from_raw(reason_code.get_i64().unwrap() as ffi::c_int) + ); +} + #[test] fn test_save_subject_der() { let cert = include_bytes!("../../test/cert.pem"); diff --git a/openssl/test/entry_extensions.crl b/openssl/test/entry_extensions.crl new file mode 100644 index 0000000000..9654171cf1 --- /dev/null +++ b/openssl/test/entry_extensions.crl @@ -0,0 +1,10 @@ +-----BEGIN X509 CRL----- +MIIBXDCCAQICAQEwCgYIKoZIzj0EAwIwETEPMA0GA1UEAwwGQ1JMIENBFw0yMzAz +MjgwOTQ5MThaFw0yMzA0MDQwOTUwMDdaMIGAMH4CFE+Y95/1pOqa6c9fUEJ8c04k +xu2PFw0yMzAzMjgwOTQ3MzNaMFcwLwYDVR0dAQH/BCUwI6QhMB8xCzAJBgNVBAYT +AkdCMRAwDgYDVQQDDAdUZXN0IENBMAoGA1UdFQQDCgEBMBgGA1UdGAQRGA8yMDIz +MDMyODA5NDQ0MFqgPTA7MB8GA1UdIwQYMBaAFNX1GZ0RWuC+4gz1wuy5H32T2W+R +MAoGA1UdFAQDAgEUMAwGA1UdHAQFMAOEAf8wCgYIKoZIzj0EAwIDSAAwRQIgbl7x +W+WVAb+zlvKcJLmHVuC+gbqR4jqwGIHHgQl2J8kCIQCo/sAF5sDqy/cL+fbzBeUe +YoY2h6lIkj9ENwU8ZCt03w== +-----END X509 CRL-----