Unverified Commit 7c4986aa authored by Steven Fackler's avatar Steven Fackler Committed by GitHub
Browse files

Merge pull request #1247 from coolreader18/x509-store-certs

Add a way to get the certificates stored in an X509Store
parents dbc5459d 29f62786
Loading
Loading
Loading
Loading
+41 −2
Original line number Diff line number Diff line
@@ -342,8 +342,46 @@ cfg_if! {
    }
}
pub enum X509_CRL {}
stack!(stack_st_X509_CRL);

pub enum X509_NAME {}

cfg_if! {
    if #[cfg(any(ossl110, libressl270))] {
        pub enum X509_STORE {}
    } else {
        #[repr(C)]
        pub struct X509_STORE {
            cache: c_int,
            pub objs: *mut stack_st_X509_OBJECT,
            get_cert_methods: *mut stack_st_X509_LOOKUP,
            param: *mut X509_VERIFY_PARAM,
            verify: Option<extern "C" fn(ctx: *mut X509_STORE_CTX) -> c_int>,
            verify_cb: Option<extern "C" fn(ok: c_int, ctx: *mut X509_STORE_CTX) -> c_int>,
            get_issuer: Option<
                extern "C" fn(issuer: *mut *mut X509, ctx: *mut X509_STORE_CTX, x: *mut X509) -> c_int,
            >,
            check_issued:
                Option<extern "C" fn(ctx: *mut X509_STORE_CTX, x: *mut X509, issuer: *mut X509) -> c_int>,
            check_revocation: Option<extern "C" fn(ctx: *mut X509_STORE_CTX) -> c_int>,
            get_crl: Option<
                extern "C" fn(ctx: *mut X509_STORE_CTX, crl: *mut *mut X509_CRL, x: *mut X509) -> c_int,
            >,
            check_crl: Option<extern "C" fn(ctx: *mut X509_STORE_CTX, crl: *mut X509_CRL) -> c_int>,
            cert_crl:
                Option<extern "C" fn(ctx: *mut X509_STORE_CTX, crl: *mut X509_CRL, x: *mut X509) -> c_int>,
            lookup_certs:
                Option<extern "C" fn(ctx: *mut X509_STORE_CTX, nm: *const X509_NAME) -> *mut stack_st_X509>,
            lookup_crls: Option<
                extern "C" fn(ctx: *const X509_STORE_CTX, nm: *const X509_NAME) -> *mut stack_st_X509_CRL,
            >,
            cleanup: Option<extern "C" fn(ctx: *mut X509_STORE_CTX) -> c_int>,
            ex_data: CRYPTO_EX_DATA,
            references: c_int,
        }
    }
}

pub enum X509_STORE_CTX {}

cfg_if! {
@@ -375,7 +413,7 @@ cfg_if! {
            pub policies: *mut stack_st_ASN1_OBJECT,
            //pub id: *mut X509_VERIFY_PARAM_ID,
        }
    } else if #[cfg(ossl102)] {
    } else {
        #[repr(C)]
        pub struct X509_VERIFY_PARAM {
            pub name: *mut c_char,
@@ -386,6 +424,7 @@ cfg_if! {
            pub trust: c_int,
            pub depth: c_int,
            pub policies: *mut stack_st_ASN1_OBJECT,
            #[cfg(ossl102)]
            pub id: *mut X509_VERIFY_PARAM_ID,
        }
    }
+51 −0
Original line number Diff line number Diff line
@@ -74,6 +74,39 @@ cfg_if! {

stack!(stack_st_X509);

cfg_if! {
    if #[cfg(not(ossl110))] {
        pub const X509_LU_FAIL: c_int = 0;
        pub const X509_LU_X509: c_int = 1;
        pub const X509_LU_CRL: c_int = 2;
    }
}

cfg_if! {
    if #[cfg(any(ossl110, libressl270))] {
        pub enum X509_OBJECT {}
    } else {
        #[repr(C)]
        pub struct X509_OBJECT {
            pub type_: c_int,
            pub data: X509_OBJECT_data,
        }
        #[repr(C)]
        pub union X509_OBJECT_data {
            pub ptr: *mut c_char,
            pub x509: *mut X509,
            pub crl: *mut X509_CRL,
            pub pkey: *mut EVP_PKEY,
        }
    }
}

stack!(stack_st_X509_OBJECT);

pub enum X509_LOOKUP {}

stack!(stack_st_X509_LOOKUP);

