Skip to content

Commit 10cee24

Browse files
authored
Merge pull request #2003 from AdmiralGT/geoffthomas/crl-extensions
Add support for CRL extensions and the Authority Information Access extension
2 parents f2217fd + c63efb9 commit 10cee24

File tree

3 files changed

+69
-9
lines changed

3 files changed

+69
-9
lines changed

openssl/src/x509/mod.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,6 +1746,17 @@ unsafe impl ExtensionType for CertificateIssuer {
17461746
type Output = Stack<GeneralName>;
17471747
}
17481748

1749+
/// The CRL extension identifying how to access information and services for the issuer of the CRL
1750+
pub enum AuthorityInformationAccess {}
1751+
1752+
// SAFETY: AuthorityInformationAccess is defined to be a stack of AccessDescription in the RFC
1753+
// and in OpenSSL.
1754+
unsafe impl ExtensionType for AuthorityInformationAccess {
1755+
const NID: Nid = Nid::from_raw(ffi::NID_info_access);
1756+
1757+
type Output = Stack<AccessDescription>;
1758+
}
1759+
17491760
foreign_type_and_impl_send_sync! {
17501761
type CType = ffi::X509_CRL;
17511762
fn drop = ffi::X509_CRL_free;
@@ -1915,6 +1926,36 @@ impl X509CrlRef {
19151926
{
19161927
unsafe { cvt_n(ffi::X509_CRL_verify(self.as_ptr(), key.as_ptr())).map(|n| n != 0) }
19171928
}
1929+
1930+
/// Get the criticality and value of an extension.
1931+
///
1932+
/// This returns None if the extension is not present or occurs multiple times.
1933+
#[corresponds(X509_CRL_get_ext_d2i)]
1934+
pub fn extension<T: ExtensionType>(&self) -> Result<Option<(bool, T::Output)>, ErrorStack> {
1935+
let mut critical = -1;
1936+
let out = unsafe {
1937+
// SAFETY: self.as_ptr() is a valid pointer to an X509_CRL.
1938+
let ext = ffi::X509_CRL_get_ext_d2i(
1939+
self.as_ptr(),
1940+
T::NID.as_raw(),
1941+
&mut critical as *mut _,
1942+
ptr::null_mut(),
1943+
);
1944+
// SAFETY: Extensions's contract promises that the type returned by
1945+
// OpenSSL here is T::Output.
1946+
T::Output::from_ptr_opt(ext as *mut _)
1947+
};
1948+
match (critical, out) {
1949+
(0, Some(out)) => Ok(Some((false, out))),
1950+
(1, Some(out)) => Ok(Some((true, out))),
1951+
// -1 means the extension wasn't found, -2 means multiple were found.
1952+
(-1 | -2, _) => Ok(None),
1953+
// A critical value of 0 or 1 suggests success, but a null pointer
1954+
// was returned so something went wrong.
1955+
(0 | 1, None) => Err(ErrorStack::get()),
1956+
(c_int::MIN..=-2 | 2.., _) => panic!("OpenSSL should only return -2, -1, 0, or 1 for an extension's criticality but it returned {}", critical),
1957+
}
1958+
}
19181959
}
19191960

19201961
/// The result of peer certificate verification.

openssl/src/x509/tests.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use hex::{self, FromHex};
3434
#[cfg(any(ossl102, libressl261))]
3535
use libc::time_t;
3636

37-
use super::{CertificateIssuer, ReasonCode};
37+
use super::{AuthorityInformationAccess, CertificateIssuer, ReasonCode};
3838

3939
fn pkey() -> PKey<Private> {
4040
let rsa = Rsa::generate(2048).unwrap();
@@ -701,6 +701,24 @@ fn test_crl_entry_extensions() {
701701
let crl = include_bytes!("../../test/entry_extensions.crl");
702702
let crl = X509Crl::from_pem(crl).unwrap();
703703

704+
let (critical, access_info) = crl
705+
.extension::<AuthorityInformationAccess>()
706+
.unwrap()
707+
.expect("Authority Information Access extension should be present");
708+
assert!(
709+
!critical,
710+
"Authority Information Access extension is not critical"
711+
);
712+
assert_eq!(
713+
access_info.len(),
714+
1,
715+
"Authority Information Access should have one entry"
716+
);
717+
assert_eq!(access_info[0].method().to_string(), "CA Issuers");
718+
assert_eq!(
719+
access_info[0].location().uri(),
720+
Some("http://www.example.com/ca.crt")
721+
);
704722
let revoked_certs = crl.get_revoked().unwrap();
705723
let entry = &revoked_certs[0];
706724

openssl/test/entry_extensions.crl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
-----BEGIN X509 CRL-----
2-
MIIBXDCCAQICAQEwCgYIKoZIzj0EAwIwETEPMA0GA1UEAwwGQ1JMIENBFw0yMzAz
3-
MjgwOTQ5MThaFw0yMzA0MDQwOTUwMDdaMIGAMH4CFE+Y95/1pOqa6c9fUEJ8c04k
4-
xu2PFw0yMzAzMjgwOTQ3MzNaMFcwLwYDVR0dAQH/BCUwI6QhMB8xCzAJBgNVBAYT
5-
AkdCMRAwDgYDVQQDDAdUZXN0IENBMAoGA1UdFQQDCgEBMBgGA1UdGAQRGA8yMDIz
6-
MDMyODA5NDQ0MFqgPTA7MB8GA1UdIwQYMBaAFNX1GZ0RWuC+4gz1wuy5H32T2W+R
7-
MAoGA1UdFAQDAgEUMAwGA1UdHAQFMAOEAf8wCgYIKoZIzj0EAwIDSAAwRQIgbl7x
8-
W+WVAb+zlvKcJLmHVuC+gbqR4jqwGIHHgQl2J8kCIQCo/sAF5sDqy/cL+fbzBeUe
9-
YoY2h6lIkj9ENwU8ZCt03w==
2+
MIIBojCCAUkCAQEwCgYIKoZIzj0EAwIwHTEbMBkGA1UEAwwSY3J5cHRvZ3JhcGh5
3+
LmlvIENBFw0yMzA3MjUxNDA1MzlaFw0yMzA4MDExNDA1MzlaMIGAMH4CFE+Y95/1
4+
pOqa6c9fUEJ8c04kxu2PFw0yMzA3MjUxNDA1MzlaMFcwLwYDVR0dAQH/BCUwI6Qh
5+
MB8xCzAJBgNVBAYTAkdCMRAwDgYDVQQDDAdUZXN0IENBMAoGA1UdFQQDCgEBMBgG
6+
A1UdGAQRGA8yMDIzMDcyNTE0MDUzOVqgeDB2MB8GA1UdIwQYMBaAFK6qKNgsGefh
7+
XexO9WsIwiQ/73R8MAoGA1UdFAQDAgEUMAwGA1UdHAQFMAOEAf8wOQYIKwYBBQUH
8+
AQEELTArMCkGCCsGAQUFBzAChh1odHRwOi8vd3d3LmV4YW1wbGUuY29tL2NhLmNy
9+
dDAKBggqhkjOPQQDAgNHADBEAiB22SXxFnQUB41uxfyCvg2dAs2nFiR0r8jft/cd
10+
G8zcKAIgeYkNOzRn4lyopK6J94rhm8jIIuJRj3Ns9XcH+91N370=
1011
-----END X509 CRL-----

0 commit comments

Comments
 (0)