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

Add a way to get the certificates stored in an X509Store
This commit is contained in:
Steven Fackler 2020-03-24 19:26:31 -04:00 committed by GitHub
commit 7c4986aae2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 173 additions and 6 deletions

View File

@ -342,8 +342,46 @@ cfg_if! {
} }
} }
pub enum X509_CRL {} pub enum X509_CRL {}
stack!(stack_st_X509_CRL);
pub enum X509_NAME {} pub enum X509_NAME {}
pub enum X509_STORE {}
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 {} pub enum X509_STORE_CTX {}
cfg_if! { cfg_if! {
@ -375,7 +413,7 @@ cfg_if! {
pub policies: *mut stack_st_ASN1_OBJECT, pub policies: *mut stack_st_ASN1_OBJECT,
//pub id: *mut X509_VERIFY_PARAM_ID, //pub id: *mut X509_VERIFY_PARAM_ID,
} }
} else if #[cfg(ossl102)] { } else {
#[repr(C)] #[repr(C)]
pub struct X509_VERIFY_PARAM { pub struct X509_VERIFY_PARAM {
pub name: *mut c_char, pub name: *mut c_char,
@ -386,6 +424,7 @@ cfg_if! {
pub trust: c_int, pub trust: c_int,
pub depth: c_int, pub depth: c_int,
pub policies: *mut stack_st_ASN1_OBJECT, pub policies: *mut stack_st_ASN1_OBJECT,
#[cfg(ossl102)]
pub id: *mut X509_VERIFY_PARAM_ID, pub id: *mut X509_VERIFY_PARAM_ID,
} }
} }

View File

@ -74,6 +74,39 @@ cfg_if! {
stack!(stack_st_X509); 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" { extern "C" {
pub fn X509_verify_cert_error_string(n: c_long) -> *const c_char; pub fn X509_verify_cert_error_string(n: c_long) -> *const c_char;
@ -347,3 +380,21 @@ cfg_if! {
extern "C" { extern "C" {
pub fn X509_verify_cert(ctx: *mut X509_STORE_CTX) -> c_int; 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);
}
}
}

View File

@ -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! { cfg_if! {
if #[cfg(any(ossl110, libressl273))] { if #[cfg(any(ossl110, libressl273))] {
use ffi::{X509_getm_notAfter, X509_getm_notBefore, X509_up_ref, X509_get0_signature}; 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);
}
}
}

View File

@ -45,7 +45,8 @@ use foreign_types::ForeignTypeRef;
use std::mem; use std::mem;
use error::ErrorStack; use error::ErrorStack;
use x509::X509; use stack::StackRef;
use x509::{X509Object, X509};
use {cvt, cvt_p}; use {cvt, cvt_p};
foreign_type_and_impl_send_sync! { foreign_type_and_impl_send_sync! {
@ -104,3 +105,21 @@ foreign_type_and_impl_send_sync! {
/// Reference to an `X509Store`. /// Reference to an `X509Store`.
pub struct X509StoreRef; 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
}
}
}

View File

@ -61,7 +61,8 @@ fn main() {
.header("openssl/bn.h") .header("openssl/bn.h")
.header("openssl/aes.h") .header("openssl/aes.h")
.header("openssl/ocsp.h") .header("openssl/ocsp.h")
.header("openssl/evp.h"); .header("openssl/evp.h")
.header("openssl/x509_vfy.h");
if openssl_version.is_some() { if openssl_version.is_some() {
cfg.header("openssl/cms.h"); cfg.header("openssl/cms.h");
@ -96,7 +97,9 @@ fn main() {
|| s == "bio_info_cb" || s == "bio_info_cb"
|| s.starts_with("CRYPTO_EX_") || 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| { cfg.skip_fn(move |s| {
s == "CRYPTO_memcmp" || // uses volatile s == "CRYPTO_memcmp" || // uses volatile
@ -113,7 +116,8 @@ fn main() {
}); });
cfg.skip_field_type(|s, field| { cfg.skip_field_type(|s, field| {
(s == "EVP_PKEY" && field == "pkey") || // union (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| { cfg.skip_signededness(|s| {
s.ends_with("_cb") s.ends_with("_cb")