From 8cfb59b9ea9046d26063837c914826a55ad9c3d7 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Sun, 22 Mar 2020 23:20:59 -0500 Subject: [PATCH 1/8] Add a way to get the certificates stored in an X509Store --- openssl-sys/src/x509.rs | 40 +++++++++++++++++++++++++++++++++++++ openssl/src/x509/mod.rs | 42 +++++++++++++++++++++++++++++++++++++++ openssl/src/x509/store.rs | 10 +++++++++- 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/openssl-sys/src/x509.rs b/openssl-sys/src/x509.rs index d9f4aae4..a3bd9fb0 100644 --- a/openssl-sys/src/x509.rs +++ b/openssl-sys/src/x509.rs @@ -74,6 +74,32 @@ cfg_if! { stack!(stack_st_X509); +pub type X509_LOOKUP_TYPE = i32; +pub const X509_LU_NONE: X509_LOOKUP_TYPE = 0; +pub const X509_LU_X509: X509_LOOKUP_TYPE = 1; +pub const X509_LU_CRL: X509_LOOKUP_TYPE = 2; + +cfg_if! { + if #[cfg(any(ossl110, libressl270))] { + pub enum X509_OBJECT {} + } else { + #[repr(C)] + pub struct X509_OBJECT { + pub type_: X509_LOOKUP_TYPE, + 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); + extern "C" { pub fn X509_verify_cert_error_string(n: c_long) -> *const c_char; @@ -347,3 +373,17 @@ cfg_if! { extern "C" { pub fn X509_verify_cert(ctx: *mut X509_STORE_CTX) -> c_int; } + +extern "C" { + pub fn X509_STORE_get0_objects(ctx: *mut X509_STORE) -> *mut stack_st_X509_OBJECT; + pub fn X509_OBJECT_free(a: *mut X509_OBJECT); +} + +cfg_if! { + if #[cfg(any(ossl110, libressl270))] { + extern "C" { + pub fn X509_OBJECT_get_type(x: *const X509_OBJECT) -> X509_LOOKUP_TYPE; + pub fn X509_OBJECT_get0_X509(x: *const X509_OBJECT) -> *mut X509; + } + } +} diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 45d09f71..b2a5db7e 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -1322,6 +1322,32 @@ impl X509AlgorithmRef { } } +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_OBJECT; + fn drop = ffi::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 { + if X509_OBJECT_get_type(self.as_ptr()) == ffi::X509_LU_X509 { + Some(X509Ref::from_ptr(X509_OBJECT_get0_X509(self.as_ptr()))) + } else { + None + } + } + } +} + +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 +1428,19 @@ cfg_if! { } } } + +cfg_if! { + if #[cfg(any(ossl110, libressl270))] { + use ffi::{X509_OBJECT_get_type, X509_OBJECT_get0_X509}; + } else { + #[allow(bad_style)] + unsafe fn X509_OBJECT_get_type(x: *mut ffi::X509_OBJECT) -> ffi::X509_LOOKUP_TYPE { + (*x).type_ + } + + #[allow(bad_style)] + unsafe fn X509_OBJECT_get0_X509(x: *mut ffi::X509_OBJECT) -> *mut ffi::X509 { + (*x).data.x509 + } + } +} diff --git a/openssl/src/x509/store.rs b/openssl/src/x509/store.rs index f533d9c7..2459a06b 100644 --- a/openssl/src/x509/store.rs +++ b/openssl/src/x509/store.rs @@ -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,10 @@ 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 certs(&self) -> &StackRef { + unsafe { StackRef::from_ptr(ffi::X509_STORE_get0_objects(self.as_ptr())) } + } +} From dfb3cb9579781b60d51565c0ce4f570f8ae5d40f Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Mon, 23 Mar 2020 10:17:02 -0500 Subject: [PATCH 2/8] Fix signedness issue --- openssl-sys/src/x509.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssl-sys/src/x509.rs b/openssl-sys/src/x509.rs index a3bd9fb0..99956fb0 100644 --- a/openssl-sys/src/x509.rs +++ b/openssl-sys/src/x509.rs @@ -74,7 +74,7 @@ cfg_if! { stack!(stack_st_X509); -pub type X509_LOOKUP_TYPE = i32; +pub type X509_LOOKUP_TYPE = u32; pub const X509_LU_NONE: X509_LOOKUP_TYPE = 0; pub const X509_LU_X509: X509_LOOKUP_TYPE = 1; pub const X509_LU_CRL: X509_LOOKUP_TYPE = 2; From e268a5ac7e0fa2fa4987d4685fe07a4b9927f99d Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Mon, 23 Mar 2020 10:20:30 -0500 Subject: [PATCH 3/8] Check null ptr for non-x509 X509Object --- openssl/src/x509/mod.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index b2a5db7e..efb5ae8e 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -1335,10 +1335,11 @@ foreign_type_and_impl_send_sync! { impl X509ObjectRef { pub fn x509(&self) -> Option<&X509Ref> { unsafe { - if X509_OBJECT_get_type(self.as_ptr()) == ffi::X509_LU_X509 { - Some(X509Ref::from_ptr(X509_OBJECT_get0_X509(self.as_ptr()))) - } else { + let ptr = X509_OBJECT_get0_X509(self.as_ptr()); + if ptr.is_null() { None + } else { + Some(X509Ref::from_ptr(ptr)) } } } @@ -1431,16 +1432,15 @@ cfg_if! { cfg_if! { if #[cfg(any(ossl110, libressl270))] { - use ffi::{X509_OBJECT_get_type, X509_OBJECT_get0_X509}; + use ffi::X509_OBJECT_get0_X509; } else { - #[allow(bad_style)] - unsafe fn X509_OBJECT_get_type(x: *mut ffi::X509_OBJECT) -> ffi::X509_LOOKUP_TYPE { - (*x).type_ - } - #[allow(bad_style)] unsafe fn X509_OBJECT_get0_X509(x: *mut ffi::X509_OBJECT) -> *mut ffi::X509 { - (*x).data.x509 + if (*x).type_ == ffi::X509_LU_X509 { + (*x).data.x509 + } else { + ptr::null_mut() + } } } } From 0769ca54fd8d7e34bf809887d70cad4a93738e8e Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Mon, 23 Mar 2020 10:23:28 -0500 Subject: [PATCH 4/8] Add x509_vfy.h header to systest --- systest/build.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/systest/build.rs b/systest/build.rs index e8bd221d..8ff03c87 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -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"); From 59bff6de8541da83cbc009852da1dc53445d2736 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Mon, 23 Mar 2020 14:31:34 -0500 Subject: [PATCH 5/8] Skip X509_OBJECT_data systests --- openssl-sys/src/x509.rs | 2 +- systest/build.rs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/openssl-sys/src/x509.rs b/openssl-sys/src/x509.rs index 99956fb0..847be83e 100644 --- a/openssl-sys/src/x509.rs +++ b/openssl-sys/src/x509.rs @@ -85,7 +85,7 @@ cfg_if! { } else { #[repr(C)] pub struct X509_OBJECT { - pub type_: X509_LOOKUP_TYPE, + pub type_: c_int, pub data: X509_OBJECT_data, } #[repr(C)] diff --git a/systest/build.rs b/systest/build.rs index 8ff03c87..e60e37ce 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -97,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 @@ -114,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") From 5c6179ce072d03ecc71add83104bc082c4bb89c2 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Mon, 23 Mar 2020 13:52:56 -0500 Subject: [PATCH 6/8] Only have constants on < ossl110 --- openssl-sys/src/x509.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/openssl-sys/src/x509.rs b/openssl-sys/src/x509.rs index 847be83e..572a29e4 100644 --- a/openssl-sys/src/x509.rs +++ b/openssl-sys/src/x509.rs @@ -74,10 +74,13 @@ cfg_if! { stack!(stack_st_X509); -pub type X509_LOOKUP_TYPE = u32; -pub const X509_LU_NONE: X509_LOOKUP_TYPE = 0; -pub const X509_LU_X509: X509_LOOKUP_TYPE = 1; -pub const X509_LU_CRL: X509_LOOKUP_TYPE = 2; +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))] { @@ -382,7 +385,6 @@ extern "C" { cfg_if! { if #[cfg(any(ossl110, libressl270))] { extern "C" { - pub fn X509_OBJECT_get_type(x: *const X509_OBJECT) -> X509_LOOKUP_TYPE; pub fn X509_OBJECT_get0_X509(x: *const X509_OBJECT) -> *mut X509; } } From 41162e27abbb67cce04c4aaf4eccc9c36ba7ef5a Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Tue, 24 Mar 2020 10:55:06 -0500 Subject: [PATCH 7/8] Add a shim for X509_STORE_get0_objects and X509_OBJECT_free --- openssl-sys/src/ossl_typ.rs | 43 +++++++++++++++++++++++++++++++++++-- openssl-sys/src/x509.rs | 15 ++++++++++--- openssl/src/x509/mod.rs | 14 +++++++++++- openssl/src/x509/store.rs | 13 ++++++++++- 4 files changed, 78 insertions(+), 7 deletions(-) diff --git a/openssl-sys/src/ossl_typ.rs b/openssl-sys/src/ossl_typ.rs index fa6eb1ba..449ecd91 100644 --- a/openssl-sys/src/ossl_typ.rs +++ b/openssl-sys/src/ossl_typ.rs @@ -342,8 +342,46 @@ cfg_if! { } } pub enum X509_CRL {} +stack!(stack_st_X509_CRL); + 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 c_int>, + verify_cb: Option 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 c_int>, + check_revocation: Option 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 c_int>, + cert_crl: + Option c_int>, + lookup_certs: + Option *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 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, } } diff --git a/openssl-sys/src/x509.rs b/openssl-sys/src/x509.rs index 572a29e4..70b8bbc1 100644 --- a/openssl-sys/src/x509.rs +++ b/openssl-sys/src/x509.rs @@ -103,6 +103,10 @@ cfg_if! { 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; @@ -377,15 +381,20 @@ 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_free(a: *mut X509_OBJECT); + pub fn X509_OBJECT_get0_X509(x: *const X509_OBJECT) -> *mut X509; } cfg_if! { - if #[cfg(any(ossl110, libressl270))] { + if #[cfg(ossl110)] { extern "C" { - pub fn X509_OBJECT_get0_X509(x: *const X509_OBJECT) -> *mut X509; + pub fn X509_OBJECT_free(a: *mut X509_OBJECT); + } + } else { + extern "C" { + pub fn X509_OBJECT_free_contents(a: *mut X509_OBJECT); } } } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index efb5ae8e..4ec47f4f 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -1324,7 +1324,7 @@ impl X509AlgorithmRef { foreign_type_and_impl_send_sync! { type CType = ffi::X509_OBJECT; - fn drop = ffi::X509_OBJECT_free; + fn drop = X509_OBJECT_free; /// An `X509` or an X509 certificate revocation list. pub struct X509Object; @@ -1444,3 +1444,15 @@ cfg_if! { } } } + +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); + } + } +} diff --git a/openssl/src/x509/store.rs b/openssl/src/x509/store.rs index 2459a06b..2fb342a1 100644 --- a/openssl/src/x509/store.rs +++ b/openssl/src/x509/store.rs @@ -109,6 +109,17 @@ foreign_type_and_impl_send_sync! { impl X509StoreRef { /// Get a reference to the cache of certificates in this store. pub fn certs(&self) -> &StackRef { - unsafe { StackRef::from_ptr(ffi::X509_STORE_get0_objects(self.as_ptr())) } + 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 + } } } From 29f62786fff33ee7d50a51835090ba7c344e311f Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 24 Mar 2020 17:20:54 -0400 Subject: [PATCH 8/8] Update openssl/src/x509/store.rs --- openssl/src/x509/store.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssl/src/x509/store.rs b/openssl/src/x509/store.rs index 2fb342a1..2ccc78d7 100644 --- a/openssl/src/x509/store.rs +++ b/openssl/src/x509/store.rs @@ -108,7 +108,7 @@ foreign_type_and_impl_send_sync! { impl X509StoreRef { /// Get a reference to the cache of certificates in this store. - pub fn certs(&self) -> &StackRef { + pub fn objects(&self) -> &StackRef { unsafe { StackRef::from_ptr(X509_STORE_get0_objects(self.as_ptr())) } } }