summaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/bn/mod.rs68
-rw-r--r--openssl/src/c_helpers.c67
-rw-r--r--openssl/src/c_helpers.rs15
-rw-r--r--openssl/src/crypto/dsa.rs56
-rw-r--r--openssl/src/crypto/hash.rs22
-rw-r--r--openssl/src/crypto/hmac.rs130
-rw-r--r--openssl/src/crypto/mod.rs1
-rw-r--r--openssl/src/crypto/pkcs12.rs34
-rw-r--r--openssl/src/crypto/pkcs5.rs7
-rw-r--r--openssl/src/crypto/rsa.rs159
-rw-r--r--openssl/src/crypto/symm.rs30
-rw-r--r--openssl/src/dh/mod.rs59
-rw-r--r--openssl/src/error.rs5
-rw-r--r--openssl/src/lib.rs5
-rw-r--r--openssl/src/macros.rs14
-rw-r--r--openssl/src/ssl/bio.rs176
-rw-r--r--openssl/src/ssl/mod.rs350
-rw-r--r--openssl/src/ssl/tests/mod.rs124
-rw-r--r--openssl/src/version.rs31
-rw-r--r--openssl/src/x509/mod.rs132
-rw-r--r--openssl/src/x509/tests.rs2
21 files changed, 939 insertions, 548 deletions
diff --git a/openssl/src/bn/mod.rs b/openssl/src/bn/mod.rs
index de9d0d2a..7d1f5458 100644
--- a/openssl/src/bn/mod.rs
+++ b/openssl/src/bn/mod.rs
@@ -1,4 +1,4 @@
-use libc::{c_int, c_ulong, c_void};
+use libc::{c_int, c_void};
use std::ffi::{CStr, CString};
use std::cmp::Ordering;
use std::{fmt, ptr};
@@ -185,10 +185,11 @@ impl<'a> BigNumRef<'a> {
}
}
- /// Add an `unsigned long` to `self`. This is more efficient than adding a `BigNum`.
- pub fn add_word(&mut self, w: c_ulong) -> Result<(), ErrorStack> {
+ /// Add a `u32` to `self`. This is more efficient than adding a
+ /// `BigNum`.
+ pub fn add_word(&mut self, w: u32) -> Result<(), ErrorStack> {
unsafe {
- if ffi::BN_add_word(self.as_ptr(), w) == 1 {
+ if ffi::BN_add_word(self.as_ptr(), w as ffi::BN_ULONG) == 1 {
Ok(())
} else {
Err(ErrorStack::get())
@@ -196,9 +197,9 @@ impl<'a> BigNumRef<'a> {
}
}
- pub fn sub_word(&mut self, w: c_ulong) -> Result<(), ErrorStack> {
+ pub fn sub_word(&mut self, w: u32) -> Result<(), ErrorStack> {
unsafe {
- if ffi::BN_sub_word(self.as_ptr(), w) == 1 {
+ if ffi::BN_sub_word(self.as_ptr(), w as ffi::BN_ULONG) == 1 {
Ok(())
} else {
Err(ErrorStack::get())
@@ -206,9 +207,9 @@ impl<'a> BigNumRef<'a> {
}
}
- pub fn mul_word(&mut self, w: c_ulong) -> Result<(), ErrorStack> {
+ pub fn mul_word(&mut self, w: u32) -> Result<(), ErrorStack> {
unsafe {
- if ffi::BN_mul_word(self.as_ptr(), w) == 1 {
+ if ffi::BN_mul_word(self.as_ptr(), w as ffi::BN_ULONG) == 1 {
Ok(())
} else {
Err(ErrorStack::get())
@@ -216,22 +217,22 @@ impl<'a> BigNumRef<'a> {
}
}
- pub fn div_word(&mut self, w: c_ulong) -> Result<c_ulong, ErrorStack> {
+ pub fn div_word(&mut self, w: u32) -> Result<u64, ErrorStack> {
unsafe {
- let result = ffi::BN_div_word(self.as_ptr(), w);
- if result != !0 as c_ulong {
- Ok(result)
+ let result = ffi::BN_div_word(self.as_ptr(), w as ffi::BN_ULONG);
+ if result != !0 {
+ Ok(result.into())
} else {
Err(ErrorStack::get())
}
}
}
- pub fn mod_word(&self, w: c_ulong) -> Result<c_ulong, ErrorStack> {
+ pub fn mod_word(&self, w: u32) -> Result<u64, ErrorStack> {
unsafe {
- let result = ffi::BN_mod_word(self.as_ptr(), w);
- if result != !0 as c_ulong {
- Ok(result)
+ let result = ffi::BN_mod_word(self.as_ptr(), w as ffi::BN_ULONG);
+ if result != !0 {
+ Ok(result as u64)
} else {
Err(ErrorStack::get())
}
@@ -257,7 +258,10 @@ impl<'a> BigNumRef<'a> {
pub fn is_prime(&self, checks: i32) -> Result<bool, ErrorStack> {
unsafe {
with_ctx!(ctx, {
- Ok(ffi::BN_is_prime_ex(self.as_ptr(), checks as c_int, ctx, ptr::null()) == 1)
+ Ok(ffi::BN_is_prime_ex(self.as_ptr(),
+ checks as c_int,
+ ctx,
+ ptr::null_mut()) == 1)
})
}
}
@@ -278,7 +282,7 @@ impl<'a> BigNumRef<'a> {
checks as c_int,
ctx,
do_trial_division as c_int,
- ptr::null()) == 1)
+ ptr::null_mut()) == 1)
})
}
}
@@ -483,9 +487,19 @@ impl<'a> BigNumRef<'a> {
}
pub fn is_negative(&self) -> bool {
+ self._is_negative()
+ }
+
+ #[cfg(ossl10x)]
+ fn _is_negative(&self) -> bool {
unsafe { (*self.as_ptr()).neg == 1 }
}
+ #[cfg(ossl110)]
+ fn _is_negative(&self) -> bool {
+ unsafe { ffi::BN_is_negative(self.as_ptr()) == 1 }
+ }
+
/// Returns the number of significant bits in `self`.
pub fn num_bits(&self) -> i32 {
unsafe { ffi::BN_num_bits(self.as_ptr()) as i32 }
@@ -536,7 +550,7 @@ impl<'a> BigNumRef<'a> {
assert!(!buf.is_null());
let str = String::from_utf8(CStr::from_ptr(buf as *const _).to_bytes().to_vec())
.unwrap();
- ffi::CRYPTO_free(buf as *mut c_void);
+ CRYPTO_free!(buf as *mut c_void);
str
}
}
@@ -555,7 +569,7 @@ impl<'a> BigNumRef<'a> {
assert!(!buf.is_null());
let str = String::from_utf8(CStr::from_ptr(buf as *const _).to_bytes().to_vec())
.unwrap();
- ffi::CRYPTO_free(buf as *mut c_void);
+ CRYPTO_free!(buf as *mut c_void);
str
}
}
@@ -580,27 +594,27 @@ impl BigNum {
}
/// Creates a new `BigNum` with the given value.
- pub fn new_from(n: c_ulong) -> Result<BigNum, ErrorStack> {
+ pub fn new_from(n: u32) -> Result<BigNum, ErrorStack> {
BigNum::new().and_then(|v| unsafe {
- try_ssl!(ffi::BN_set_word(v.as_ptr(), n));
+ try_ssl!(ffi::BN_set_word(v.as_ptr(), n as ffi::BN_ULONG));
Ok(v)
})
}
/// Creates a `BigNum` from a decimal string.
pub fn from_dec_str(s: &str) -> Result<BigNum, ErrorStack> {
- BigNum::new().and_then(|v| unsafe {
+ BigNum::new().and_then(|mut v| unsafe {
let c_str = CString::new(s.as_bytes()).unwrap();
- try_ssl!(ffi::BN_dec2bn(&(v.0).0, c_str.as_ptr() as *const _));
+ try_ssl!(ffi::BN_dec2bn(&mut (v.0).0, c_str.as_ptr() as *const _));
Ok(v)
})
}
/// Creates a `BigNum` from a hexadecimal string.
pub fn from_hex_str(s: &str) -> Result<BigNum, ErrorStack> {
- BigNum::new().and_then(|v| unsafe {
+ BigNum::new().and_then(|mut v| unsafe {
let c_str = CString::new(s.as_bytes()).unwrap();
- try_ssl!(ffi::BN_hex2bn(&(v.0).0, c_str.as_ptr() as *const _));
+ try_ssl!(ffi::BN_hex2bn(&mut (v.0).0, c_str.as_ptr() as *const _));
Ok(v)
})
}
@@ -646,7 +660,7 @@ impl BigNum {
safe as c_int,
add_arg,
rem_arg,
- ptr::null()) == 1
+ ptr::null_mut()) == 1
})
}
}
diff --git a/openssl/src/c_helpers.c b/openssl/src/c_helpers.c
deleted file mode 100644
index 6e6a5021..00000000
--- a/openssl/src/c_helpers.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <openssl/hmac.h>
-#include <openssl/ssl.h>
-#include <openssl/dh.h>
-#include <openssl/bn.h>
-
-void rust_0_8_SSL_CTX_clone(SSL_CTX *ctx) {
- CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
-}
-
-void rust_0_8_X509_clone(X509 *x509) {
- CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
-}
-
-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(X509 *x) {
- return X509_get_notAfter(x);
-}
-
-ASN1_TIME* rust_0_8_X509_get_notBefore(X509 *x) {
- return X509_get_notBefore(x);
-}
-
-DH *rust_0_8_DH_new_from_params(BIGNUM *p, BIGNUM *g, BIGNUM *q) {
- DH *dh;
-
- if ((dh = DH_new()) == NULL) {
- return NULL;
- }
- dh->p = p;
- dh->g = g;
- dh->q = q;
- return dh;
-}
-
-#if OPENSSL_VERSION_NUMBER < 0x10000000L
-int rust_0_8_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) {
- HMAC_Init_ex(ctx, key, key_len, md, impl);
- return 1;
-}
-
-int rust_0_8_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len) {
- HMAC_Update(ctx, data, len);
- return 1;
-}
-
-int rust_0_8_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) {
- HMAC_Final(ctx, md, len);
- return 1;
-}
-
-#else
-
-int rust_0_8_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) {
- return HMAC_Init_ex(ctx, key, key_len, md, impl);
-}
-
-int rust_0_8_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len) {
- return HMAC_Update(ctx, data, len);
-}
-
-int rust_0_8_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) {
- return HMAC_Final(ctx, md, len);
-}
-#endif
diff --git a/openssl/src/c_helpers.rs b/openssl/src/c_helpers.rs
deleted file mode 100644
index d16c3125..00000000
--- a/openssl/src/c_helpers.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-use ffi;
-use libc::{c_int, c_void, c_uint, c_uchar};
-
-#[allow(dead_code)]
-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;
- pub fn rust_0_8_DH_new_from_params(p: *mut ffi::BIGNUM, g: *mut ffi::BIGNUM, q: *mut ffi::BIGNUM) -> *mut ffi::DH;
-}
diff --git a/openssl/src/crypto/dsa.rs b/openssl/src/crypto/dsa.rs
index 97ba7a97..bb4fe474 100644
--- a/openssl/src/crypto/dsa.rs
+++ b/openssl/src/crypto/dsa.rs
@@ -19,8 +19,13 @@ impl DSAParams {
unsafe {
// Wrap it so that if we panic we'll call the dtor
let dsa = DSAParams(try_ssl_null!(ffi::DSA_new()));
- try_ssl!(ffi::DSA_generate_parameters_ex(dsa.0, size as c_int, ptr::null(), 0,
- ptr::null_mut(), ptr::null_mut(), ptr::null()));
+ try_ssl!(ffi::DSA_generate_parameters_ex(dsa.0,
+ size as c_int,
+ ptr::null(),
+ 0,
+ ptr::null_mut(),
+ ptr::null_mut(),
+ ptr::null_mut()));
Ok(dsa)
}
}
@@ -190,43 +195,74 @@ impl DSA {
pub fn p<'a>(&'a self) -> Option<BigNumRef<'a>> {
unsafe {
- let p = (*self.0).p;
+ let p = compat::pqg(self.0)[0];
if p.is_null() {
None
} else {
- Some(BigNumRef::from_ptr((*self.0).p))
+ Some(BigNumRef::from_ptr(p as *mut _))
}
}
}
pub fn q<'a>(&'a self) -> Option<BigNumRef<'a>> {
unsafe {
- let q = (*self.0).q;
+ let q = compat::pqg(self.0)[1];
if q.is_null() {
None
} else {
- Some(BigNumRef::from_ptr((*self.0).q))
+ Some(BigNumRef::from_ptr(q as *mut _))
}
}
}
pub fn g<'a>(&'a self) -> Option<BigNumRef<'a>> {
unsafe {
- let g = (*self.0).g;
+ let g = compat::pqg(self.0)[2];
if g.is_null() {
None
} else {
- Some(BigNumRef::from_ptr((*self.0).g))
+ Some(BigNumRef::from_ptr(g as *mut _))
}
}
}
pub fn has_public_key(&self) -> bool {
- unsafe { !(*self.0).pub_key.is_null() }
+ unsafe { !compat::keys(self.0)[0].is_null() }
}
pub fn has_private_key(&self) -> bool {
- unsafe { !(*self.0).priv_key.is_null() }
+ unsafe { !compat::keys(self.0)[1].is_null() }
+ }
+}
+
+#[cfg(ossl110)]
+mod compat {
+ use std::ptr;
+ use ffi::{self, BIGNUM, DSA};
+
+ pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] {
+ let (mut p, mut q, mut g) = (ptr::null(), ptr::null(), ptr::null());
+ ffi::DSA_get0_pqg(d, &mut p, &mut q, &mut g);
+ [p, q, g]
+ }
+
+ pub unsafe fn keys(d: *const DSA) -> [*const BIGNUM; 2] {
+ let (mut pub_key, mut priv_key) = (ptr::null(), ptr::null());
+ ffi::DSA_get0_key(d, &mut pub_key, &mut priv_key);
+ [pub_key, priv_key]
+ }
+}
+
+#[cfg(ossl10x)]
+mod compat {
+ use ffi::{BIGNUM, DSA};
+
+ pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] {
+ [(*d).p, (*d).q, (*d).g]
+ }
+
+ pub unsafe fn keys(d: *const DSA) -> [*const BIGNUM; 2] {
+ [(*d).pub_key, (*d).priv_key]
}
}
diff --git a/openssl/src/crypto/hash.rs b/openssl/src/crypto/hash.rs
index 207a55f5..d87c43c5 100644
--- a/openssl/src/crypto/hash.rs
+++ b/openssl/src/crypto/hash.rs
@@ -1,8 +1,6 @@
-use libc::c_uint;
use std::io::prelude::*;
use std::io;
use std::ptr;
-use std::cmp;
use ffi;
use HashTypeInternals;
@@ -102,7 +100,7 @@ impl Hasher {
pub fn new(ty: Type) -> Result<Hasher, ErrorStack> {
ffi::init();
- let ctx = unsafe { try_ssl_null!(ffi::EVP_MD_CTX_create()) };
+ let ctx = unsafe { try_ssl_null!(ffi::EVP_MD_CTX_new()) };
let md = ty.evp_md();
let mut h = Hasher {
@@ -123,22 +121,20 @@ impl Hasher {
}
Finalized => (),
}
- unsafe { try_ssl!(ffi::EVP_DigestInit_ex(self.ctx, self.md, 0 as *const _)); }
+ unsafe { try_ssl!(ffi::EVP_DigestInit_ex(self.ctx, self.md, 0 as *mut _)); }
self.state = Reset;
Ok(())
}
/// Feeds data into the hasher.
- pub fn update(&mut self, mut data: &[u8]) -> Result<(), ErrorStack> {
+ pub fn update(&mut self, data: &[u8]) -> Result<(), ErrorStack> {
if self.state == Finalized {
try!(self.init());
}
- while !data.is_empty() {
- let len = cmp::min(data.len(), c_uint::max_value() as usize);
- unsafe {
- try_ssl!(ffi::EVP_DigestUpdate(self.ctx, data.as_ptr(), len as c_uint));
- }
- data = &data[len..];
+ unsafe {
+ try_ssl!(ffi::EVP_DigestUpdate(self.ctx,
+ data.as_ptr() as *mut _,
+ data.len()));
}
self.state = Updated;
Ok(())
@@ -176,7 +172,7 @@ impl Write for Hasher {
impl Clone for Hasher {
fn clone(&self) -> Hasher {
let ctx = unsafe {
- let ctx = ffi::EVP_MD_CTX_create();
+ let ctx = ffi::EVP_MD_CTX_new();
assert!(!ctx.is_null());
let r = ffi::EVP_MD_CTX_copy_ex(ctx, self.ctx);
assert_eq!(r, 1);
@@ -197,7 +193,7 @@ impl Drop for Hasher {
if self.state != Finalized {
drop(self.finish());
}
- ffi::EVP_MD_CTX_destroy(self.ctx);
+ ffi::EVP_MD_CTX_free(self.ctx);
}
}
}
diff --git a/openssl/src/crypto/hmac.rs b/openssl/src/crypto/hmac.rs
index 1847d6b1..8f44ed7f 100644
--- a/openssl/src/crypto/hmac.rs
+++ b/openssl/src/crypto/hmac.rs
@@ -13,16 +13,14 @@
// limitations under the License.
//
-use libc::{c_int, c_uint};
+use libc::{c_int};
use std::io;
use std::io::prelude::*;
-use std::cmp;
use ffi;
use HashTypeInternals;
use crypto::hash::Type;
use error::ErrorStack;
-use c_helpers;
#[derive(PartialEq, Copy, Clone)]
enum State {
@@ -66,7 +64,7 @@ use self::State::*;
/// assert_eq!(res, spec);
/// ```
pub struct HMAC {
- ctx: ffi::HMAC_CTX,
+ ctx: compat::HMAC_CTX,
state: State,
}
@@ -75,11 +73,7 @@ impl HMAC {
pub fn new(ty: Type, key: &[u8]) -> Result<HMAC, ErrorStack> {
ffi::init();
- let ctx = unsafe {
- let mut ctx = ::std::mem::uninitialized();
- ffi::HMAC_CTX_init(&mut ctx);
- ctx
- };
+ let ctx = compat::HMAC_CTX::new();
let md = ty.evp_md();
let mut h = HMAC {
@@ -92,11 +86,11 @@ impl HMAC {
fn init_once(&mut self, md: *const ffi::EVP_MD, key: &[u8]) -> Result<(), ErrorStack> {
unsafe {
- try_ssl!(c_helpers::rust_0_8_HMAC_Init_ex(&mut self.ctx,
- key.as_ptr() as *const _,
- key.len() as c_int,
- md,
- 0 as *mut _));
+ try_ssl!(ffi::HMAC_Init_ex(self.ctx.get(),
+ key.as_ptr() as *const _,
+ key.len() as c_int,
+ md,
+ 0 as *mut _));
}
self.state = Reset;
Ok(())
@@ -113,26 +107,24 @@ impl HMAC {
// If the key and/or md is not supplied it's reused from the last time
// avoiding redundant initializations
unsafe {
- try_ssl!(c_helpers::rust_0_8_HMAC_Init_ex(&mut self.ctx,
- 0 as *const _,
- 0,
- 0 as *const _,
- 0 as *mut _));
+ try_ssl!(ffi::HMAC_Init_ex(self.ctx.get(),
+ 0 as *const _,
+ 0,
+ 0 as *const _,
+ 0 as *mut _));
}
self.state = Reset;
Ok(())
}
- pub fn update(&mut self, mut data: &[u8]) -> Result<(), ErrorStack> {
+ pub fn update(&mut self, data: &[u8]) -> Result<(), ErrorStack> {
if self.state == Finalized {
try!(self.init());
}
- while !data.is_empty() {
- let len = cmp::min(data.len(), c_uint::max_value() as usize);
- unsafe {
- try_ssl!(c_helpers::rust_0_8_HMAC_Update(&mut self.ctx, data.as_ptr(), len as c_uint));
- }
- data = &data[len..];
+ unsafe {
+ try_ssl!(ffi::HMAC_Update(self.ctx.get(),
+ data.as_ptr(),
+ data.len()));
}
self.state = Updated;
Ok(())
@@ -147,7 +139,9 @@ impl HMAC {
unsafe {
let mut len = ffi::EVP_MAX_MD_SIZE;
let mut res = vec![0; len as usize];
- try_ssl!(c_helpers::rust_0_8_HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut len));
+ try_ssl!(ffi::HMAC_Final(self.ctx.get(),
+ res.as_mut_ptr(),
+ &mut len));
res.truncate(len as usize);
self.state = Finalized;
Ok(res)
@@ -167,14 +161,11 @@ impl Write for HMAC {
}
}
-#[cfg(feature = "hmac_clone")]
impl Clone for HMAC {
- /// Requires the `hmac_clone` feature.
fn clone(&self) -> HMAC {
- let mut ctx: ffi::HMAC_CTX;
+ let ctx = compat::HMAC_CTX::new();
unsafe {
- ctx = ::std::mem::uninitialized();
- let r = ffi::HMAC_CTX_copy(&mut ctx, &self.ctx);
+ let r = ffi::HMAC_CTX_copy(ctx.get(), self.ctx.get());
assert_eq!(r, 1);
}
HMAC {
@@ -186,11 +177,8 @@ impl Clone for HMAC {
impl Drop for HMAC {
fn drop(&mut self) {
- unsafe {
- if self.state != Finalized {
- drop(self.finish());
- }
- ffi::HMAC_CTX_cleanup(&mut self.ctx);
+ if self.state != Finalized {
+ drop(self.finish());
}
}
}
@@ -202,6 +190,73 @@ pub fn hmac(t: Type, key: &[u8], data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
h.finish()
}
+#[cfg(ossl110)]
+#[allow(bad_style)]
+mod compat {
+ use ffi;
+
+ pub struct HMAC_CTX {
+ ctx: *mut ffi::HMAC_CTX,
+ }
+
+ impl HMAC_CTX {
+ pub fn new() -> HMAC_CTX {
+ unsafe {
+ let ctx = ffi::HMAC_CTX_new();
+ assert!(!ctx.is_null());
+ HMAC_CTX { ctx: ctx }
+ }
+ }
+
+ pub fn get(&self) -> *mut ffi::HMAC_CTX {
+ self.ctx
+ }
+ }
+
+ impl Drop for HMAC_CTX {
+ fn drop(&mut self) {
+ unsafe {
+ ffi::HMAC_CTX_free(self.ctx);
+ }
+ }
+ }
+}
+
+#[cfg(ossl10x)]
+#[allow(bad_style)]
+mod compat {
+ use std::mem;
+ use std::cell::UnsafeCell;
+
+ use ffi;
+
+ pub struct HMAC_CTX {
+ ctx: UnsafeCell<ffi::HMAC_CTX>,
+ }
+
+ impl HMAC_CTX {
+ pub fn new() -> HMAC_CTX {
+ unsafe {
+ let mut ctx = mem::zeroed();
+ ffi::HMAC_CTX_init(&mut ctx);
+ HMAC_CTX { ctx: UnsafeCell::new(ctx) }
+ }
+ }
+
+ pub fn get(&self) -> *mut ffi::HMAC_CTX {
+ self.ctx.get()
+ }
+ }
+
+ impl Drop for HMAC_CTX {
+ fn drop(&mut self) {
+ unsafe {
+ ffi::HMAC_CTX_cleanup(self.get());
+ }
+ }
+ }
+}
+
#[cfg(test)]
mod tests {
use std::iter::repeat;
@@ -289,7 +344,6 @@ mod tests {
}
#[test]
- #[cfg(feature = "hmac_clone")]
fn test_clone() {
let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 2] =
[(repeat(0xaa_u8).take(80).collect(),
diff --git a/openssl/src/crypto/mod.rs b/openssl/src/crypto/mod.rs
index b8b109a2..389b7cc9 100644
--- a/openssl/src/crypto/mod.rs
+++ b/openssl/src/crypto/mod.rs
@@ -15,7 +15,6 @@
//
pub mod hash;
-#[cfg(feature = "hmac")]
pub mod hmac;
pub mod pkcs5;
pub mod pkcs12;
diff --git a/openssl/src/crypto/pkcs12.rs b/openssl/src/crypto/pkcs12.rs
index 89bcbd5c..5f03a3d5 100644
--- a/openssl/src/crypto/pkcs12.rs
+++ b/openssl/src/crypto/pkcs12.rs
@@ -44,13 +44,14 @@ impl Pkcs12 {
let pkey = PKey::from_ptr(pkey);
let cert = X509::from_ptr(cert);
+ let chain = chain as *mut _;
let mut chain_out = vec![];
- for i in 0..(*chain).stack.num {
- let x509 = *(*chain).stack.data.offset(i as isize) as *mut _;
- chain_out.push(X509::from_ptr(x509));
+ for i in 0..compat::OPENSSL_sk_num(chain) {
+ let x509 = compat::OPENSSL_sk_value(chain, i);
+ chain_out.push(X509::from_ptr(x509 as *mut _));
}
- ffi::sk_free(&mut (*chain).stack);
+ compat::OPENSSL_sk_free(chain as *mut _);
Ok(ParsedPkcs12 {
pkey: pkey,
@@ -69,6 +70,31 @@ pub struct ParsedPkcs12 {
_p: (),
}
+#[cfg(ossl110)]
+mod compat {
+ pub use ffi::OPENSSL_sk_free;
+ pub use ffi::OPENSSL_sk_num;
+ pub use ffi::OPENSSL_sk_value;
+}
+
+#[cfg(ossl10x)]
+#[allow(bad_style)]
+mod compat {
+ use libc::{c_int, c_void};
+ use ffi;
+
+ pub use ffi::sk_free as OPENSSL_sk_free;
+
+ pub unsafe fn OPENSSL_sk_num(stack: *mut ffi::_STACK) -> c_int {
+ (*stack).num
+ }
+
+ pub unsafe fn OPENSSL_sk_value(stack: *const ffi::_STACK, idx: c_int)
+ -> *mut c_void {
+ *(*stack).data.offset(idx as isize) as *mut c_void
+ }
+}
+
#[cfg(test)]
mod test {
use crypto::hash::Type::SHA1;
diff --git a/openssl/src/crypto/pkcs5.rs b/openssl/src/crypto/pkcs5.rs
index ef84fbe1..adcbc9db 100644
--- a/openssl/src/crypto/pkcs5.rs
+++ b/openssl/src/crypto/pkcs5.rs
@@ -82,7 +82,7 @@ pub fn pbkdf2_hmac_sha1(pass: &[u8],
ffi::init();
- try_ssl!(ffi::PKCS5_PBKDF2_HMAC_SHA1(pass.as_ptr(),
+ try_ssl!(ffi::PKCS5_PBKDF2_HMAC_SHA1(pass.as_ptr() as *const _,
pass.len() as c_int,
salt.as_ptr(),
salt.len() as c_int,
@@ -94,7 +94,6 @@ pub fn pbkdf2_hmac_sha1(pass: &[u8],
}
/// Derives a key from a password and salt using the PBKDF2-HMAC algorithm with a digest function.
-#[cfg(feature = "pkcs5_pbkdf2_hmac")]
pub fn pbkdf2_hmac(pass: &[u8],
salt: &[u8],
iter: usize,
@@ -104,7 +103,7 @@ pub fn pbkdf2_hmac(pass: &[u8],
unsafe {
let mut out = vec![0; keylen];
ffi::init();
- try_ssl!(ffi::PKCS5_PBKDF2_HMAC(pass.as_ptr(),
+ try_ssl!(ffi::PKCS5_PBKDF2_HMAC(pass.as_ptr() as *const _,
pass.len() as c_int,
salt.as_ptr(),
salt.len() as c_int,
@@ -162,7 +161,6 @@ mod tests {
// Test vectors from
// https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c
#[test]
- #[cfg(feature = "pkcs5_pbkdf2_hmac")]
fn test_pbkdf2_hmac_sha256() {
assert_eq!(super::pbkdf2_hmac(b"passwd", b"salt", 1, hash::Type::SHA256, 16).unwrap(),
vec![0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8,
@@ -176,7 +174,6 @@ mod tests {
// Test vectors from
// https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c
#[test]
- #[cfg(feature = "pkcs5_pbkdf2_hmac")]
fn test_pbkdf2_hmac_sha512() {
assert_eq!(super::pbkdf2_hmac(b"password", b"NaCL", 1, hash::Type::SHA512, 64).unwrap(),
vec![0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8,
diff --git a/openssl/src/crypto/rsa.rs b/openssl/src/crypto/rsa.rs
index 8a3f9188..f91f39fb 100644
--- a/openssl/src/crypto/rsa.rs
+++ b/openssl/src/crypto/rsa.rs
@@ -2,7 +2,7 @@ use ffi;
use std::fmt;
use std::ptr;
use std::mem;
-use libc::{c_int, c_void, c_char, c_ulong};
+use libc::{c_int, c_void, c_char};
use bn::{BigNum, BigNumRef};
use bio::{MemBio, MemBioSlice};
@@ -44,12 +44,13 @@ impl RSA {
/// the supplied load and save methods for DER formatted keys.
pub fn from_public_components(n: BigNum, e: BigNum) -> Result<RSA, ErrorStack> {
unsafe {
- let rsa = try_ssl_null!(ffi::RSA_new());
- (*rsa).n = n.as_ptr();
- (*rsa).e = e.as_ptr();
- mem::forget(n);
- mem::forget(e);
- Ok(RSA(rsa))
+ let rsa = RSA(try_ssl_null!(ffi::RSA_new()));
+ try_ssl!(compat::set_key(rsa.0,
+ n.as_ptr(),
+ e.as_ptr(),
+ ptr::null_mut()));
+ mem::forget((n, e));
+ Ok(rsa)
}
}
@@ -63,24 +64,15 @@ impl RSA {
qi: BigNum)
-> Result<RSA, ErrorStack> {
unsafe {
- let rsa = try_ssl_null!(ffi::RSA_new());
- (*rsa).n = n.as_ptr();
- (*rsa).e = e.as_ptr();
- (*rsa).d = d.as_ptr();
- (*rsa).p = p.as_ptr();
- (*rsa).q = q.as_ptr();
- (*rsa).dmp1 = dp.as_ptr();
- (*rsa).dmq1 = dq.as_ptr();
- (*rsa).iqmp = qi.as_ptr();
- mem::forget(n);
- mem::forget(e);
- mem::forget(d);
- mem::forget(p);
- mem::forget(q);
- mem::forget(dp);
- mem::forget(dq);
- mem::forget(qi);
- Ok(RSA(rsa))
+ let rsa = RSA(try_ssl_null!(ffi::RSA_new()));
+ try_ssl!(compat::set_key(rsa.0, n.as_ptr(), e.as_ptr(), d.as_ptr()));
+ mem::forget((n, e, d));
+ try_ssl!(compat::set_factors(rsa.0, p.as_ptr(), q.as_ptr()));
+ mem::forget((p, q));
+ try_ssl!(compat::set_crt_params(rsa.0, dp.as_ptr(), dq.as_ptr(),
+ qi.as_ptr()));
+ mem::forget((dp, dq, qi));
+ Ok(rsa)
}
}
@@ -95,7 +87,7 @@ impl RSA {
unsafe {
let rsa = try_ssl_null!(ffi::RSA_new());
let rsa = RSA(rsa);
- let e = try!(BigNum::new_from(ffi::RSA_F4 as c_ulong));
+ let e = try!(BigNum::new_from(ffi::RSA_F4 as u32));
try_ssl!(ffi::RSA_generate_key_ex(rsa.0, bits as c_int, e.as_ptr(), ptr::null_mut()));
@@ -292,55 +284,55 @@ impl RSA {
pub fn n<'a>(&'a self) -> Option<BigNumRef<'a>> {
unsafe {
- let n = (*self.0).n;
+ let n = compat::key(self.0)[0];
if n.is_null() {
None
} else {
- Some(BigNumRef::from_ptr(n))
+ Some(BigNumRef::from_ptr(n as *mut _))
}
}
}
pub fn d<'a>(&self) -> Option<BigNumRef<'a>> {
unsafe {
- let d = (*self.0).d;
+ let d = compat::key(self.0)[2];
if d.is_null() {
None
} else {
- Some(BigNumRef::from_ptr(d))
+ Some(BigNumRef::from_ptr(d as *mut _))
}
}
}
pub fn e<'a>(&'a self) -> Option<BigNumRef<'a>> {
unsafe {
- let e = (*self.0).e;
+ let e = compat::key(self.0)[1];
if e.is_null() {
None
} else {
- Some(BigNumRef::from_ptr(e))
+ Some(BigNumRef::from_ptr(e as *mut _))
}
}
}
pub fn p<'a>(&'a self) -> Option<BigNumRef<'a>> {
unsafe {
- let p = (*self.0).p;
+ let p = compat::factors(self.0)[0];
if p.is_null() {
None
} else {
- Some(BigNumRef::from_ptr(p))
+ Some(BigNumRef::from_ptr(p as *mut _))
}
}
}
pub fn q<'a>(&'a self) -> Option<BigNumRef<'a>> {
unsafe {
- let q = (*self.0).q;
+ let q = compat::factors(self.0)[1];
if q.is_null() {
None
} else {
- Some(BigNumRef::from_ptr(q))
+ Some(BigNumRef::from_ptr(q as *mut _))
}
}
}
@@ -352,6 +344,89 @@ impl fmt::Debug for RSA {
}
}
+#[cfg(ossl110)]
+mod compat {
+ use std::ptr;
+
+ use ffi::{self, BIGNUM, RSA};
+ use libc::c_int;
+
+ pub unsafe fn key(r: *const RSA) -> [*const BIGNUM; 3] {
+ let (mut n, mut e, mut d) = (ptr::null(), ptr::null(), ptr::null());
+ ffi::RSA_get0_key(r, &mut n, &mut e, &mut d);
+ [n, e, d]
+ }
+
+ pub unsafe fn factors(r: *const RSA) -> [*const BIGNUM; 2] {
+ let (mut p, mut q) = (ptr::null(), ptr::null());
+ ffi::RSA_get0_factors(r, &mut p, &mut q);
+ [p, q]
+ }
+
+ pub unsafe fn set_key(r: *mut RSA,
+ n: *mut BIGNUM,
+ e: *mut BIGNUM,
+ d: *mut BIGNUM) -> c_int {
+ ffi::RSA_set0_key(r, n, e, d)
+ }
+
+ pub unsafe fn set_factors(r: *mut RSA,
+ p: *mut BIGNUM,
+ q: *mut BIGNUM) -> c_int {
+ ffi::RSA_set0_factors(r, p, q)
+ }
+
+ pub unsafe fn set_crt_params(r: *mut RSA,
+ dmp1: *mut BIGNUM,
+ dmq1: *mut BIGNUM,
+ iqmp: *mut BIGNUM) -> c_int {
+ ffi::RSA_set0_crt_params(r, dmp1, dmq1, iqmp)
+ }
+}
+
+#[cfg(ossl10x)]
+mod compat {
+ use libc::c_int;
+ use ffi::{BIGNUM, RSA};
+
+ pub unsafe fn key(r: *const RSA) -> [*const BIGNUM; 3] {
+ [(*r).n, (*r).e, (*r).d]
+ }
+
+ pub unsafe fn factors(r: *const RSA) -> [*const BIGNUM; 2] {
+ [(*r).p, (*r).q]
+ }
+
+ pub unsafe fn set_key(r: *mut RSA,
+ n: *mut BIGNUM,
+ e: *mut BIGNUM,
+ d: *mut BIGNUM) -> c_int {
+ (*r).n = n;
+ (*r).e = e;
+ (*r).d = d;
+ 1 // TODO: is this right? should it be 0? what's success?
+ }
+
+ pub unsafe fn set_factors(r: *mut RSA,
+ p: *mut BIGNUM,
+ q: *mut BIGNUM) -> c_int {
+ (*r).p = p;
+ (*r).q = q;
+ 1 // TODO: is this right? should it be 0? what's success?
+ }
+
+ pub unsafe fn set_crt_params(r: *mut RSA,
+ dmp1: *mut BIGNUM,
+ dmq1: *mut BIGNUM,
+ iqmp: *mut BIGNUM) -> c_int {
+ (*r).dmp1 = dmp1;
+ (*r).dmq1 = dmq1;
+ (*r).iqmp = iqmp;
+ 1 // TODO: is this right? should it be 0? what's success?
+ }
+}
+
+
#[cfg(test)]
mod test {
use std::io::Write;
@@ -449,9 +524,9 @@ mod test {
#[test]
fn test_private_encrypt() {
- let mut k0 = super::RSA::generate(512).unwrap();
+ let k0 = super::RSA::generate(512).unwrap();
let k0pkey = k0.public_key_to_pem().unwrap();
- let mut k1 = super::RSA::public_key_from_pem(&k0pkey).unwrap();
+ let k1 = super::RSA::public_key_from_pem(&k0pkey).unwrap();
let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
@@ -462,9 +537,9 @@ mod test {
#[test]
fn test_public_encrypt() {
- let mut k0 = super::RSA::generate(512).unwrap();
+ let k0 = super::RSA::generate(512).unwrap();
let k0pkey = k0.public_key_to_pem().unwrap();
- let mut k1 = super::RSA::public_key_from_pem(&k0pkey).unwrap();
+ let k1 = super::RSA::public_key_from_pem(&k0pkey).unwrap();
let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
@@ -475,9 +550,9 @@ mod test {
#[test]
fn test_public_encrypt_pkcs() {
- let mut k0 = super::RSA::generate(512).unwrap();
+ let k0 = super::RSA::generate(512).unwrap();
let k0pkey = k0.public_key_to_pem().unwrap();
- let mut k1 = super::RSA::public_key_from_pem(&k0pkey).unwrap();
+ let k1 = super::RSA::public_key_from_pem(&k0pkey).unwrap();
let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
diff --git a/openssl/src/crypto/symm.rs b/openssl/src/crypto/symm.rs
index 93764e4d..c4021338 100644
--- a/openssl/src/crypto/symm.rs
+++ b/openssl/src/crypto/symm.rs
@@ -81,7 +81,7 @@ impl Type {
/// Returns the length of keys used with this cipher.
pub fn key_len(&self) -> usize {
unsafe {
- ffi::EVP_CIPHER_key_length(self.as_ptr()) as usize
+ EVP_CIPHER_key_length(self.as_ptr()) as usize
}
}
@@ -89,7 +89,7 @@ impl Type {
/// cipher does not use an IV.
pub fn iv_len(&self) -> Option<usize> {
unsafe {
- let len = ffi::EVP_CIPHER_iv_length(self.as_ptr()) as usize;
+ let len = EVP_CIPHER_iv_length(self.as_ptr()) as usize;
if len == 0 {
None
} else {
@@ -105,7 +105,7 @@ impl Type {
/// Stream ciphers such as RC4 have a block size of 1.
pub fn block_size(&self) -> usize {
unsafe {
- ffi::EVP_CIPHER_block_size(self.as_ptr()) as usize
+ EVP_CIPHER_block_size(self.as_ptr()) as usize
}
}
}
@@ -272,6 +272,30 @@ fn cipher(t: Type,
Ok(out)
}
+#[cfg(ossl110)]
+use ffi::{EVP_CIPHER_iv_length, EVP_CIPHER_block_size, EVP_CIPHER_key_length};
+
+#[cfg(ossl10x)]
+#[allow(bad_style)]
+mod compat {
+ use libc::c_int;
+ use ffi::EVP_CIPHER;
+
+ pub unsafe fn EVP_CIPHER_iv_length(ptr: *const EVP_CIPHER) -> c_int {
+ (*ptr).iv_len
+ }
+
+ pub unsafe fn EVP_CIPHER_block_size(ptr: *const EVP_CIPHER) -> c_int {
+ (*ptr).block_size
+ }
+
+ pub unsafe fn EVP_CIPHER_key_length(ptr: *const EVP_CIPHER) -> c_int {
+ (*ptr).key_len
+ }
+}
+#[cfg(ossl10x)]
+use self::compat::*;
+
#[cfg(test)]
mod tests {
use serialize::hex::{FromHex, ToHex};
diff --git a/openssl/src/dh/mod.rs b/openssl/src/dh/mod.rs
index e0cf885a..4ee2d890 100644
--- a/openssl/src/dh/mod.rs
+++ b/openssl/src/dh/mod.rs
@@ -3,24 +3,22 @@ use error::ErrorStack;
use bio::MemBioSlice;
use std::ptr;
-#[cfg(feature = "dh_from_params")]
use bn::BigNum;
-#[cfg(feature = "dh_from_params")]
use std::mem;
pub struct DH(*mut ffi::DH);
impl DH {
- /// Requires the `dh_from_params` feature.
- #[cfg(feature = "dh_from_params")]
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<DH, ErrorStack> {
- let dh = unsafe {
- try_ssl_null!(::c_helpers::rust_0_8_DH_new_from_params(p.as_ptr(), g.as_ptr(), q.as_ptr()))
- };
- mem::forget(p);
- mem::forget(g);
- mem::forget(q);
- Ok(DH(dh))
+ unsafe {
+ let dh = DH(try_ssl_null!(ffi::DH_new()));
+ try_ssl!(compat::DH_set0_pqg(dh.0,
+ p.as_ptr(),
+ q.as_ptr(),
+ g.as_ptr()));
+ mem::forget((p, g, q));
+ Ok(dh)
+ }
}
pub fn from_pem(buf: &[u8]) -> Result<DH, ErrorStack> {
@@ -32,19 +30,19 @@ impl DH {
Ok(DH(dh))
}
- #[cfg(feature = "rfc5114")]
+ #[cfg(all(feature = "rfc5114", not(ossl101)))]
pub fn get_1024_160() -> Result<DH, ErrorStack> {
let dh = try_ssl_null!(unsafe { ffi::DH_get_1024_160() });
Ok(DH(dh))
}
- #[cfg(feature = "rfc5114")]
+ #[cfg(all(feature = "rfc5114", not(ossl101)))]
pub fn get_2048_224() -> Result<DH, ErrorStack> {
let dh = try_ssl_null!(unsafe { ffi::DH_get_2048_224() });
Ok(DH(dh))
}
- #[cfg(feature = "rfc5114")]
+ #[cfg(all(feature = "rfc5114", not(ossl101)))]
pub fn get_2048_256() -> Result<DH, ErrorStack> {
let dh = try_ssl_null!(unsafe { ffi::DH_get_2048_256() });
Ok(DH(dh))
@@ -64,17 +62,39 @@ impl Drop for DH {
}
}
+#[cfg(ossl110)]
+mod compat {
+ pub use ffi::DH_set0_pqg;
+}
+
+#[cfg(ossl10x)]
+#[allow(bad_style)]
+mod compat {
+ use ffi;
+ use libc::c_int;
+
+ pub unsafe fn DH_set0_pqg(dh: *mut ffi::DH,
+ p: *mut ffi::BIGNUM,
+ q: *mut ffi::BIGNUM,
+ g: *mut ffi::BIGNUM) -> c_int {
+ (*dh).p = p;
+ (*dh).q = q;
+ (*dh).g = g;
+ 1
+ }
+}
+
#[cfg(test)]
mod tests {
use super::DH;
use bn::BigNum;
use ssl::SslContext;
- use ssl::SslMethod::Sslv23;
+ use ssl::SslMethod::Tls;
#[test]
- #[cfg(feature = "rfc5114")]
+ #[cfg(all(feature = "rfc5114", not(ossl101)))]
fn test_dh_rfc5114() {
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
let dh1 = DH::get_1024_160().unwrap();
ctx.set_tmp_dh(&dh1).unwrap();
let dh2 = DH::get_2048_224().unwrap();
@@ -84,9 +104,8 @@ mod tests {
}
#[test]
- #[cfg(feature = "dh_from_params")]
fn test_dh() {
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
let p = BigNum::from_hex_str("87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435\
E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF429\
6D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C02\
@@ -116,7 +135,7 @@ mod tests {
#[test]
fn test_dh_from_pem() {
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
let params = include_bytes!("../../test/dhparams.pem");
let dh = DH::from_pem(params).ok().expect("Failed to load PEM");
ctx.set_tmp_dh(&dh).unwrap();
diff --git a/openssl/src/error.rs b/openssl/src/error.rs
index d76e7cbd..f54d7bda 100644
--- a/openssl/src/error.rs
+++ b/openssl/src/error.rs
@@ -71,7 +71,7 @@ impl Error {
match unsafe { ffi::ERR_get_error() } {
0 => None,
- err => Some((Error(err))),
+ err => Some(Error(err)),
}
}
@@ -121,6 +121,7 @@ impl error::Error for Error {
fn get_lib(err: c_ulong) -> &'static str {
unsafe {
let cstr = ffi::ERR_lib_error_string(err);
+ assert!(!cstr.is_null(), "bad lib: {}", err);
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
str::from_utf8(bytes).unwrap()
}
@@ -129,6 +130,7 @@ fn get_lib(err: c_ulong) -> &'static str {
fn get_func(err: c_ulong) -> &'static str {
unsafe {
let cstr = ffi::ERR_func_error_string(err);
+ assert!(!cstr.is_null(), "bad func: {}", err);
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
str::from_utf8(bytes).unwrap()
}
@@ -137,6 +139,7 @@ fn get_func(err: c_ulong) -> &'static str {
fn get_reason(err: c_ulong) -> &'static str {
unsafe {
let cstr = ffi::ERR_reason_error_string(err);
+ assert!(!cstr.is_null(), "bad reason: {}", err);
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
str::from_utf8(bytes).unwrap()
}
diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs
index 879681f4..66c767dc 100644
--- a/openssl/src/lib.rs
+++ b/openssl/src/lib.rs
@@ -13,6 +13,9 @@ extern crate rustc_serialize as serialize;
#[cfg(test)]
extern crate net2;
+#[cfg(test)]
+extern crate tempdir;
+
#[doc(inline)]
pub use ffi::init;
@@ -23,8 +26,6 @@ mod macros;
pub mod asn1;
mod bio;
pub mod bn;
-#[cfg(feature = "c_helpers")]
-mod c_helpers;
pub mod crypto;
pub mod dh;
pub mod error;
diff --git a/openssl/src/macros.rs b/openssl/src/macros.rs
index e2d9cae5..31c298fa 100644
--- a/openssl/src/macros.rs
+++ b/openssl/src/macros.rs
@@ -80,3 +80,17 @@ macro_rules! lift_ssl_returns_size {
}
})
}
+
+#[cfg(ossl10x)]
+macro_rules! CRYPTO_free {
+ ($e:expr) => (::ffi::CRYPTO_free($e))
+}
+
+#[cfg(ossl110)]
+macro_rules! CRYPTO_free {
+ ($e:expr) => (
+ ::ffi::CRYPTO_free($e,
+ concat!(file!(), "\0").as_ptr() as *const _,
+ line!() as i32)
+ )
+}
diff --git a/openssl/src/ssl/bio.rs b/openssl/src/ssl/bio.rs
index c5663eb1..ccf3a472 100644
--- a/openssl/src/ssl/bio.rs
+++ b/openssl/src/ssl/bio.rs
@@ -1,5 +1,5 @@
use libc::{c_char, c_int, c_long, c_void, strlen};
-use ffi::{self, BIO, BIO_CTRL_FLUSH, BIO_TYPE_NONE, BIO_new, BIO_clear_retry_flags,
+use ffi::{BIO, BIO_CTRL_FLUSH, BIO_new, BIO_clear_retry_flags,
BIO_set_retry_read, BIO_set_retry_write};
use std::any::Any;
use std::io;
@@ -18,22 +18,11 @@ pub struct StreamState<S> {
}
/// Safe wrapper for BIO_METHOD
-pub struct BioMethod(ffi::BIO_METHOD);
+pub struct BioMethod(compat::BIO_METHOD);
impl BioMethod {
pub fn new<S: Read + Write>() -> BioMethod {
- BioMethod(ffi::BIO_METHOD {
- type_: BIO_TYPE_NONE,
- name: b"rust\0".as_ptr() as *const _,
- bwrite: Some(bwrite::<S>),
- bread: Some(bread::<S>),
- bputs: Some(bputs::<S>),
- bgets: None,
- ctrl: Some(ctrl::<S>),
- create: Some(create),
- destroy: Some(destroy::<S>),
- callback_ctrl: None,
- })
+ BioMethod(compat::BIO_METHOD::new::<S>())
}
}
@@ -49,9 +38,9 @@ pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Arc<BioMethod>), Err
});
unsafe {
- let bio = try_ssl_null!(BIO_new(&method.0));
- (*bio).ptr = Box::into_raw(state) as *mut _;
- (*bio).init = 1;
+ let bio = try_ssl_null!(BIO_new(method.0.get()));
+ compat::BIO_set_data(bio, Box::into_raw(state) as *mut _);
+ compat::BIO_set_init(bio, 1);
return Ok((bio, method));
}
@@ -62,14 +51,13 @@ pub unsafe fn take_error<S>(bio: *mut BIO) -> Option<io::Error> {
state.error.take()
}
-#[cfg_attr(not(feature = "nightly"), allow(dead_code))]
pub unsafe fn take_panic<S>(bio: *mut BIO) -> Option<Box<Any + Send>> {
let state = state::<S>(bio);
state.panic.take()
}
pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S {
- let state: &'a StreamState<S> = mem::transmute((*bio).ptr);
+ let state: &'a StreamState<S> = mem::transmute(compat::BIO_get_data(bio));
&state.stream
}
@@ -78,24 +66,16 @@ pub unsafe fn get_mut<'a, S: 'a>(bio: *mut BIO) -> &'a mut S {
}
unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState<S> {
- mem::transmute((*bio).ptr)
+ mem::transmute(compat::BIO_get_data(bio))
}
-#[cfg(feature = "nightly")]
fn catch_unwind<F, T>(f: F) -> Result<T, Box<Any + Send>>
where F: FnOnce() -> T
{
::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(f))
}
-#[cfg(not(feature = "nightly"))]
-fn catch_unwind<F, T>(f: F) -> Result<T, Box<Any + Send>>
- where F: FnOnce() -> T
-{
- Ok(f())
-}
-
-unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int {
+unsafe extern fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int {
BIO_clear_retry_flags(bio);
let state = state::<S>(bio);
@@ -117,7 +97,7 @@ unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_
}
}
-unsafe extern "C" fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int) -> c_int {
+unsafe extern fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int) -> c_int {
BIO_clear_retry_flags(bio);
let state = state::<S>(bio);
@@ -147,15 +127,15 @@ fn retriable_error(err: &io::Error) -> bool {
}
}
-unsafe extern "C" fn bputs<S: Write>(bio: *mut BIO, s: *const c_char) -> c_int {
+unsafe extern fn bputs<S: Write>(bio: *mut BIO, s: *const c_char) -> c_int {
bwrite::<S>(bio, s, strlen(s) as c_int)
}
-unsafe extern "C" fn ctrl<S: Write>(bio: *mut BIO,
- cmd: c_int,
- _num: c_long,
- _ptr: *mut c_void)
- -> c_long {
+unsafe extern fn ctrl<S: Write>(bio: *mut BIO,
+ cmd: c_int,
+ _num: c_long,
+ _ptr: *mut c_void)
+ -> c_long {
if cmd == BIO_CTRL_FLUSH {
let state = state::<S>(bio);
@@ -175,22 +155,126 @@ unsafe extern "C" fn ctrl<S: Write>(bio: *mut BIO,
}
}
-unsafe extern "C" fn create(bio: *mut BIO) -> c_int {
- (*bio).init = 0;
- (*bio).num = 0;
- (*bio).ptr = ptr::null_mut();
- (*bio).flags = 0;
+unsafe extern fn create(bio: *mut BIO) -> c_int {
+ compat::BIO_set_init(bio, 0);
+ compat::BIO_set_num(bio, 0);
+ compat::BIO_set_data(bio, ptr::null_mut());
+ compat::BIO_set_flags(bio, 0);
1
}
-unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int {
+unsafe extern fn destroy<S>(bio: *mut BIO) -> c_int {
if bio.is_null() {
return 0;
}
- assert!(!(*bio).ptr.is_null());
- Box::<StreamState<S>>::from_raw((*bio).ptr as *mut _);
- (*bio).ptr = ptr::null_mut();
- (*bio).init = 0;
+ let data = compat::BIO_get_data(bio);
+ assert!(!data.is_null());
+ Box::<StreamState<S>>::from_raw(data as *mut _);
+ compat::BIO_set_data(bio, ptr::null_mut());
+ compat::BIO_set_init(bio, 0);
1
}
+
+#[cfg(ossl110)]
+#[allow(bad_style)]
+mod compat {
+ use std::io::{Read, Write};
+
+ use libc::c_int;
+ use ffi;
+ pub use ffi::{BIO_set_init, BIO_set_flags, BIO_set_data, BIO_get_data};
+
+ pub unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
+
+ pub struct BIO_METHOD {
+ inner: *mut ffi::BIO_METHOD,
+ }
+
+ impl BIO_METHOD {
+ pub fn new<S: Read + Write>() -> BIO_METHOD {
+ unsafe {
+ let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE,
+ b"rust\0".as_ptr() as *const _);
+ assert!(!ptr.is_null());
+ let ret = BIO_METHOD { inner: ptr };
+ assert!(ffi::BIO_meth_set_write(ptr, super::bwrite::<S>) != 0);
+ assert!(ffi::BIO_meth_set_read(ptr, super::bread::<S>) != 0);
+ assert!(ffi::BIO_meth_set_puts(ptr, super::bputs::<S>) != 0);
+ assert!(ffi::BIO_meth_set_ctrl(ptr, super::ctrl::<S>) != 0);
+ assert!(ffi::BIO_meth_set_create(ptr, super::create) != 0);
+ assert!(ffi::BIO_meth_set_destroy(ptr, super::destroy::<S>) != 0);
+ return ret
+ }
+ }
+
+ pub fn get(&self) -> *mut ffi::BIO_METHOD {
+ self.inner
+ }
+ }
+
+ impl Drop for BIO_METHOD {
+ fn drop(&mut self) {
+ unsafe {
+ ffi::BIO_meth_free(self.inner);
+ }
+ }
+ }
+}
+
+#[cfg(ossl10x)]
+#[allow(bad_style)]
+mod compat {
+ use std::io::{Read, Write};
+ use std::cell::UnsafeCell;
+
+ use ffi;
+ use libc::{c_int, c_void};
+
+ pub struct BIO_METHOD {
+ inner: UnsafeCell<ffi::BIO_METHOD>,
+ }
+
+ impl BIO_METHOD {
+ pub fn new<S: Read + Write>() -> BIO_METHOD {
+ BIO_METHOD {
+ inner: UnsafeCell::new(ffi::BIO_METHOD {
+ type_: ffi::BIO_TYPE_NONE,
+ name: b"rust\0".as_ptr() as *const _,
+ bwrite: Some(super::bwrite::<S>),
+ bread: Some(super::bread::<S>),
+ bputs: Some(super::bputs::<S>),
+ bgets: None,
+ ctrl: Some(super::ctrl::<S>),
+ create: Some(super::create),
+ destroy: Some(super::destroy::<S>),
+ callback_ctrl: None,
+ }),
+ }
+ }
+
+ pub fn get(&self) -> *mut ffi::BIO_METHOD {
+ self.inner.get()
+ }
+ }
+
+ pub unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) {
+ (*bio).init = init;
+ }
+
+ pub unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) {
+ (*bio).flags = flags;
+ }
+
+ pub unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void {
+ (*bio).ptr
+ }
+
+ pub unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) {
+ (*bio).ptr = data;
+ }
+
+ pub unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) {
+ (*bio).num = num;
+ }
+}
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index 6e365af6..51bfc790 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -1,4 +1,4 @@
-use libc::{c_int, c_void, c_long};
+use libc::{c_int, c_void, c_long, c_ulong};
use std::any::Any;
use std::any::TypeId;
use std::cmp;
@@ -38,12 +38,11 @@ use self::bio::BioMethod;
pub use ssl::error::Error;
bitflags! {
- pub flags SslContextOptions: c_long {
+ pub flags SslContextOptions: c_ulong {
const SSL_OP_MICROSOFT_SESS_ID_BUG = ffi::SSL_OP_MICROSOFT_SESS_ID_BUG,
const SSL_OP_NETSCAPE_CHALLENGE_BUG = ffi::SSL_OP_NETSCAPE_CHALLENGE_BUG,
const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG =
ffi::SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG,
- const SSL_OP_TLSEXT_PADDING = ffi::SSL_OP_TLSEXT_PADDING,
const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = ffi::SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER,
const SSL_OP_SSLEAY_080_CLIENT_DH_BUG = ffi::SSL_OP_SSLEAY_080_CLIENT_DH_BUG,
const SSL_OP_TLS_D5_BUG = ffi::SSL_OP_TLS_D5_BUG,
@@ -73,74 +72,11 @@ bitflags! {
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum SslMethod {
- #[cfg(feature = "sslv2")]
- /// Only support the SSLv2 protocol, requires the `sslv2` feature.
- Sslv2,
- /// Support the SSLv2, SSLv3, TLSv1, TLSv1.1, and TLSv1.2 protocols depending on what the
- /// linked OpenSSL library supports.
- Sslv23,
- #[cfg(feature = "sslv3")]
- /// Only support the SSLv3 protocol.
- Sslv3,
- /// Only support the TLSv1 protocol.
- Tlsv1,
- #[cfg(feature = "tlsv1_1")]
- /// Support TLSv1.1 protocol, requires the `tlsv1_1` feature.
- Tlsv1_1,
- #[cfg(feature = "tlsv1_2")]
- /// Support TLSv1.2 protocol, requires the `tlsv1_2` feature.
- Tlsv1_2,
- #[cfg(feature = "dtlsv1")]
- /// Support DTLSv1 protocol, requires the `dtlsv1` feature.
- Dtlsv1,
- #[cfg(feature = "dtlsv1_2")]
- /// Support DTLSv1.2 protocol, requires the `dtlsv1_2` feature.
- Dtlsv1_2,
-}
-
-impl SslMethod {
- fn to_raw(&self) -> *const ffi::SSL_METHOD {
- unsafe {
- match *self {
- #[cfg(feature = "sslv2")]
- SslMethod::Sslv2 => ffi::SSLv2_method(),
- #[cfg(feature = "sslv3")]
- SslMethod::Sslv3 => ffi::SSLv3_method(),
- SslMethod::Tlsv1 => ffi::TLSv1_method(),
- SslMethod::Sslv23 => ffi::SSLv23_method(),
- #[cfg(feature = "tlsv1_1")]
- SslMethod::Tlsv1_1 => ffi::TLSv1_1_method(),
- #[cfg(feature = "tlsv1_2")]
- SslMethod::Tlsv1_2 => ffi::TLSv1_2_method(),
- #[cfg(feature = "dtlsv1")]
- SslMethod::Dtlsv1 => ffi::DTLSv1_method(),
- #[cfg(feature = "dtlsv1_2")]
- SslMethod::Dtlsv1_2 => ffi::DTLSv1_2_method(),
- }
- }
- }
-
- fn from_raw(method: *const ffi::SSL_METHOD) -> Option<SslMethod> {
- unsafe {
- match method {
- #[cfg(feature = "sslv2")]
- x if x == ffi::SSLv2_method() => Some(SslMethod::Sslv2),
- #[cfg(feature = "sslv3")]
- x if x == ffi::SSLv3_method() => Some(SslMethod::Sslv3),
- x if x == ffi::TLSv1_method() => Some(SslMethod::Tlsv1),
- x if x == ffi::SSLv23_method() => Some(SslMethod::Sslv23),
- #[cfg(feature = "tlsv1_1")]
- x if x == ffi::TLSv1_1_method() => Some(SslMethod::Tlsv1_1),
- #[cfg(feature = "tlsv1_2")]
- x if x == ffi::TLSv1_2_method() => Some(SslMethod::Tlsv1_2),
- #[cfg(feature = "dtlsv1")]
- x if x == ffi::DTLSv1_method() => Some(SslMethod::Dtlsv1),
- #[cfg(feature = "dtlsv1_2")]
- x if x == ffi::DTLSv1_2_method() => Some(SslMethod::Dtlsv1_2),
- _ => None,
- }
- }
- }
+ // TODO: support more methods
+ /// Support the TLS protocol
+ Tls,
+ /// Support DTLS protocol
+ Dtls,
}
/// Determines the type of certificate verification used
@@ -172,11 +108,11 @@ fn get_ssl_verify_data_idx<T: Any + 'static>() -> c_int {
*SSL_INDEXES.lock().unwrap().entry(TypeId::of::<T>()).or_insert_with(|| get_new_ssl_idx::<T>())
}
-#[cfg(feature = "npn")]
+#[cfg(all(feature = "npn", not(ossl101)))]
lazy_static! {
static ref NPN_PROTOS_IDX: c_int = get_new_idx::<Vec<u8>>();
}
-#[cfg(feature = "alpn")]
+#[cfg(all(feature = "alpn", not(ossl101)))]
lazy_static! {
static ref ALPN_PROTOS_IDX: c_int = get_new_idx::<Vec<u8>>();
}
@@ -184,52 +120,50 @@ lazy_static! {
/// Determine a new index to use for SSL CTX ex data.
/// Registers a destruct for the data which will be called by openssl when the context is freed.
fn get_new_idx<T>() -> c_int {
- extern "C" fn free_data_box<T>(_parent: *mut c_void,
- ptr: *mut c_void,
- _ad: *mut ffi::CRYPTO_EX_DATA,
- _idx: c_int,
- _argl: c_long,
- _argp: *mut c_void) {
+ extern fn free_data_box<T>(_parent: *mut c_void,
+ ptr: *mut c_void,
+ _ad: *mut ffi::CRYPTO_EX_DATA,
+ _idx: c_int,
+ _argl: c_long,
+ _argp: *mut c_void) {
if !ptr.is_null() {
let _: Box<T> = unsafe { mem::transmute(ptr) };
}
}
unsafe {
- let f: ffi::CRYPTO_EX_free = free_data_box::<T>;
- let idx = ffi::SSL_CTX_get_ex_new_index(0, ptr::null(), None, None, Some(f));
+ let idx = compat::get_new_idx(free_data_box::<T>);
assert!(idx >= 0);
idx
}
}
fn get_new_ssl_idx<T>() -> c_int {
- extern "C" fn free_data_box<T>(_parent: *mut c_void,
- ptr: *mut c_void,
- _ad: *mut ffi::CRYPTO_EX_DATA,
- _idx: c_int,
- _argl: c_long,
- _argp: *mut c_void) {
+ extern fn free_data_box<T>(_parent: *mut c_void,
+ ptr: *mut c_void,
+ _ad: *mut ffi::CRYPTO_EX_DATA,
+ _idx: c_int,
+ _argl: c_long,
+ _argp: *mut c_void) {
if !ptr.is_null() {
let _: Box<T> = unsafe { mem::transmute(ptr) };
}
}
unsafe {
- let f: ffi::CRYPTO_EX_free = free_data_box::<T>;
- let idx = ffi::SSL_get_ex_new_index(0, ptr::null(), None, None, Some(f));
+ let idx = compat::get_new_ssl_idx(free_data_box::<T>);
assert!(idx >= 0);
idx
}
}
-extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
+extern fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
where F: Fn(bool, &X509StoreContext) -> bool + Any + 'static + Sync + Send
{
unsafe {
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx);
- let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl);
+ let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _);
let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>());
let verify: &F = mem::transmute(verify);
@@ -239,13 +173,14 @@ extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_
}
}
-extern "C" fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
+extern fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
where F: Fn(bool, &X509StoreContext) -> bool + Any + 'static + Sync + Send
{
unsafe {
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx);
- let verify = ffi::SSL_get_ex_data(ssl, get_ssl_verify_data_idx::<F>());
+ let verify = ffi::SSL_get_ex_data(ssl as *const _,
+ get_ssl_verify_data_idx::<F>());
let verify: &F = mem::transmute(verify);
let ctx = X509StoreContext::new(x509_ctx);
@@ -254,7 +189,7 @@ extern "C" fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_ST
}
}
-extern "C" fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, _arg: *mut c_void) -> c_int
+extern fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, _arg: *mut c_void) -> c_int
where F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send
{
unsafe {
@@ -278,7 +213,7 @@ extern "C" fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, _arg: *mut c_void)
}
}
-#[cfg(any(feature = "npn", feature = "alpn"))]
+#[cfg(all(any(feature = "npn", feature = "alpn"), not(ossl101)))]
unsafe fn select_proto_using(ssl: *mut ffi::SSL,
out: *mut *mut c_uchar,
outlen: *mut c_uchar,
@@ -311,26 +246,26 @@ unsafe fn select_proto_using(ssl: *mut ffi::SSL,
/// supported by the server. It achieves this by delegating to the `SSL_select_next_proto`
/// function. The list of protocols supported by the client is found in the extra data of the
/// OpenSSL context.
-#[cfg(feature = "npn")]
-extern "C" fn raw_next_proto_select_cb(ssl: *mut ffi::SSL,
- out: *mut *mut c_uchar,
- outlen: *mut c_uchar,
- inbuf: *const c_uchar,
- inlen: c_uint,
- _arg: *mut c_void)
- -> c_int {
+#[cfg(all(feature = "npn", not(ossl101)))]
+extern fn raw_next_proto_select_cb(ssl: *mut ffi::SSL,
+ out: *mut *mut c_uchar,
+ outlen: *mut c_uchar,
+ inbuf: *const c_uchar,
+ inlen: c_uint,
+ _arg: *mut c_void)
+ -> c_int {
unsafe { select_proto_using(ssl, out, outlen, inbuf, inlen, *NPN_PROTOS_IDX) }
}
-#[cfg(feature = "alpn")]
-extern "C" fn raw_alpn_select_cb(ssl: *mut ffi::SSL,
- out: *mut *mut c_uchar,
- outlen: *mut c_uchar,
- inbuf: *const c_uchar,
- inlen: c_uint,
- _arg: *mut c_void)
- -> c_int {
- unsafe { select_proto_using(ssl, out, outlen, inbuf, inlen, *ALPN_PROTOS_IDX) }
+#[cfg(all(feature = "alpn", not(ossl101)))]
+extern fn raw_alpn_select_cb(ssl: *mut ffi::SSL,
+ out: *mut *const c_uchar,
+ outlen: *mut c_uchar,
+ inbuf: *const c_uchar,
+ inlen: c_uint,
+ _arg: *mut c_void)
+ -> c_int {
+ unsafe { select_proto_using(ssl, out as *mut _, outlen, inbuf, inlen, *ALPN_PROTOS_IDX) }
}
/// The function is given as the callback to `SSL_CTX_set_next_protos_advertised_cb`.
@@ -340,12 +275,12 @@ extern "C" fn raw_alpn_select_cb(ssl: *mut ffi::SSL,
/// that it supports.
/// The list of supported protocols is found in the extra data of the OpenSSL
/// context.
-#[cfg(feature = "npn")]
-extern "C" fn raw_next_protos_advertise_cb(ssl: *mut ffi::SSL,
- out: *mut *const c_uchar,
- outlen: *mut c_uint,
- _arg: *mut c_void)
- -> c_int {
+#[cfg(all(feature = "npn", not(ossl101)))]
+extern fn raw_next_protos_advertise_cb(ssl: *mut ffi::SSL,
+ out: *mut *const c_uchar,
+ outlen: *mut c_uint,
+ _arg: *mut c_void)
+ -> c_int {
unsafe {
// First, get the list of (supported) protocols saved in the context extra data.
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl);
@@ -367,7 +302,7 @@ extern "C" fn raw_next_protos_advertise_cb(ssl: *mut ffi::SSL,
/// Convert a set of byte slices into a series of byte strings encoded for SSL. Encoding is a byte
/// containing the length followed by the string.
-#[cfg(any(feature = "npn", feature = "alpn"))]
+#[cfg(all(any(feature = "alpn", feature = "npn"), not(ossl101)))]
fn ssl_encode_byte_strings(strings: &[&[u8]]) -> Vec<u8> {
let mut enc = Vec::new();
for string in strings {
@@ -442,8 +377,8 @@ impl<'a> SslContextRef<'a> {
ffi::SSL_CTX_set_ex_data(self.as_ptr(),
get_verify_data_idx::<F>(),
mem::transmute(callback));
- let f: extern "C" fn(_, _, _) -> _ = raw_sni::<F>;
- let f: extern "C" fn() = mem::transmute(f);
+ let f: extern fn(_, _, _) -> _ = raw_sni::<F>;
+ let f: extern fn() = mem::transmute(f);
ffi::SSL_CTX_set_tlsext_servername_callback(self.as_ptr(), Some(f));
}
}
@@ -515,15 +450,12 @@ impl<'a> SslContextRef<'a> {
}
/// Specifies the file that contains certificate chain
- pub fn set_certificate_chain_file<P: AsRef<Path>>(&mut self,
- file: P,
- file_type: X509FileType)
+ pub fn set_certificate_chain_file<P: AsRef<Path>>(&mut self, file: P)
-> Result<(), ErrorStack> {
let file = CString::new(file.as_ref().as_os_str().to_str().expect("invalid utf8")).unwrap();
wrap_ssl_result(unsafe {
ffi::SSL_CTX_use_certificate_chain_file(self.as_ptr(),
- file.as_ptr() as *const _,
- file_type as c_int)
+ file.as_ptr() as *const _)
})
}
@@ -575,27 +507,44 @@ impl<'a> SslContextRef<'a> {
})
}
- /// If `onoff` is set to `true`, enable ECDHE for key exchange with compatible
- /// clients, and automatically select an appropriate elliptic curve.
+ /// If `onoff` is set to `true`, enable ECDHE for key exchange with
+ /// compatible clients, and automatically select an appropriate elliptic
+ /// curve.
///
- /// This method requires OpenSSL >= 1.0.2 or LibreSSL and the `ecdh_auto` feature.
- #[cfg(feature = "ecdh_auto")]
+ /// This method requires OpenSSL >= 1.0.2 or LibreSSL and the `ecdh_auto`
+ /// feature.
+ #[cfg(all(feature = "ecdh_auto", not(ossl101)))]
pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> {
- wrap_ssl_result(unsafe { ffi::SSL_CTX_set_ecdh_auto(self.as_ptr(), onoff as c_long) as c_int })
+ self._set_ecdh_auto(onoff)
+ }
+
+ #[cfg(all(feature = "ecdh_auto", ossl102))]
+ fn _set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> {
+ wrap_ssl_result(unsafe {
+ ffi::SSL_CTX_ctrl(self.as_ptr(),
+ ffi::SSL_CTRL_SET_ECDH_AUTO,
+ onoff as c_long,
+ ptr::null_mut()) as c_int
+ })
+ }
+
+ #[cfg(all(feature = "ecdh_auto", ossl110))]
+ fn _set_ecdh_auto(&mut self, _onoff: bool) -> Result<(), ErrorStack> {
+ Ok(())
}
pub fn set_options(&mut self, option: SslContextOptions) -> SslContextOptions {
- let ret = unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits()) };
+ let ret = unsafe { compat::SSL_CTX_set_options(self.as_ptr(), option.bits()) };
SslContextOptions::from_bits(ret).unwrap()
}
pub fn options(&self) -> SslContextOptions {
- let ret = unsafe { ffi::SSL_CTX_get_options(self.as_ptr()) };
+ let ret = unsafe { compat::SSL_CTX_get_options(self.as_ptr()) };
SslContextOptions::from_bits(ret).unwrap()
}
pub fn clear_options(&mut self, option: SslContextOptions) -> SslContextOptions {
- let ret = unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits()) };
+ let ret = unsafe { compat::SSL_CTX_clear_options(self.as_ptr(), option.bits()) };
SslContextOptions::from_bits(ret).unwrap()
}
@@ -603,7 +552,7 @@ impl<'a> SslContextRef<'a> {
/// supported by the application).
///
/// This method needs the `npn` feature.
- #[cfg(feature = "npn")]
+ #[cfg(all(feature = "npn", not(ossl101)))]
pub fn set_npn_protocols(&mut self, protocols: &[&[u8]]) {
// Firstly, convert the list of protocols to a byte-array that can be passed to OpenSSL
// APIs -- a list of length-prefixed strings.
@@ -635,7 +584,7 @@ impl<'a> SslContextRef<'a> {
/// Note that ordering of the protocols controls the priority with which they are chosen.
///
/// This method needs the `alpn` feature.
- #[cfg(feature = "alpn")]
+ #[cfg(all(feature = "alpn", not(ossl101)))]
pub fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) {
let protocols: Box<Vec<u8>> = Box::new(ssl_encode_byte_strings(protocols));
unsafe {
@@ -662,12 +611,10 @@ pub struct SslContext(SslContextRef<'static>);
unsafe impl Send for SslContext {}
unsafe impl Sync for SslContext {}
-#[cfg(feature = "ssl_context_clone")]
impl Clone for SslContext {
- /// Requires the `ssl_context_clone` feature.
fn clone(&self) -> Self {
unsafe {
- ::c_helpers::rust_0_8_SSL_CTX_clone(self.as_ptr());
+ compat::SSL_CTX_up_ref(self.as_ptr());
SslContext::from_ptr(self.as_ptr())
}
}
@@ -706,15 +653,13 @@ impl SslContext {
init();
let mut ctx = unsafe {
- let ctx = try_ssl_null!(ffi::SSL_CTX_new(method.to_raw()));
+ let method = compat::get_method(method);
+ let ctx = try_ssl_null!(ffi::SSL_CTX_new(method));
SslContext::from_ptr(ctx)
};
match method {
- #[cfg(feature = "dtlsv1")]
- SslMethod::Dtlsv1 => ctx.set_read_ahead(1),
- #[cfg(feature = "dtlsv1_2")]
- SslMethod::Dtlsv1_2 => ctx.set_read_ahead(1),
+ SslMethod::Dtls => ctx.set_read_ahead(1),
_ => {}
}
// this is a bit dubious (?)
@@ -982,7 +927,7 @@ impl<'a> SslRef<'a> {
/// to interpret it.
///
/// This method needs the `alpn` feature.
- #[cfg(feature = "alpn")]
+ #[cfg(all(feature = "alpn", not(ossl101)))]
pub fn selected_alpn_protocol(&self) -> Option<&[u8]> {
unsafe {
let mut data: *const c_uchar = ptr::null();
@@ -1023,13 +968,6 @@ impl<'a> SslRef<'a> {
Some(s)
}
- pub fn ssl_method(&self) -> SslMethod {
- unsafe {
- let method = ffi::SSL_get_ssl_method(self.as_ptr());
- SslMethod::from_raw(method).unwrap()
- }
- }
-
/// Returns the server's name for the current connection
pub fn servername(&self) -> Option<String> {
let name = unsafe { ffi::SSL_get_servername(self.as_ptr(), ffi::TLSEXT_NAMETYPE_host_name) };
@@ -1319,16 +1257,12 @@ impl<S> SslStream<S> {
}
}
- #[cfg(feature = "nightly")]
fn check_panic(&mut self) {
if let Some(err) = unsafe { bio::take_panic::<S>(self.ssl.get_raw_rbio()) } {
::std::panic::resume_unwind(err)
}
}
- #[cfg(not(feature = "nightly"))]
- fn check_panic(&mut self) {}
-
fn get_bio_error(&mut self) -> io::Error {
let error = unsafe { bio::take_error::<S>(self.ssl.get_raw_rbio()) };
match error {
@@ -1412,3 +1346,107 @@ impl<'a> IntoSsl for &'a SslContext {
Ssl::new(self)
}
}
+
+#[cfg(ossl110)]
+mod compat {
+ use std::ptr;
+
+ use ffi;
+ use libc::c_int;
+
+ pub use ffi::{SSL_CTX_get_options, SSL_CTX_set_options};
+ pub use ffi::{SSL_CTX_clear_options, SSL_CTX_up_ref};
+
+ use super::SslMethod;
+
+ pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int {
+ ffi::CRYPTO_get_ex_new_index(ffi::CRYPTO_EX_INDEX_SSL_CTX,
+ 0,
+ ptr::null_mut(),
+ None,
+ None,
+ Some(f))
+ }
+
+ pub unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int {
+ ffi::CRYPTO_get_ex_new_index(ffi::CRYPTO_EX_INDEX_SSL,
+ 0,
+ ptr::null_mut(),
+ None,
+ None,
+ Some(f))
+ }
+
+ pub unsafe fn get_method(method: SslMethod) -> *const ffi::SSL_METHOD {
+ match method {
+ SslMethod::Tls => ffi::TLS_method(),
+ SslMethod::Dtls => ffi::DTLS_method(),
+ }
+ }
+}
+
+#[cfg(ossl10x)]
+#[allow(bad_style)]
+mod compat {
+ use std::ptr;
+
+ use ffi;
+ use libc::{self, c_long, c_ulong, c_int};
+
+ use super::SslMethod;
+
+ pub unsafe fn SSL_CTX_get_options(ctx: *const ffi::SSL_CTX) -> c_ulong {
+ ffi::SSL_CTX_ctrl(ctx as *mut _,
+ ffi::SSL_CTRL_OPTIONS,
+ 0,
+ ptr::null_mut()) as c_ulong
+ }
+
+ pub unsafe fn SSL_CTX_set_options(ctx: *const ffi::SSL_CTX,
+ op: c_ulong) -> c_ulong {
+ ffi::SSL_CTX_ctrl(ctx as *mut _,
+ ffi::SSL_CTRL_OPTIONS,
+ op as c_long,
+ ptr::null_mut()) as c_ulong
+ }
+
+ pub unsafe fn SSL_CTX_clear_options(ctx: *const ffi::SSL_CTX,
+ op: c_ulong) -> c_ulong {
+ ffi::SSL_CTX_ctrl(ctx as *mut _,
+ ffi::SSL_CTRL_CLEAR_OPTIONS,
+ op as c_long,
+ ptr::null_mut()) as c_ulong
+ }
+
+ pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int {
+ ffi::SSL_CTX_get_ex_new_index(0,
+ ptr::null_mut(),
+ None,
+ None,
+ Some(f))
+ }
+
+ pub unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int {
+ ffi::SSL_get_ex_new_index(0,
+ ptr::null_mut(),
+ None,
+ None,
+ Some(f))
+ }
+
+ pub unsafe fn get_method(method: SslMethod) -> *const ffi::SSL_METHOD {
+ match method {
+ SslMethod::Tls => ffi::SSLv23_method(),
+ SslMethod::Dtls => ffi::DTLSv1_method(),
+ }
+ }
+
+ pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> libc::c_int {
+ ffi::CRYPTO_add_lock(&mut (*ssl).references,
+ 1,
+ ffi::CRYPTO_LOCK_SSL_CTX,
+ "mod.rs\0".as_ptr() as *const _,
+ line!() as libc::c_int);
+ 0
+ }
+}
diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs
index 3bbbed03..e5bdc8da 100644
--- a/openssl/src/ssl/tests/mod.rs
+++ b/openssl/src/ssl/tests/mod.rs
@@ -1,5 +1,6 @@
#![allow(unused_imports)]
+use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::io::{self, BufReader};
@@ -12,11 +13,12 @@ use std::thread;
use std::time::Duration;
use net2::TcpStreamExt;
+use tempdir::TempDir;
use crypto::hash::Type::SHA256;
use ssl;
use ssl::SSL_VERIFY_PEER;
-use ssl::SslMethod::Sslv23;
+use ssl::SslMethod::Tls;
use ssl::{SslMethod, HandshakeError};
use ssl::error::Error;
use ssl::{SslContext, SslStream};
@@ -46,10 +48,21 @@ fn next_addr() -> SocketAddr {
struct Server {
p: Child,
+ _temp: TempDir,
}
impl Server {
fn spawn(args: &[&str], input: Option<Box<FnMut(ChildStdin) + Send>>) -> (Server, SocketAddr) {
+ static CERT: &'static [u8] = include_bytes!("../../../test/cert.pem");
+ static KEY: &'static [u8] = include_bytes!("../../../test/key.pem");
+
+
+ let td = TempDir::new("openssl").unwrap();
+ let cert = td.path().join("cert.pem");
+ let key = td.path().join("key.pem");
+ File::create(&cert).unwrap().write_all(CERT).unwrap();
+ File::create(&key).unwrap().write_all(KEY).unwrap();
+
let addr = next_addr();
let mut child = Command::new("openssl")
.arg("s_server")
@@ -57,11 +70,10 @@ impl Server {
.arg(addr.port().to_string())
.args(args)
.arg("-cert")
- .arg("cert.pem")
+ .arg(&cert)
.arg("-key")
- .arg("key.pem")
+ .arg(&key)
.arg("-no_dhe")
- .current_dir("test")
.stdout(Stdio::null())
.stderr(Stdio::null())
.stdin(Stdio::piped())
@@ -71,7 +83,7 @@ impl Server {
if let Some(mut input) = input {
thread::spawn(move || input(stdin));
}
- (Server { p: child }, addr)
+ (Server { p: child, _temp: td }, addr)
}
fn new_tcp(args: &[&str]) -> (Server, TcpStream) {
@@ -92,7 +104,7 @@ impl Server {
Server::new_tcp(&["-www"])
}
- #[cfg(any(feature = "alpn", feature = "npn"))]
+ #[cfg(all(any(feature = "alpn", feature = "npn"), not(ossl101)))]
fn new_alpn() -> (Server, TcpStream) {
Server::new_tcp(&["-www",
"-nextprotoneg",
@@ -119,7 +131,7 @@ impl Server {
// but don't currently have a great way to do that so just wait for a
// bit.
thread::sleep(Duration::from_millis(100));
- let socket = UdpSocket::bind(next_addr()).unwrap();
+ let socket = UdpSocket::bind("127.0.0.1:0").unwrap();
socket.connect(&addr).unwrap();
(s, UdpConnected(socket))
}
@@ -205,7 +217,7 @@ macro_rules! run_test(
#[test]
fn sslv23() {
let (_s, stream) = Server::new();
- $blk(SslMethod::Sslv23, stream);
+ $blk(SslMethod::Tls, stream);
}
#[test]
@@ -226,11 +238,6 @@ run_test!(new_sslstream, |method, stream| {
SslStream::connect(&SslContext::new(method).unwrap(), stream).unwrap();
});
-run_test!(get_ssl_method, |method, _| {
- let ssl = Ssl::new(&SslContext::new(method).unwrap()).unwrap();
- assert_eq!(ssl.ssl_method(), method);
-});
-
run_test!(verify_untrusted, |method, stream| {
let mut ctx = SslContext::new(method).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
@@ -391,11 +398,11 @@ run_test!(ssl_verify_callback, |method, stream| {
// Make sure every write call translates to a write call to the underlying socket.
#[test]
fn test_write_hits_stream() {
- let listener = TcpListener::bind(next_addr()).unwrap();
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap();
let guard = thread::spawn(move || {
- let ctx = SslContext::new(Sslv23).unwrap();
+ let ctx = SslContext::new(Tls).unwrap();
let stream = TcpStream::connect(addr).unwrap();
let mut stream = SslStream::connect(&ctx, stream).unwrap();
@@ -403,7 +410,7 @@ fn test_write_hits_stream() {
stream
});
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM).unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM).unwrap();
@@ -423,7 +430,7 @@ fn test_set_certificate_and_private_key() {
let cert = include_bytes!("../../../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_private_key(&key).unwrap();
ctx.set_certificate(&cert).unwrap();
@@ -451,7 +458,7 @@ run_test!(clear_ctx_options, |method, _| {
#[test]
fn test_write() {
let (_s, stream) = Server::new();
- let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), stream).unwrap();
+ let mut stream = SslStream::connect(&SslContext::new(Tls).unwrap(), stream).unwrap();
stream.write_all("hello".as_bytes()).unwrap();
stream.flush().unwrap();
stream.write_all(" there".as_bytes()).unwrap();
@@ -461,7 +468,7 @@ fn test_write() {
#[test]
fn test_write_direct() {
let (_s, stream) = Server::new();
- let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), stream).unwrap();
+ let mut stream = SslStream::connect(&SslContext::new(Tls).unwrap(), stream).unwrap();
stream.write_all("hello".as_bytes()).unwrap();
stream.flush().unwrap();
stream.write_all(" there".as_bytes()).unwrap();
@@ -492,7 +499,7 @@ fn test_write_dtlsv1() {
#[test]
fn test_read() {
let (_s, tcp) = Server::new();
- let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
+ let mut stream = SslStream::connect(&SslContext::new(Tls).unwrap(), tcp).unwrap();
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
stream.flush().unwrap();
io::copy(&mut stream, &mut io::sink()).ok().expect("read error");
@@ -501,7 +508,7 @@ fn test_read() {
#[test]
fn test_read_direct() {
let (_s, tcp) = Server::new();
- let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
+ let mut stream = SslStream::connect(&SslContext::new(Tls).unwrap(), tcp).unwrap();
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
stream.flush().unwrap();
io::copy(&mut stream, &mut io::sink()).ok().expect("read error");
@@ -510,7 +517,7 @@ fn test_read_direct() {
#[test]
fn test_pending() {
let (_s, tcp) = Server::new();
- let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
+ let mut stream = SslStream::connect(&SslContext::new(Tls).unwrap(), tcp).unwrap();
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
stream.flush().unwrap();
@@ -533,7 +540,7 @@ fn test_pending() {
#[test]
fn test_state() {
let (_s, tcp) = Server::new();
- let stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
+ let stream = SslStream::connect(&SslContext::new(Tls).unwrap(), tcp).unwrap();
assert_eq!(stream.ssl().state_string(), "SSLOK ");
assert_eq!(stream.ssl().state_string_long(),
"SSL negotiation finished successfully");
@@ -542,10 +549,10 @@ fn test_state() {
/// Tests that connecting with the client using ALPN, but the server not does not
/// break the existing connection behavior.
#[test]
-#[cfg(feature = "alpn")]
+#[cfg(all(feature = "alpn", not(ossl101)))]
fn test_connect_with_unilateral_alpn() {
let (_s, stream) = Server::new();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@@ -564,10 +571,10 @@ fn test_connect_with_unilateral_alpn() {
/// Tests that connecting with the client using NPN, but the server not does not
/// break the existing connection behavior.
#[test]
-#[cfg(feature = "npn")]
+#[cfg(all(feature = "npn", not(ossl101)))]
fn test_connect_with_unilateral_npn() {
let (_s, stream) = Server::new();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@@ -586,10 +593,10 @@ fn test_connect_with_unilateral_npn() {
/// Tests that when both the client as well as the server use ALPN and their
/// lists of supported protocols have an overlap, the correct protocol is chosen.
#[test]
-#[cfg(feature = "alpn")]
+#[cfg(all(feature = "alpn", not(ossl101)))]
fn test_connect_with_alpn_successful_multiple_matching() {
let (_s, stream) = Server::new_alpn();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@@ -608,10 +615,10 @@ fn test_connect_with_alpn_successful_multiple_matching() {
/// Tests that when both the client as well as the server use NPN and their
/// lists of supported protocols have an overlap, the correct protocol is chosen.
#[test]
-#[cfg(feature = "npn")]
+#[cfg(all(feature = "npn", not(ossl101)))]
fn test_connect_with_npn_successful_multiple_matching() {
let (_s, stream) = Server::new_alpn();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@@ -631,10 +638,10 @@ fn test_connect_with_npn_successful_multiple_matching() {
/// lists of supported protocols have an overlap -- with only ONE protocol
/// being valid for both.
#[test]
-#[cfg(feature = "alpn")]
+#[cfg(all(feature = "alpn", not(ossl101)))]
fn test_connect_with_alpn_successful_single_match() {
let (_s, stream) = Server::new_alpn();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@@ -655,10 +662,10 @@ fn test_connect_with_alpn_successful_single_match() {
/// lists of supported protocols have an overlap -- with only ONE protocol
/// being valid for both.
#[test]
-#[cfg(feature = "npn")]
+#[cfg(all(feature = "npn", not(ossl101)))]
fn test_connect_with_npn_successful_single_match() {
let (_s, stream) = Server::new_alpn();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_npn_protocols(&[b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@@ -677,13 +684,13 @@ fn test_connect_with_npn_successful_single_match() {
/// Tests that when the `SslStream` is created as a server stream, the protocols
/// are correctly advertised to the client.
#[test]
-#[cfg(feature = "npn")]
+#[cfg(all(feature = "npn", not(ossl101)))]
fn test_npn_server_advertise_multiple() {
- let listener = TcpListener::bind(next_addr()).unwrap();
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let localhost = listener.local_addr().unwrap();
// We create a different context instance for the server...
let listener_ctx = {
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]);
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
@@ -698,7 +705,7 @@ fn test_npn_server_advertise_multiple() {
let _ = SslStream::accept(&listener_ctx, stream).unwrap();
});
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_npn_protocols(&[b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@@ -718,13 +725,13 @@ fn test_npn_server_advertise_multiple() {
/// Tests that when the `SslStream` is created as a server stream, the protocols
/// are correctly advertised to the client.
#[test]
-#[cfg(feature = "alpn")]
+#[cfg(all(feature = "alpn", not(ossl101)))]
fn test_alpn_server_advertise_multiple() {
- let listener = TcpListener::bind(next_addr()).unwrap();
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let localhost = listener.local_addr().unwrap();
// We create a different context instance for the server...
let listener_ctx = {
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
@@ -739,7 +746,7 @@ fn test_alpn_server_advertise_multiple() {
let _ = SslStream::accept(&listener_ctx, stream).unwrap();
});
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@@ -759,13 +766,13 @@ fn test_alpn_server_advertise_multiple() {
/// Test that Servers supporting ALPN don't report a protocol when none of their protocols match
/// the client's reported protocol.
#[test]
-#[cfg(feature = "alpn")]
+#[cfg(all(feature = "alpn", not(ossl101)))]
fn test_alpn_server_select_none() {
- let listener = TcpListener::bind(next_addr()).unwrap();
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let localhost = listener.local_addr().unwrap();
// We create a different context instance for the server...
let listener_ctx = {
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
@@ -780,7 +787,7 @@ fn test_alpn_server_select_none() {
let _ = SslStream::accept(&listener_ctx, stream).unwrap();
});
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::new(Tls).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/2"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@@ -875,7 +882,7 @@ fn handshake(res: Result<SslStream<TcpStream>, HandshakeError<TcpStream>>)
fn test_write_nonblocking() {
let (_s, stream) = Server::new();
stream.set_nonblocking(true).unwrap();
- let cx = SslContext::new(Sslv23).unwrap();
+ let cx = SslContext::new(Tls).unwrap();
let mut stream = handshake(SslStream::connect(&cx, stream));
let mut iterations = 0;
@@ -913,7 +920,7 @@ fn test_write_nonblocking() {
fn test_read_nonblocking() {
let (_s, stream) = Server::new();
stream.set_nonblocking(true).unwrap();
- let cx = SslContext::new(Sslv23).unwrap();
+ let cx = SslContext::new(Tls).unwrap();
let mut stream = handshake(SslStream::connect(&cx, stream));
let mut iterations = 0;
@@ -965,7 +972,6 @@ fn test_read_nonblocking() {
#[test]
#[should_panic(expected = "blammo")]
-#[cfg(feature = "nightly")]
fn write_panic() {
struct ExplodingStream(TcpStream);
@@ -988,13 +994,12 @@ fn write_panic() {
let (_s, stream) = Server::new();
let stream = ExplodingStream(stream);
- let ctx = SslContext::new(SslMethod::Sslv23).unwrap();
+ let ctx = SslContext::new(SslMethod::Tls).unwrap();
let _ = SslStream::connect(&ctx, stream);
}
#[test]
#[should_panic(expected = "blammo")]
-#[cfg(feature = "nightly")]
fn read_panic() {
struct ExplodingStream(TcpStream);
@@ -1017,13 +1022,12 @@ fn read_panic() {
let (_s, stream) = Server::new();
let stream = ExplodingStream(stream);
- let ctx = SslContext::new(SslMethod::Sslv23).unwrap();
+ let ctx = SslContext::new(SslMethod::Tls).unwrap();
let _ = SslStream::connect(&ctx, stream);
}
#[test]
#[should_panic(expected = "blammo")]
-#[cfg(feature = "nightly")]
fn flush_panic() {
struct ExplodingStream(TcpStream);
@@ -1046,20 +1050,20 @@ fn flush_panic() {
let (_s, stream) = Server::new();
let stream = ExplodingStream(stream);
- let ctx = SslContext::new(SslMethod::Sslv23).unwrap();
- let mut stream = SslStream::connect(&ctx, stream).unwrap();
+ let ctx = SslContext::new(SslMethod::Tls).unwrap();
+ let mut stream = SslStream::connect(&ctx, stream).ok().unwrap();
let _ = stream.flush();
}
#[test]
fn refcount_ssl_context() {
let mut ssl = {
- let ctx = SslContext::new(SslMethod::Sslv23).unwrap();
+ let ctx = SslContext::new(SslMethod::Tls).unwrap();
ssl::Ssl::new(&ctx).unwrap()
};
{
- let new_ctx_a = SslContext::new(SslMethod::Sslv23).unwrap();
+ let new_ctx_a = SslContext::new(SslMethod::Tls).unwrap();
let _new_ctx_b = ssl.set_ssl_context(&new_ctx_a);
}
}
@@ -1067,7 +1071,7 @@ fn refcount_ssl_context() {
#[test]
#[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :(
fn default_verify_paths() {
- let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap();
+ let mut ctx = SslContext::new(SslMethod::Tls).unwrap();
ctx.set_default_verify_paths().unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
let s = TcpStream::connect("google.com:443").unwrap();
@@ -1086,6 +1090,6 @@ fn default_verify_paths() {
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();
+ let mut ctx = SslContext::new(SslMethod::Tls).unwrap();
ctx.add_extra_chain_cert(&cert).unwrap();
}
diff --git a/openssl/src/version.rs b/openssl/src/version.rs
index 0e9f61d8..245305e8 100644
--- a/openssl/src/version.rs
+++ b/openssl/src/version.rs
@@ -11,9 +11,26 @@
// limitations under the License.
//
-use ffi;
use std::ffi::CStr;
+#[cfg(ossl10x)]
+use ffi::{
+ SSLEAY_VERSION as OPENSSL_VERSION,
+ SSLEAY_CFLAGS as OPENSSL_CFLAGS,
+ SSLEAY_BUILT_ON as OPENSSL_BUILT_ON,
+ SSLEAY_PLATFORM as OPENSSL_PLATFORM,
+ SSLEAY_DIR as OPENSSL_DIR,
+ SSLeay as OpenSSL_version_num,
+ SSLeay_version as OpenSSL_version,
+};
+
+#[cfg(ossl110)]
+use ffi::{OPENSSL_VERSION, OPENSSL_CFLAGS};
+#[cfg(ossl110)]
+use ffi::{OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR};
+#[cfg(ossl110)]
+use ffi::{OpenSSL_version_num, OpenSSL_version};
+
/// OPENSSL_VERSION_NUMBER is a numeric release version identifier:
///
/// `MNNFFPPS: major minor fix patch status`
@@ -39,34 +56,34 @@ use std::ffi::CStr;
///
/// The return value of this function can be compared to the macro to make sure that the correct version of the library has been loaded, especially when using DLLs on Windows systems.
pub fn number() -> i64 {
- unsafe { ffi::SSLeay() as i64 }
+ unsafe { OpenSSL_version_num() as i64 }
}
/// The text variant of the version number and the release date. For example, "OpenSSL 0.9.5a 1 Apr 2000".
pub fn version() -> &'static str {
- unsafe { CStr::from_ptr(ffi::SSLeay_version(ffi::SSLEAY_VERSION)).to_str().unwrap() }
+ unsafe { CStr::from_ptr(OpenSSL_version(OPENSSL_VERSION)).to_str().unwrap() }
}
/// The compiler flags set for the compilation process in the form "compiler: ..." if available or
/// "compiler: information not available" otherwise.
pub fn c_flags() -> &'static str {
- unsafe { CStr::from_ptr(ffi::SSLeay_version(ffi::SSLEAY_CFLAGS)).to_str().unwrap() }
+ unsafe { CStr::from_ptr(OpenSSL_version(OPENSSL_CFLAGS)).to_str().unwrap() }
}
/// The date of the build process in the form "built on: ..." if available or "built on: date not available" otherwise.
pub fn built_on() -> &'static str {
- unsafe { CStr::from_ptr(ffi::SSLeay_version(ffi::SSLEAY_BUILT_ON)).to_str().unwrap() }
+ unsafe { CStr::from_ptr(OpenSSL_version(OPENSSL_BUILT_ON)).to_str().unwrap() }
}
/// The "Configure" target of the library build in the form "platform: ..." if available or "platform: information not available" otherwise.
pub fn platform() -> &'static str {
- unsafe { CStr::from_ptr(ffi::SSLeay_version(ffi::SSLEAY_PLATFORM)).to_str().unwrap() }
+ unsafe { CStr::from_ptr(OpenSSL_version(OPENSSL_PLATFORM)).to_str().unwrap() }
}
/// The "OPENSSLDIR" setting of the library build in the form "OPENSSLDIR: "..."" if available or "OPENSSLDIR: N/A" otherwise.
pub fn dir() -> &'static str {
- unsafe { CStr::from_ptr(ffi::SSLeay_version(ffi::SSLEAY_DIR)).to_str().unwrap() }
+ unsafe { CStr::from_ptr(OpenSSL_version(OPENSSL_DIR)).to_str().unwrap() }
}
/// This test ensures that we do not segfault when calling the functions of this module
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");