From e60c257019f49d783b430551a8748886471f9aa8 Mon Sep 17 00:00:00 2001 From: David Weinstein Date: Wed, 17 Aug 2016 00:48:56 -0400 Subject: [PATCH 01/13] Improve build script - try and fallback to a mirror when openssl.org is down - check the sha1 of the downloaded tarball --- openssl/test/build.sh | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/openssl/test/build.sh b/openssl/test/build.sh index 982cc5cb..775479dd 100755 --- a/openssl/test/build.sh +++ b/openssl/test/build.sh @@ -1,6 +1,11 @@ #!/bin/bash set -e +MAX_REDIRECTS=5 +OPENSSL=openssl-1.0.2h.tar.gz +OUT=/tmp/$OPENSSL +SHA1="577585f5f5d299c44dd3c993d3c0ac7a219e4949" + if [ "$TRAVIS_OS_NAME" == "osx" ]; then exit 0 fi @@ -13,9 +18,15 @@ else OS_COMPILER=linux-x86_64 fi -mkdir /tmp/openssl +mkdir -p /tmp/openssl cd /tmp/openssl -curl https://openssl.org/source/openssl-1.0.2h.tar.gz | tar --strip-components=1 -xzf - + +curl -o $OUT -L --max-redirs $MAX_REDIRECTS https://openssl.org/source/$OPENSSL \ + || curl -o $OUT -L --max-redirs ${MAX_REDIRECTS} http://mirrors.ibiblio.org/openssl/source/$OPENSSL + +echo "$SHA1 $OUT" | sha1sum -c - || exit 1 + +tar --strip-components=1 -xzf $OUT ./Configure --prefix=$HOME/openssl shared --cross-compile-prefix=$CROSS $OS_COMPILER make make install From e64d3fcfcc98c5a79a709692a724d8d02b913dd6 Mon Sep 17 00:00:00 2001 From: David Weinstein Date: Wed, 17 Aug 2016 00:58:05 -0400 Subject: [PATCH 02/13] Fix finicky sha1 stdin format --- openssl/test/build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openssl/test/build.sh b/openssl/test/build.sh index 775479dd..2c38f3a3 100755 --- a/openssl/test/build.sh +++ b/openssl/test/build.sh @@ -24,9 +24,10 @@ cd /tmp/openssl curl -o $OUT -L --max-redirs $MAX_REDIRECTS https://openssl.org/source/$OPENSSL \ || curl -o $OUT -L --max-redirs ${MAX_REDIRECTS} http://mirrors.ibiblio.org/openssl/source/$OPENSSL -echo "$SHA1 $OUT" | sha1sum -c - || exit 1 +echo "$SHA1 $OUT" | sha1sum -c - tar --strip-components=1 -xzf $OUT + ./Configure --prefix=$HOME/openssl shared --cross-compile-prefix=$CROSS $OS_COMPILER make make install From f9cd4bff1f371336bc4f69298713069ce09825b7 Mon Sep 17 00:00:00 2001 From: David Weinstein Date: Wed, 3 Aug 2016 15:56:38 -0400 Subject: [PATCH 03/13] Progress on asn1 expiry - Use MemBio and implement `Display` for Asn1Time - Tweak doc for asn1 `not_before`, `not_after` --- openssl-sys/src/lib.rs | 5 ++++- openssl/src/asn1/mod.rs | 13 +++++++++++++ openssl/src/c_helpers.c | 8 ++++++++ openssl/src/c_helpers.rs | 3 ++- openssl/src/error.rs | 6 ++++++ openssl/src/x509/mod.rs | 16 ++++++++++++++++ 6 files changed, 49 insertions(+), 2 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index be3ae53e..92be6183 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -7,7 +7,7 @@ extern crate libc; #[cfg(target_os = "nacl")] extern crate libressl_pnacl_sys; -use libc::{c_void, c_int, c_char, c_ulong, c_long, c_uint, c_uchar, size_t}; +use libc::{c_void, c_int, c_char, c_ulong, c_long, c_uint, c_uchar, size_t, FILE}; use std::mem; use std::ptr; use std::sync::{Mutex, MutexGuard}; @@ -625,13 +625,16 @@ extern "C" { pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING; pub fn ASN1_TIME_free(tm: *mut ASN1_TIME); + pub fn ASN1_TIME_print(b: *mut BIO, tm: *const ASN1_TIME); pub fn BIO_ctrl(b: *mut BIO, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long; pub fn BIO_free_all(b: *mut BIO); pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO; + pub fn BIO_new_fp(stream: *mut FILE, close_flag: c_int) -> *mut BIO; pub fn BIO_new_socket(sock: c_int, close_flag: c_int) -> *mut BIO; pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int; pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int; + pub fn BIO_s_file() -> *const BIO_METHOD; pub fn BIO_s_mem() -> *const BIO_METHOD; pub fn BIO_new_mem_buf(buf: *const c_void, len: c_int) -> *mut BIO; pub fn BIO_set_flags(b: *mut BIO, flags: c_int); diff --git a/openssl/src/asn1/mod.rs b/openssl/src/asn1/mod.rs index 7d209775..40b6e0f7 100644 --- a/openssl/src/asn1/mod.rs +++ b/openssl/src/asn1/mod.rs @@ -1,10 +1,12 @@ use libc::c_long; use std::ptr; +use std::fmt; use ffi; use error::ErrorStack; pub struct Asn1Time(*mut ffi::ASN1_TIME); +use bio::MemBio; impl Asn1Time { /// Wraps existing ASN1_TIME and takes ownership @@ -32,6 +34,17 @@ impl Asn1Time { } } +impl fmt::Display for Asn1Time { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mem_bio = try!(MemBio::new()); + let as_str = unsafe { + ffi::ASN1_TIME_print(mem_bio.handle(), self.handle); + String::from_utf8_unchecked(mem_bio.get_buf().to_owned()) + }; + write!(f, "{}", as_str) + } +} + impl Drop for Asn1Time { fn drop(&mut self) { unsafe { ffi::ASN1_TIME_free(self.0) }; diff --git a/openssl/src/c_helpers.c b/openssl/src/c_helpers.c index 5d149553..08b5b6d3 100644 --- a/openssl/src/c_helpers.c +++ b/openssl/src/c_helpers.c @@ -15,6 +15,14 @@ STACK_OF(X509_EXTENSION) *rust_0_8_X509_get_extensions(X509 *x) { return x->cert_info ? x->cert_info->extensions : NULL; } +ASN1_TIME* rust_0_8_X509_get_notAfter_shim(X509 *x) { + return X509_get_notAfter(x); +} + +ASN1_TIME* rust_0_8_X509_get_notBefore_shim(X509 *x) { + return X509_get_notBefore(x); +} + DH *rust_0_8_DH_new_from_params(BIGNUM *p, BIGNUM *g, BIGNUM *q) { DH *dh; diff --git a/openssl/src/c_helpers.rs b/openssl/src/c_helpers.rs index 74ddb9ac..d16c3125 100644 --- a/openssl/src/c_helpers.rs +++ b/openssl/src/c_helpers.rs @@ -6,7 +6,8 @@ extern "C" { pub fn rust_0_8_SSL_CTX_clone(cxt: *mut ffi::SSL_CTX); pub fn rust_0_8_X509_clone(x509: *mut ffi::X509); pub fn rust_0_8_X509_get_extensions(x: *mut ffi::X509) -> *mut ffi::stack_st_X509_EXTENSION; - + pub fn rust_0_8_X509_get_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME; + pub fn rust_0_8_X509_get_notBefore(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME; pub fn rust_0_8_HMAC_Init_ex(ctx: *mut ffi::HMAC_CTX, key: *const c_void, keylen: c_int, md: *const ffi::EVP_MD, impl_: *mut ffi::ENGINE) -> c_int; pub fn rust_0_8_HMAC_Final(ctx: *mut ffi::HMAC_CTX, output: *mut c_uchar, len: *mut c_uint) -> c_int; pub fn rust_0_8_HMAC_Update(ctx: *mut ffi::HMAC_CTX, input: *const c_uchar, len: c_uint) -> c_int; diff --git a/openssl/src/error.rs b/openssl/src/error.rs index 5fa542c2..cc89b5db 100644 --- a/openssl/src/error.rs +++ b/openssl/src/error.rs @@ -54,6 +54,12 @@ impl From for io::Error { } } +impl From for fmt::Error { + fn from(_: ErrorStack) -> fmt::Error { + fmt::Error + } +} + /// An error reported from OpenSSL. pub struct Error(c_ulong); diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 0cc0eca7..851dd881 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -433,6 +433,22 @@ impl<'a> X509Ref<'a> { } } + /// Returns Issuer validity notAfter + pub fn not_after(&self) -> Asn1Time { + unsafe { + let date = ffi_extras::X509_get_notAfter(self.handle()); + Asn1Time::from_raw(date) + } + } + + /// Returns Issuer validity notBefore + pub fn not_before(&self) -> Asn1Time { + unsafe { + let date = ffi_extras::X509_get_notBefore(self.handle()); + Asn1Time::from_raw(date) + } + } + /// Writes certificate as PEM pub fn to_pem(&self) -> Result, ErrorStack> { let mem_bio = try!(MemBio::new()); From 32a4e2ba50786a3c5a0d6c5951236c16e2976955 Mon Sep 17 00:00:00 2001 From: David Weinstein Date: Mon, 8 Aug 2016 16:42:02 -0400 Subject: [PATCH 04/13] Introduce `Asn1TimeRef` --- openssl/src/asn1/mod.rs | 36 ++++++++++++++++++++++++++++-------- openssl/src/x509/mod.rs | 14 +++++++------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/openssl/src/asn1/mod.rs b/openssl/src/asn1/mod.rs index 40b6e0f7..4fb4c7cf 100644 --- a/openssl/src/asn1/mod.rs +++ b/openssl/src/asn1/mod.rs @@ -1,17 +1,19 @@ use libc::c_long; -use std::ptr; -use std::fmt; +use std::{ptr, fmt}; +use std::marker::PhantomData; +use std::ops::Deref; +use bio::MemBio; use ffi; use error::ErrorStack; -pub struct Asn1Time(*mut ffi::ASN1_TIME); -use bio::MemBio; +/// Corresponds to the ASN.1 structure Time defined in RFC5280 +pub struct Asn1Time(Asn1TimeRef<'static>); impl Asn1Time { /// Wraps existing ASN1_TIME and takes ownership pub unsafe fn from_ptr(handle: *mut ffi::ASN1_TIME) -> Asn1Time { - Asn1Time(handle) + Asn1Time(Asn1TimeRef::from_ptr(handle)) } fn from_period(period: c_long) -> Result { @@ -27,6 +29,24 @@ impl Asn1Time { pub fn days_from_now(days: u32) -> Result { Asn1Time::from_period(days as c_long * 60 * 60 * 24) } +} + +impl Deref for Asn1Time { + type Target = Asn1TimeRef<'static>; + + fn deref(&self) -> &Asn1TimeRef<'static> { + &self.0 + } +} + +/// A borrowed Asn1Time +pub struct Asn1TimeRef<'a>(*mut ffi::ASN1_TIME, PhantomData<&'a ()>); + +impl<'a> Asn1TimeRef<'a> { + /// Creates a new `Asn1TimeRef` wrapping the provided handle. + pub unsafe fn from_ptr(handle: *mut ffi::ASN1_TIME) -> Asn1TimeRef<'a> { + Asn1TimeRef(handle, PhantomData) + } /// Returns the raw handle pub fn as_ptr(&self) -> *mut ffi::ASN1_TIME { @@ -34,11 +54,11 @@ impl Asn1Time { } } -impl fmt::Display for Asn1Time { +impl<'a> fmt::Display for Asn1TimeRef<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mem_bio = try!(MemBio::new()); let as_str = unsafe { - ffi::ASN1_TIME_print(mem_bio.handle(), self.handle); + ffi::ASN1_TIME_print(mem_bio.as_ptr(), self.0); String::from_utf8_unchecked(mem_bio.get_buf().to_owned()) }; write!(f, "{}", as_str) @@ -47,6 +67,6 @@ impl fmt::Display for Asn1Time { impl Drop for Asn1Time { fn drop(&mut self) { - unsafe { ffi::ASN1_TIME_free(self.0) }; + unsafe { ffi::ASN1_TIME_free(self.as_ptr()) }; } } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 851dd881..dc649f18 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -10,7 +10,7 @@ use std::collections::HashMap; use std::marker::PhantomData; use HashTypeInternals; -use asn1::Asn1Time; +use asn1::{Asn1Time, Asn1TimeRef}; use bio::{MemBio, MemBioSlice}; use crypto::hash; use crypto::hash::Type as HashType; @@ -434,18 +434,18 @@ impl<'a> X509Ref<'a> { } /// Returns Issuer validity notAfter - pub fn not_after(&self) -> Asn1Time { + pub fn not_after(&self) -> Asn1TimeRef { unsafe { - let date = ffi_extras::X509_get_notAfter(self.handle()); - Asn1Time::from_raw(date) + let date = ::c_helpers::rust_0_8_X509_get_notAfter(self.0); + Asn1TimeRef::from_ptr(date) } } /// Returns Issuer validity notBefore - pub fn not_before(&self) -> Asn1Time { + pub fn not_before(&self) -> Asn1TimeRef { unsafe { - let date = ffi_extras::X509_get_notBefore(self.handle()); - Asn1Time::from_raw(date) + let date = ::c_helpers::rust_0_8_X509_get_notBefore(self.0); + Asn1TimeRef::from_ptr(date) } } From 96b1ef829cc51a901dd7b7225b9307b8628a4898 Mon Sep 17 00:00:00 2001 From: David Weinstein Date: Tue, 16 Aug 2016 22:39:30 -0400 Subject: [PATCH 05/13] Add `"x509_expiry"` feature flag - fix return of `ASN1_TIME_print` - assert on null `date` --- openssl-sys/src/lib.rs | 2 +- openssl/Cargo.toml | 1 + openssl/src/asn1/mod.rs | 2 +- openssl/src/c_helpers.c | 4 ++-- openssl/src/x509/mod.rs | 4 ++++ 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 92be6183..ab29f55c 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -625,7 +625,7 @@ extern "C" { pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING; pub fn ASN1_TIME_free(tm: *mut ASN1_TIME); - pub fn ASN1_TIME_print(b: *mut BIO, tm: *const ASN1_TIME); + pub fn ASN1_TIME_print(b: *mut BIO, tm: *const ASN1_TIME) -> c_int; pub fn BIO_ctrl(b: *mut BIO, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long; pub fn BIO_free_all(b: *mut BIO); diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index d1d709a3..9c09aed6 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -30,6 +30,7 @@ hmac_clone = ["openssl-sys/hmac_clone"] c_helpers = ["gcc"] x509_clone = ["c_helpers"] x509_generator_request = ["c_helpers"] +x509_expiry = ["c_helpers"] ssl_context_clone = ["c_helpers"] hmac = ["c_helpers"] dh_from_params = ["c_helpers"] diff --git a/openssl/src/asn1/mod.rs b/openssl/src/asn1/mod.rs index 4fb4c7cf..1eab9f04 100644 --- a/openssl/src/asn1/mod.rs +++ b/openssl/src/asn1/mod.rs @@ -58,7 +58,7 @@ impl<'a> fmt::Display for Asn1TimeRef<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mem_bio = try!(MemBio::new()); let as_str = unsafe { - ffi::ASN1_TIME_print(mem_bio.as_ptr(), self.0); + try_ssl!(ffi::ASN1_TIME_print(mem_bio.as_ptr(), self.0)); String::from_utf8_unchecked(mem_bio.get_buf().to_owned()) }; write!(f, "{}", as_str) diff --git a/openssl/src/c_helpers.c b/openssl/src/c_helpers.c index 08b5b6d3..6e6a5021 100644 --- a/openssl/src/c_helpers.c +++ b/openssl/src/c_helpers.c @@ -15,11 +15,11 @@ STACK_OF(X509_EXTENSION) *rust_0_8_X509_get_extensions(X509 *x) { return x->cert_info ? x->cert_info->extensions : NULL; } -ASN1_TIME* rust_0_8_X509_get_notAfter_shim(X509 *x) { +ASN1_TIME* rust_0_8_X509_get_notAfter(X509 *x) { return X509_get_notAfter(x); } -ASN1_TIME* rust_0_8_X509_get_notBefore_shim(X509 *x) { +ASN1_TIME* rust_0_8_X509_get_notBefore(X509 *x) { return X509_get_notBefore(x); } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index dc649f18..bb5743e9 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -434,17 +434,21 @@ impl<'a> X509Ref<'a> { } /// Returns Issuer validity notAfter + #[cfg(feature = "x509_expiry")] pub fn not_after(&self) -> Asn1TimeRef { unsafe { let date = ::c_helpers::rust_0_8_X509_get_notAfter(self.0); + assert!(!date.is_null()); Asn1TimeRef::from_ptr(date) } } /// Returns Issuer validity notBefore + #[cfg(feature = "x509_expiry")] pub fn not_before(&self) -> Asn1TimeRef { unsafe { let date = ::c_helpers::rust_0_8_X509_get_notBefore(self.0); + assert!(!date.is_null()); Asn1TimeRef::from_ptr(date) } } From 8fa4059b82545740440d9e6c796b644327b83c2e Mon Sep 17 00:00:00 2001 From: David Weinstein Date: Tue, 16 Aug 2016 22:50:20 -0400 Subject: [PATCH 06/13] Add test for `"x509_validity"` feature --- openssl/src/x509/tests.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 43add896..eac08941 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -92,6 +92,18 @@ fn test_cert_loading() { assert_eq!(fingerprint, hash_vec); } +#[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"); + let not_before = cert.not_before().to_string(); + let not_after = cert.not_after().to_string(); + + assert_eq!(not_before, "Aug 14 17:00:03 2016 GMT"); + assert_eq!(not_after, "Aug 12 17:00:03 2026 GMT"); +} + #[test] fn test_save_der() { let cert = include_bytes!("../../test/cert.pem"); From 234ce581f9401a7298d67e52bdeb857d4b53e645 Mon Sep 17 00:00:00 2001 From: David Weinstein Date: Tue, 16 Aug 2016 23:31:01 -0400 Subject: [PATCH 07/13] Add x509_validity feature to travis tests - also update docs for new x509 `not_before`, `not_after` --- openssl/src/x509/mod.rs | 6 ++++-- openssl/test/run.sh | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index bb5743e9..649dfdc2 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -433,7 +433,8 @@ impl<'a> X509Ref<'a> { } } - /// Returns Issuer validity notAfter + /// Returns certificate Not Before validity period. + /// Requires the `x509_expiry` feature. #[cfg(feature = "x509_expiry")] pub fn not_after(&self) -> Asn1TimeRef { unsafe { @@ -443,7 +444,8 @@ impl<'a> X509Ref<'a> { } } - /// Returns Issuer validity notBefore + /// Returns certificate Not After validity period. + /// Requires the `x509_expiry` feature. #[cfg(feature = "x509_expiry")] pub fn not_before(&self) -> Asn1TimeRef { unsafe { diff --git a/openssl/test/run.sh b/openssl/test/run.sh index b9481837..2c2473b1 100755 --- a/openssl/test/run.sh +++ b/openssl/test/run.sh @@ -4,7 +4,7 @@ set -e MAIN_TARGETS=https://static.rust-lang.org/dist if [ "$TEST_FEATURES" == "true" ]; then - FEATURES="tlsv1_2 tlsv1_1 dtlsv1 dtlsv1_2 sslv3 aes_xts aes_ctr npn alpn rfc5114 ecdh_auto pkcs5_pbkdf2_hmac x509_clone ssl_context_clone x509_generator_request hmac hmac_clone dh_from_params" + FEATURES="tlsv1_2 tlsv1_1 dtlsv1 dtlsv1_2 sslv3 aes_xts aes_ctr npn alpn rfc5114 ecdh_auto pkcs5_pbkdf2_hmac x509_clone ssl_context_clone x509_generator_request hmac hmac_clone dh_from_params x509_expiry" fi if [ "$TRAVIS_OS_NAME" != "osx" ]; then From 90c42fc026bb2be02da93f5b73e781e854e3544c Mon Sep 17 00:00:00 2001 From: David Weinstein Date: Tue, 16 Aug 2016 23:56:37 -0400 Subject: [PATCH 08/13] Fix docs --- openssl/src/x509/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 649dfdc2..12a122b2 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -433,7 +433,7 @@ impl<'a> X509Ref<'a> { } } - /// Returns certificate Not Before validity period. + /// Returns certificate Not After validity period. /// Requires the `x509_expiry` feature. #[cfg(feature = "x509_expiry")] pub fn not_after(&self) -> Asn1TimeRef { @@ -444,7 +444,7 @@ impl<'a> X509Ref<'a> { } } - /// Returns certificate Not After validity period. + /// Returns certificate Not Before validity period. /// Requires the `x509_expiry` feature. #[cfg(feature = "x509_expiry")] pub fn not_before(&self) -> Asn1TimeRef { From 06f19cf285c9fc3b46bd8baca2825dcf1634a64a Mon Sep 17 00:00:00 2001 From: David Weinstein Date: Tue, 16 Aug 2016 23:59:24 -0400 Subject: [PATCH 09/13] Be explicit regarding Asn1TimeRef lifetimes --- openssl/src/x509/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 12a122b2..31a6cae8 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -436,7 +436,7 @@ impl<'a> X509Ref<'a> { /// Returns certificate Not After validity period. /// Requires the `x509_expiry` feature. #[cfg(feature = "x509_expiry")] - pub fn not_after(&self) -> Asn1TimeRef { + pub fn not_after<'b>(&'b self) -> Asn1TimeRef<'b> { unsafe { let date = ::c_helpers::rust_0_8_X509_get_notAfter(self.0); assert!(!date.is_null()); @@ -447,7 +447,7 @@ impl<'a> X509Ref<'a> { /// Returns certificate Not Before validity period. /// Requires the `x509_expiry` feature. #[cfg(feature = "x509_expiry")] - pub fn not_before(&self) -> Asn1TimeRef { + pub fn not_before<'b>(&'b self) -> Asn1TimeRef<'b> { unsafe { let date = ::c_helpers::rust_0_8_X509_get_notBefore(self.0); assert!(!date.is_null()); From 7a653282a9132b6110554afb7a50938a602059b0 Mon Sep 17 00:00:00 2001 From: David Weinstein Date: Wed, 17 Aug 2016 00:10:41 -0400 Subject: [PATCH 10/13] Get rid of use Asn1TimeRef warning for some builds --- openssl/src/x509/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 31a6cae8..1319b75c 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -10,7 +10,10 @@ use std::collections::HashMap; use std::marker::PhantomData; use HashTypeInternals; -use asn1::{Asn1Time, Asn1TimeRef}; +use asn1::Asn1Time; +#[cfg(feature = "x509_expiry")] +use asn1::Asn1TimeRef; + use bio::{MemBio, MemBioSlice}; use crypto::hash; use crypto::hash::Type as HashType; From 80ed1ef8ab900d3532da17da79ec85d350fdffd6 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 16 Aug 2016 22:41:36 -0700 Subject: [PATCH 11/13] Ignore flickering test on windows --- openssl/src/ssl/tests/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index 4e4985e1..2881d4fe 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -909,6 +909,7 @@ fn test_write_nonblocking() { } #[test] +#[cfg_attr(windows, ignore)] // FIXME flickers on appveyor fn test_read_nonblocking() { let (_s, stream) = Server::new(); stream.set_nonblocking(true).unwrap(); From cd69343d67081ab9c070f21d58918433a44f97bf Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 17 Aug 2016 19:30:57 -0700 Subject: [PATCH 12/13] Fix SslContext::add_extra_chain_cert SSL_CTX_add_extra_chain_cert assumes ownership of the certificate, so the method really needs to take an X509 by value. Work around this by manually cloning the cert. This method has been around for over a year but I'm guessing nobody actually used it since it produces a nice double free into segfault! --- openssl-sys/src/lib.rs | 1 + openssl/src/ssl/mod.rs | 11 ++++++++--- openssl/src/ssl/tests/mod.rs | 8 ++++++++ openssl/src/x509/mod.rs | 11 +++++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index ab29f55c..be9de412 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1073,6 +1073,7 @@ extern "C" { pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: *mut stack_st_X509_EXTENSION) -> c_int; pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; + pub fn d2i_X509(a: *mut *mut X509, pp: *mut *mut c_uchar, length: c_long) -> *mut X509; pub fn i2d_X509_bio(b: *mut BIO, x: *mut X509) -> c_int; pub fn i2d_X509_REQ_bio(b: *mut BIO, x: *mut X509_REQ) -> c_int; diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 64a2ccaf..6e365af6 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -535,9 +535,14 @@ impl<'a> SslContextRef<'a> { /// Adds a certificate to the certificate chain presented together with the /// certificate specified using set_certificate() pub fn add_extra_chain_cert(&mut self, cert: &X509Ref) -> Result<(), ErrorStack> { - wrap_ssl_result(unsafe { - ffi::SSL_CTX_add_extra_chain_cert(self.as_ptr(), cert.as_ptr()) as c_int - }) + // FIXME this should really just take an X509 by value + let der = try!(cert.to_der()); + let cert = try!(X509::from_der(&der)); + unsafe { + try_ssl!(ffi::SSL_CTX_add_extra_chain_cert(self.as_ptr(), cert.as_ptr())); + } + mem::forget(cert); + Ok(()) } /// Specifies the file that contains private key diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index 2881d4fe..3bbbed03 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -1081,3 +1081,11 @@ fn default_verify_paths() { assert!(result.starts_with(b"HTTP/1.0")); assert!(result.ends_with(b"\r\n") || result.ends_with(b"")); } + +#[test] +fn add_extra_chain_cert() { + let cert = include_bytes!("../../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap(); + ctx.add_extra_chain_cert(&cert).unwrap(); +} diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 1319b75c..f5369447 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -1,4 +1,5 @@ use libc::{c_char, c_int, c_long, c_ulong, c_void}; +use std::cmp; use std::ffi::CString; use std::mem; use std::ptr; @@ -492,6 +493,16 @@ impl X509 { X509::from_ptr(x509) } + /// Reads a certificate from DER. + pub fn from_der(buf: &[u8]) -> Result { + unsafe { + let mut ptr = buf.as_ptr() as *mut _; + 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)) + } + } + /// Reads a certificate from PEM. pub fn from_pem(buf: &[u8]) -> Result { let mem_bio = try!(MemBioSlice::new(buf)); From 4718a88e0437ca138854a7128fb29d1c3831d34e Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 18 Aug 2016 12:59:22 -0700 Subject: [PATCH 13/13] Release openssl-sys v0.7.17, openssl v0.8.2 --- README.md | 2 +- openssl-sys/Cargo.toml | 4 ++-- openssl-sys/src/lib.rs | 2 +- openssl/Cargo.toml | 6 +++--- openssl/src/lib.rs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index da4411b2..1ae43ff4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://travis-ci.org/sfackler/rust-openssl.svg?branch=master)](https://travis-ci.org/sfackler/rust-openssl) -[Documentation](https://sfackler.github.io/rust-openssl/doc/v0.8.1/openssl). +[Documentation](https://sfackler.github.io/rust-openssl/doc/v0.8.2/openssl). ## Building diff --git a/openssl-sys/Cargo.toml b/openssl-sys/Cargo.toml index 4b2b6691..dcdf9d1a 100644 --- a/openssl-sys/Cargo.toml +++ b/openssl-sys/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "openssl-sys" -version = "0.7.16" +version = "0.7.17" authors = ["Alex Crichton ", "Steven Fackler "] license = "MIT" description = "FFI bindings to OpenSSL" repository = "https://github.com/sfackler/rust-openssl" -documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.16/openssl_sys" +documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.17/openssl_sys" links = "openssl" build = "build.rs" diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index be9de412..380f0058 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1,6 +1,6 @@ #![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)] #![allow(dead_code)] -#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.7.16")] +#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.7.17")] extern crate libc; diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index 9c09aed6..96402eb8 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "openssl" -version = "0.8.1" +version = "0.8.2" authors = ["Steven Fackler "] license = "Apache-2.0" description = "OpenSSL bindings" repository = "https://github.com/sfackler/rust-openssl" -documentation = "https://sfackler.github.io/rust-openssl/doc/v0.8.1/openssl" +documentation = "https://sfackler.github.io/rust-openssl/doc/v0.8.2/openssl" readme = "../README.md" keywords = ["crypto", "tls", "ssl", "dtls"] build = "build.rs" @@ -39,7 +39,7 @@ dh_from_params = ["c_helpers"] bitflags = "0.7" lazy_static = "0.2" libc = "0.2" -openssl-sys = { version = "0.7.16", path = "../openssl-sys" } +openssl-sys = { version = "0.7.17", path = "../openssl-sys" } [build-dependencies] gcc = { version = "0.3", optional = true } diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index f20401f6..0c4bc51f 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.8.1")] +#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.8.2")] #[macro_use] extern crate bitflags;