Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic X509 Distribution Point extension support #1801

Merged
merged 1 commit into from
Mar 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions openssl-sys/src/handwritten/x509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand Down
27 changes: 27 additions & 0 deletions openssl-sys/src/handwritten/x509v3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 57 additions & 0 deletions openssl/src/x509/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>> {
Expand Down Expand Up @@ -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)
steffen-eiden marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

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;
Expand Down
27 changes: 27 additions & 0 deletions openssl/src/x509/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 23 additions & 0 deletions openssl/test/certv3.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
-----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-----
1 change: 1 addition & 0 deletions openssl/test/certv3_extfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
crlDistributionPoints=URI:http://example.com/crl.pem,URI:http://example.com/crl2.pem
5 changes: 4 additions & 1 deletion systest/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ fn main() {
|| s.starts_with("CRYPTO_EX_")
});
cfg.skip_struct(|s| {
s == "ProbeResult" || s == "X509_OBJECT_data" // inline union
s == "ProbeResult" ||
s == "X509_OBJECT_data" || // inline union
s == "DIST_POINT_NAME_st_anon_union" // inline union
});
cfg.skip_fn(move |s| {
s == "CRYPTO_memcmp" || // uses volatile
Expand All @@ -130,6 +132,7 @@ fn main() {
cfg.skip_field_type(|s, field| {
(s == "EVP_PKEY" && field == "pkey") || // union
(s == "GENERAL_NAME" && field == "d") || // union
(s == "DIST_POINT_NAME" && field == "name") || // union
(s == "X509_OBJECT" && field == "data") // union
});
cfg.skip_signededness(|s| {
Expand Down