extern "C" {
    pub fn X509_verify_cert_error_string(n: c_long) -> *const c_char;

@@ -347,3 +380,21 @@ cfg_if! {
extern "C" {
    pub fn X509_verify_cert(ctx: *mut X509_STORE_CTX) -> c_int;
}

#[cfg(any(ossl110, libressl270))]
extern "C" {
    pub fn X509_STORE_get0_objects(ctx: *mut X509_STORE) -> *mut stack_st_X509_OBJECT;
    pub fn X509_OBJECT_get0_X509(x: *const X509_OBJECT) -> *mut X509;
}

cfg_if! {
    if #[cfg(ossl110)] {
        extern "C" {
            pub fn X509_OBJECT_free(a: *mut X509_OBJECT);
        }
    } else {
        extern "C" {
            pub fn X509_OBJECT_free_contents(a: *mut X509_OBJECT);
        }
    }
}
+54 −0
Original line number Diff line number Diff line
@@ -1322,6 +1322,33 @@ impl X509AlgorithmRef {
    }
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::X509_OBJECT;
    fn drop = X509_OBJECT_free;

    /// An `X509` or an X509 certificate revocation list.
    pub struct X509Object;
    /// Reference to `X509Object`
    pub struct X509ObjectRef;
}

impl X509ObjectRef {
    pub fn x509(&self) -> Option<&X509Ref> {
        unsafe {
            let ptr = X509_OBJECT_get0_X509(self.as_ptr());
            if ptr.is_null() {
                None
            } else {
                Some(X509Ref::from_ptr(ptr))
            }
        }
    }
}

impl Stackable for X509Object {
    type StackType = ffi::stack_st_X509_OBJECT;
}

cfg_if! {
    if #[cfg(any(ossl110, libressl273))] {
        use ffi::{X509_getm_notAfter, X509_getm_notBefore, X509_up_ref, X509_get0_signature};
@@ -1402,3 +1429,30 @@ cfg_if! {
        }
    }
}

cfg_if! {
    if #[cfg(any(ossl110, libressl270))] {
        use ffi::X509_OBJECT_get0_X509;
    } else {
        #[allow(bad_style)]
        unsafe fn X509_OBJECT_get0_X509(x: *mut ffi::X509_OBJECT) -> *mut ffi::X509 {
            if (*x).type_ == ffi::X509_LU_X509 {
                (*x).data.x509
            } else {
                ptr::null_mut()
            }
        }
    }
}

cfg_if! {
    if #[cfg(ossl110)] {
        use ffi::X509_OBJECT_free;
    } else {
        #[allow(bad_style)]
        unsafe fn X509_OBJECT_free(x: *mut ffi::X509_OBJECT) {
            ffi::X509_OBJECT_free_contents(x);
            ffi::CRYPTO_free(x as *mut libc::c_void);
        }
    }
}
+20 −1
Original line number Diff line number Diff line
@@ -45,7 +45,8 @@ use foreign_types::ForeignTypeRef;
use std::mem;

use error::ErrorStack;
use x509::X509;
use stack::StackRef;
use x509::{X509Object, X509};
use {cvt, cvt_p};

foreign_type_and_impl_send_sync! {
@@ -104,3 +105,21 @@ foreign_type_and_impl_send_sync! {
    /// Reference to an `X509Store`.
    pub struct X509StoreRef;
}

impl X509StoreRef {
    /// Get a reference to the cache of certificates in this store.
    pub fn objects(&self) -> &StackRef<X509Object> {
        unsafe { StackRef::from_ptr(X509_STORE_get0_objects(self.as_ptr())) }
    }
}

cfg_if! {
    if #[cfg(any(ossl110, libressl270))] {
        use ffi::X509_STORE_get0_objects;
    } else {
        #[allow(bad_style)]
        unsafe fn X509_STORE_get0_objects(x: *mut ffi::X509_STORE) -> *mut ffi::stack_st_X509_OBJECT {
            (*x).objs
        }
    }
}
+7 −3
Original line number Diff line number Diff line
@@ -61,7 +61,8 @@ fn main() {
        .header("openssl/bn.h")
        .header("openssl/aes.h")
        .header("openssl/ocsp.h")
        .header("openssl/evp.h");
        .header("openssl/evp.h")
        .header("openssl/x509_vfy.h");

    if openssl_version.is_some() {
        cfg.header("openssl/cms.h");
@@ -96,7 +97,9 @@ fn main() {
            || s == "bio_info_cb"
            || s.starts_with("CRYPTO_EX_")
    });
    cfg.skip_struct(|s| s == "ProbeResult");
    cfg.skip_struct(|s| {
        s == "ProbeResult" || s == "X509_OBJECT_data" // inline union
    });
    cfg.skip_fn(move |s| {
        s == "CRYPTO_memcmp" ||                 // uses volatile

@@ -113,7 +116,8 @@ fn main() {
    });
    cfg.skip_field_type(|s, field| {
        (s == "EVP_PKEY" && field == "pkey") ||      // union
            (s == "GENERAL_NAME" && field == "d") // union
            (s == "GENERAL_NAME" && field == "d") || // union
            (s == "X509_OBJECT" && field == "data") // union
    });
    cfg.skip_signededness(|s| {
        s.ends_with("_cb")