Unverified Commit 6af36a70 authored by Jack Rickard's avatar Jack Rickard Committed by GitHub
Browse files

Merge pull request #1801 from steffen-eiden/distpoint

Add basic X509 Distribution Point extension support
parents b127fb2b 34171f4f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@ pub struct X509_VAL {

pub enum X509_NAME_ENTRY {}

stack!(stack_st_X509_NAME_ENTRY);

stack!(stack_st_X509_NAME);

pub enum X509_EXTENSION {}
+27 −0
Original line number Diff line number Diff line
@@ -103,3 +103,30 @@ extern "C" {
    #[cfg(ossl110)]
    pub fn X509_get_extended_key_usage(x: *mut X509) -> u32;
}

#[repr(C)]
pub struct DIST_POINT_NAME {
    pub type_: c_int,
    pub name: DIST_POINT_NAME_st_anon_union,
    pub dpname: *mut X509_NAME,
}

#[repr(C)]
pub union DIST_POINT_NAME_st_anon_union {
    pub fullname: *mut stack_st_GENERAL_NAME,
    pub relativename: *mut stack_st_X509_NAME_ENTRY,
}

#[repr(C)]
pub struct DIST_POINT {
    pub distpoint: *mut DIST_POINT_NAME,
    pub reasons: *mut ASN1_BIT_STRING,
    pub CRLissuer: *mut stack_st_GENERAL_NAME,
    pub dp_reasons: c_int,
}
stack!(stack_st_DIST_POINT);

extern "C" {
    pub fn DIST_POINT_free(dist_point: *mut DIST_POINT);
    pub fn DIST_POINT_NAME_free(dist_point: *mut DIST_POINT_NAME);
}
+57 −0
Original line number Diff line number Diff line
@@ -423,6 +423,20 @@ impl X509Ref {
        }
    }

    /// Returns this certificate's CRL distribution points, if they exist.
    #[corresponds(X509_get_ext_d2i)]
    pub fn crl_distribution_points(&self) -> Option<Stack<DistPoint>> {
        unsafe {
            let stack = ffi::X509_get_ext_d2i(
                self.as_ptr(),
                ffi::NID_crl_distribution_points,
                ptr::null_mut(),
                ptr::null_mut(),
            );
            Stack::from_ptr_opt(stack as *mut _)
        }
    }

    /// Returns this certificate's issuer alternative name entries, if they exist.
    #[corresponds(X509_get_ext_d2i)]
    pub fn issuer_alt_names(&self) -> Option<Stack<GeneralName>> {
@@ -1927,6 +1941,49 @@ impl Stackable for GeneralName {
    type StackType = ffi::stack_st_GENERAL_NAME;
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::DIST_POINT;
    fn drop = ffi::DIST_POINT_free;

    /// A `X509` distribution point.
    pub struct DistPoint;
    /// Reference to `DistPoint`.
    pub struct DistPointRef;
}

impl DistPointRef {
    /// Returns the name of this distribution point if it exists
    pub fn distpoint(&self) -> Option<&DistPointNameRef> {
        unsafe { DistPointNameRef::from_const_ptr_opt((*self.as_ptr()).distpoint) }
    }
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::DIST_POINT_NAME;
    fn drop = ffi::DIST_POINT_NAME_free;

    /// A `X509` distribution point.
    pub struct DistPointName;
    /// Reference to `DistPointName`.
    pub struct DistPointNameRef;
}

impl DistPointNameRef {
    /// Returns the contents of this DistPointName if it is a fullname.
    pub fn fullname(&self) -> Option<&StackRef<GeneralName>> {
        unsafe {
            if (*self.as_ptr()).type_ != 0 {
                return None;
            }
            StackRef::from_const_ptr_opt((*self.as_ptr()).name.fullname)
        }
    }
}

impl Stackable for DistPoint {
    type StackType = ffi::stack_st_DIST_POINT;
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::ACCESS_DESCRIPTION;
    fn drop = ffi::ACCESS_DESCRIPTION_free;
+27 −0
Original line number Diff line number Diff line
@@ -986,3 +986,30 @@ fn ipv6_as_subject_alternative_name_is_formatted_in_debug() {
        8u8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 128,
    ]);
}

