aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/x509
diff options
context:
space:
mode:
authorAlex Crichton <[email protected]>2016-09-30 00:43:05 -0700
committerAlex Crichton <[email protected]>2016-10-12 22:49:55 -0700
commit43c951f743e68fac5f45119eda7c994882a1d489 (patch)
tree45169f1b92858a3ba2ad0287de1bf1ecb395804b /openssl/src/x509
parentRename NoPadding to None (diff)
downloadrust-openssl-43c951f743e68fac5f45119eda7c994882a1d489.tar.xz
rust-openssl-43c951f743e68fac5f45119eda7c994882a1d489.zip
Add support for OpenSSL 1.1.0
This commit is relatively major refactoring of the `openssl-sys` crate as well as the `openssl` crate itself. The end goal here was to support OpenSSL 1.1.0, and lots of other various tweaks happened along the way. The major new features are: * OpenSSL 1.1.0 is supported * OpenSSL 0.9.8 is no longer supported (aka all OSX users by default) * All FFI bindings are verified with the `ctest` crate (same way as the `libc` crate) * CI matrixes are vastly expanded to include 32/64 of all platforms, more OpenSSL version coverage, as well as ARM coverage on Linux * The `c_helpers` module is completely removed along with the `gcc` dependency. * The `openssl-sys` build script was completely rewritten * Now uses `OPENSSL_DIR` to find the installation, not include/lib env vars. * Better error messages for mismatched versions. * Better error messages for failing to find OpenSSL on a platform (more can be done here) * Probing of OpenSSL build-time configuration to inform the API of the `*-sys` crate. * Many Cargo features have been removed as they're now enabled by default. As this is a breaking change to both the `openssl` and `openssl-sys` crates this will necessitate a major version bump of both. There's still a few more API questions remaining but let's hash that out on a PR! Closes #452
Diffstat (limited to 'openssl/src/x509')
-rw-r--r--openssl/src/x509/mod.rs132
-rw-r--r--openssl/src/x509/tests.rs2
2 files changed, 103 insertions, 31 deletions
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs
index f5369447..086342dd 100644
--- a/openssl/src/x509/mod.rs
+++ b/openssl/src/x509/mod.rs
@@ -12,7 +12,6 @@ use std::marker::PhantomData;
use HashTypeInternals;
use asn1::Asn1Time;
-#[cfg(feature = "x509_expiry")]
use asn1::Asn1TimeRef;
use bio::{MemBio, MemBioSlice};
@@ -24,6 +23,19 @@ use ffi;
use nid::Nid;
use error::ErrorStack;
+#[cfg(ossl10x)]
+use ffi::{
+ X509_set_notBefore,
+ X509_set_notAfter,
+ ASN1_STRING_data,
+};
+#[cfg(ossl110)]
+use ffi::{
+ X509_set1_notBefore as X509_set_notBefore,
+ X509_set1_notAfter as X509_set_notAfter,
+ ASN1_STRING_get0_data as ASN1_STRING_data,
+};
+
pub mod extension;
use self::extension::{ExtensionType, Extension};
@@ -36,7 +48,7 @@ pub struct SslString(&'static str);
impl<'s> Drop for SslString {
fn drop(&mut self) {
unsafe {
- ffi::CRYPTO_free(self.0.as_ptr() as *mut c_void);
+ CRYPTO_free!(self.0.as_ptr() as *mut c_void);
}
}
}
@@ -50,8 +62,8 @@ impl Deref for SslString {
}
impl SslString {
- unsafe fn new(buf: *const c_char, len: c_int) -> SslString {
- let slice = slice::from_raw_parts(buf as *const _, len as usize);
+ unsafe fn new(buf: *const u8, len: c_int) -> SslString {
+ let slice = slice::from_raw_parts(buf, len as usize);
SslString(str::from_utf8_unchecked(slice))
}
}
@@ -311,11 +323,11 @@ impl X509Generator {
let not_before = try!(Asn1Time::days_from_now(0));
let not_after = try!(Asn1Time::days_from_now(self.days));
- try_ssl!(ffi::X509_set_notBefore(x509.as_ptr(), not_before.as_ptr() as *const _));
+ try_ssl!(X509_set_notBefore(x509.as_ptr(), not_before.as_ptr() as *const _));
// If prev line succeded - ownership should go to cert
mem::forget(not_before);
- try_ssl!(ffi::X509_set_notAfter(x509.as_ptr(), not_after.as_ptr() as *const _));
+ try_ssl!(X509_set_notAfter(x509.as_ptr(), not_after.as_ptr() as *const _));
// If prev line succeded - ownership should go to cert
mem::forget(not_after);
@@ -350,9 +362,6 @@ impl X509Generator {
}
/// Obtain a certificate signing request (CSR)
- ///
- /// Requries the `x509_generator_request` feature.
- #[cfg(feature = "x509_generator_request")]
pub fn request(&self, p_key: &PKey) -> Result<X509Req, ErrorStack> {
let cert = match self.sign(p_key) {
Ok(c) => c,
@@ -363,9 +372,9 @@ impl X509Generator {
let req = ffi::X509_to_X509_REQ(cert.as_ptr(), ptr::null_mut(), ptr::null());
try_ssl_null!(req);
- let exts = ::c_helpers::rust_0_8_X509_get_extensions(cert.as_ptr());
+ let exts = compat::X509_get0_extensions(cert.as_ptr());
if exts != ptr::null_mut() {
- try_ssl!(ffi::X509_REQ_add_extensions(req, exts));
+ try_ssl!(ffi::X509_REQ_add_extensions(req, exts as *mut _));
}
let hash_fn = self.hash_type.evp_md();
@@ -438,22 +447,18 @@ impl<'a> X509Ref<'a> {
}
/// Returns certificate Not After validity period.
- /// Requires the `x509_expiry` feature.
- #[cfg(feature = "x509_expiry")]
pub fn not_after<'b>(&'b self) -> Asn1TimeRef<'b> {
unsafe {
- let date = ::c_helpers::rust_0_8_X509_get_notAfter(self.0);
+ let date = compat::X509_get_notAfter(self.0);
assert!(!date.is_null());
Asn1TimeRef::from_ptr(date)
}
}
/// Returns certificate Not Before validity period.
- /// Requires the `x509_expiry` feature.
- #[cfg(feature = "x509_expiry")]
pub fn not_before<'b>(&'b self) -> Asn1TimeRef<'b> {
unsafe {
- let date = ::c_helpers::rust_0_8_X509_get_notBefore(self.0);
+ let date = compat::X509_get_notBefore(self.0);
assert!(!date.is_null());
Asn1TimeRef::from_ptr(date)
}
@@ -496,7 +501,7 @@ impl X509 {
/// Reads a certificate from DER.
pub fn from_der(buf: &[u8]) -> Result<X509, ErrorStack> {
unsafe {
- let mut ptr = buf.as_ptr() as *mut _;
+ let mut ptr = buf.as_ptr();
let len = cmp::min(buf.len(), c_long::max_value() as usize) as c_long;
let x509 = try_ssl_null!(ffi::d2i_X509(ptr::null_mut(), &mut ptr, len));
Ok(X509::from_ptr(x509))
@@ -524,13 +529,11 @@ impl Deref for X509 {
}
}
-#[cfg(feature = "x509_clone")]
impl Clone for X509 {
- /// Requires the `x509_clone` feature.
fn clone(&self) -> X509 {
unsafe {
- ::c_helpers::rust_0_8_X509_clone(self.as_ptr());
- X509::new(self.as_ptr())
+ compat::X509_up_ref(self.as_ptr());
+ X509::from_ptr(self.as_ptr())
}
}
}
@@ -561,7 +564,7 @@ impl<'x> X509Name<'x> {
return None;
}
- let mut str_from_asn1: *mut c_char = ptr::null_mut();
+ let mut str_from_asn1: *mut u8 = ptr::null_mut();
let len = ffi::ASN1_STRING_to_UTF8(&mut str_from_asn1, asn1_str);
if len < 0 {
@@ -779,22 +782,43 @@ pub struct GeneralNames<'a> {
}
impl<'a> Drop for GeneralNames<'a> {
+ #[cfg(ossl10x)]
fn drop(&mut self) {
unsafe {
// This transmute is dubious but it's what openssl itself does...
- let free: unsafe extern "C" fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free;
- let free: unsafe extern "C" fn(*mut c_void) = mem::transmute(free);
+ let free: unsafe extern fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free;
+ let free: unsafe extern fn(*mut c_void) = mem::transmute(free);
ffi::sk_pop_free(&mut (*self.stack).stack, Some(free));
}
}
+
+ #[cfg(ossl110)]
+ fn drop(&mut self) {
+ unsafe {
+ // This transmute is dubious but it's what openssl itself does...
+ let free: unsafe extern fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free;
+ let free: unsafe extern fn(*mut c_void) = mem::transmute(free);
+ ffi::OPENSSL_sk_pop_free(self.stack as *mut _, Some(free));
+ }
+ }
}
impl<'a> GeneralNames<'a> {
/// Returns the number of `GeneralName`s in this structure.
pub fn len(&self) -> usize {
+ self._len()
+ }
+
+ #[cfg(ossl10x)]
+ fn _len(&self) -> usize {
unsafe { (*self.stack).stack.num as usize }
}
+ #[cfg(ossl110)]
+ fn _len(&self) -> usize {
+ unsafe { ffi::OPENSSL_sk_num(self.stack as *const _) as usize }
+ }
+
/// Returns the specified `GeneralName`.
///
/// # Panics
@@ -803,14 +827,23 @@ impl<'a> GeneralNames<'a> {
pub fn get(&self, idx: usize) -> GeneralName<'a> {
unsafe {
assert!(idx < self.len());
-
GeneralName {
- name: *(*self.stack).stack.data.offset(idx as isize) as *const ffi::GENERAL_NAME,
+ name: self._get(idx),
m: PhantomData,
}
}
}
+ #[cfg(ossl10x)]
+ unsafe fn _get(&self, idx: usize) -> *const ffi::GENERAL_NAME {
+ *(*self.stack).stack.data.offset(idx as isize) as *const ffi::GENERAL_NAME
+ }
+
+ #[cfg(ossl110)]
+ unsafe fn _get(&self, idx: usize) -> *const ffi::GENERAL_NAME {
+ ffi::OPENSSL_sk_value(self.stack as *const _, idx as c_int) as *mut _
+ }
+
/// Returns an iterator over the `GeneralName`s in this structure.
pub fn iter(&self) -> GeneralNamesIter {
GeneralNamesIter {
@@ -870,7 +903,7 @@ impl<'a> GeneralName<'a> {
return None;
}
- let ptr = ffi::ASN1_STRING_data((*self.name).d as *mut _);
+ let ptr = ASN1_STRING_data((*self.name).d as *mut _);
let len = ffi::ASN1_STRING_length((*self.name).d as *mut _);
let slice = slice::from_raw_parts(ptr as *const u8, len as usize);
@@ -888,7 +921,7 @@ impl<'a> GeneralName<'a> {
return None;
}
- let ptr = ffi::ASN1_STRING_data((*self.name).d as *mut _);
+ let ptr = ASN1_STRING_data((*self.name).d as *mut _);
let len = ffi::ASN1_STRING_length((*self.name).d as *mut _);
Some(slice::from_raw_parts(ptr as *const u8, len as usize))
@@ -904,3 +937,44 @@ fn test_negative_serial() {
"All serials should be positive");
}
}
+
+#[cfg(ossl110)]
+mod compat {
+ pub use ffi::X509_getm_notAfter as X509_get_notAfter;
+ pub use ffi::X509_getm_notBefore as X509_get_notBefore;
+ pub use ffi::X509_up_ref;
+ pub use ffi::X509_get0_extensions;
+}
+
+#[cfg(ossl10x)]
+#[allow(bad_style)]
+mod compat {
+ use libc::c_int;
+ use ffi;
+
+ pub unsafe fn X509_get_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
+ (*(*(*x).cert_info).validity).notAfter
+ }
+
+ pub unsafe fn X509_get_notBefore(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
+ (*(*(*x).cert_info).validity).notBefore
+ }
+
+ pub unsafe fn X509_up_ref(x: *mut ffi::X509) {
+ ffi::CRYPTO_add_lock(&mut (*x).references,
+ 1,
+ ffi::CRYPTO_LOCK_X509,
+ "mod.rs\0".as_ptr() as *const _,
+ line!() as c_int);
+ }
+
+ pub unsafe fn X509_get0_extensions(cert: *const ffi::X509)
+ -> *const ffi::stack_st_X509_EXTENSION {
+ let info = (*cert).cert_info;
+ if info.is_null() {
+ 0 as *mut _
+ } else {
+ (*info).extensions
+ }
+ }
+}
diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs
index eac08941..07d9e1d4 100644
--- a/openssl/src/x509/tests.rs
+++ b/openssl/src/x509/tests.rs
@@ -69,7 +69,6 @@ fn test_cert_gen_extension_bad_ordering() {
}
#[test]
-#[cfg(feature = "x509_generator_request")]
fn test_req_gen() {
let pkey = pkey();
@@ -93,7 +92,6 @@ fn test_cert_loading() {
}
#[test]
-#[cfg(feature = "x509_expiry")]
fn test_cert_issue_validity() {
let cert = include_bytes!("../../test/cert.pem");
let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");