#[test]
fn test_dist_point() {
    let cert = include_bytes!("../../test/certv3.pem");
    let cert = X509::from_pem(cert).unwrap();

    let dps = cert.crl_distribution_points().unwrap();
    let dp = dps.get(0).unwrap();
    let dp_nm = dp.distpoint().unwrap();
    let dp_gns = dp_nm.fullname().unwrap();
    let dp_gn = dp_gns.get(0).unwrap();
    assert_eq!(dp_gn.uri().unwrap(), "http://example.com/crl.pem");

    let dp = dps.get(1).unwrap();
    let dp_nm = dp.distpoint().unwrap();
    let dp_gns = dp_nm.fullname().unwrap();
    let dp_gn = dp_gns.get(0).unwrap();
    assert_eq!(dp_gn.uri().unwrap(), "http://example.com/crl2.pem");
    assert!(dps.get(2).is_none())
}

#[test]
fn test_dist_point_null() {
    let cert = include_bytes!("../../test/cert.pem");
    let cert = X509::from_pem(cert).unwrap();
    assert!(cert.crl_distribution_points().is_none());
}
+23 −0
Original line number Diff line number Diff line
-----BEGIN CERTIFICATE-----
MIIDwTCCAqmgAwIBAgIUDeCGNunyJfBd3U/qUtmCcvbMyZwwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMzAxMjMxMzMzNTJaFw0zMzAx
MjAxMzMzNTJaMFoxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEzARBgNVBAMMCmZvb2Jh
ci5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo9CWMRLMXo1CF
/iORh9B4NhtJF/8tR9PlG95sNvyWuQQ/8jfev+8zErplxfLkt0pJqcoiZG8g9NU0
kU6o5T+/1QgZclCAoZaS0Jqxmoo2Yk/1Qsj16pnMBc10uSDk6V9aJSX1vKwONVNS
wiHA1MhX+i7Wf7/K0niq+k7hOkhleFkWgZtUq41gXh1VfOugka7UktYnk9mrBbAM
jmaloZNn2pMMAQxVg4ThiLm3zvuWqvXASWzUZc7IAd1GbN4AtDuhs252eqE9E4iT
Hk7F14wAS1JWqv666hReGHrmZJGx0xQTM9vPD1HN5t2U3KTfhO/mTlAUWVyg9tCt
OzboKgs1AgMBAAGjgZMwgZAwTgYDVR0fBEcwRTAgoB6gHIYaaHR0cDovL2V4YW1w
bGUuY29tL2NybC5wZW0wIaAfoB2GG2h0dHA6Ly9leGFtcGxlLmNvbS9jcmwyLnBl
bTAdBgNVHQ4EFgQUtnMvYaVLoe9ILBWxn/PcNC+8rDAwHwYDVR0jBBgwFoAUbNOl
A6sNXyzJjYqciKeId7g3/ZowDQYJKoZIhvcNAQELBQADggEBAJZyk6Eo4p3JIyOt
7t6ET3K18BKvlRilze+zrGkaQYvKRsP6YzbZWgcIq59hy5VeFCX5O2WP91CPG3MU
I9eRiih66/ry3G4I8QEdpRKnn0N5unbGjb5qPT5wXrhU4IO+vn3sGZGM4uIM1/3K
N/bOh9CTsu9YqrdHSGeDyNzCy/XZ/j5bP4aNm31ZDNCZDFsbjr3/yTLcpHPL0UP3
mCX8D16BDu1Nep+wK9VRuOEw6Z9tlT/VjTImzoOUoJO/o2UHfSHahX+n2aC5OpI6
BdhaFBuJ1vn+yTWf3zIjhWUdp9TlzgRyFiyetP2FcKwremVVGdDq/Y6dfXaq8CA1
6Fr9KTY=
-----END CERTIFICATE-----
Loading