aboutsummaryrefslogtreecommitdiff
path: root/openssl
diff options
context:
space:
mode:
authorBenjamin Cheng <[email protected]>2018-06-02 10:56:31 -0400
committerBenjamin Cheng <[email protected]>2018-06-02 10:56:31 -0400
commitb1eb1224f50b6242f82cdeca7a876409c98e1d3a (patch)
tree4aad295a6847fb1bd2d54880cf5bcd4b7ec522f5 /openssl
parentAdd wrapper for SSL_CTX_set_psk_server_callback (diff)
parentMerge pull request #940 from CmdrMoozy/rsa_padding (diff)
downloadrust-openssl-b1eb1224f50b6242f82cdeca7a876409c98e1d3a.tar.xz
rust-openssl-b1eb1224f50b6242f82cdeca7a876409c98e1d3a.zip
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'openssl')
-rw-r--r--openssl/Cargo.toml6
-rw-r--r--openssl/build.rs43
-rw-r--r--openssl/src/asn1.rs24
-rw-r--r--openssl/src/bio.rs20
-rw-r--r--openssl/src/bn.rs57
-rw-r--r--openssl/src/cms.rs37
-rw-r--r--openssl/src/dh.rs48
-rw-r--r--openssl/src/dsa.rs50
-rw-r--r--openssl/src/ec.rs16
-rw-r--r--openssl/src/ecdsa.rs80
-rw-r--r--openssl/src/hash.rs64
-rw-r--r--openssl/src/lib.rs4
-rw-r--r--openssl/src/nid.rs129
-rw-r--r--openssl/src/pkcs12.rs27
-rw-r--r--openssl/src/rsa.rs230
-rw-r--r--openssl/src/sign.rs27
-rw-r--r--openssl/src/ssl/bio.rs204
-rw-r--r--openssl/src/ssl/callbacks.rs75
-rw-r--r--openssl/src/ssl/connector.rs388
-rw-r--r--openssl/src/ssl/error.rs17
-rw-r--r--openssl/src/ssl/mod.rs565
-rw-r--r--openssl/src/ssl/test.rs34
-rw-r--r--openssl/src/stack.rs57
-rw-r--r--openssl/src/symm.rs43
-rw-r--r--openssl/src/version.rs25
-rw-r--r--openssl/src/x509/mod.rs196
-rw-r--r--openssl/src/x509/store.rs10
-rw-r--r--openssl/src/x509/tests.rs21
-rw-r--r--openssl/src/x509/verify.rs2
29 files changed, 1482 insertions, 1017 deletions
diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml
index 25aab11d..81568472 100644
--- a/openssl/Cargo.toml
+++ b/openssl/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "openssl"
-version = "0.10.7"
+version = "0.10.9"
authors = ["Steven Fackler <[email protected]>"]
license = "Apache-2.0"
description = "OpenSSL bindings"
@@ -18,10 +18,12 @@ v111 = []
[dependencies]
bitflags = "1.0"
+cfg-if = "0.1"
foreign-types = "0.3.1"
lazy_static = "1"
libc = "0.2"
-openssl-sys = { version = "0.9.30", path = "../openssl-sys" }
+
+openssl-sys = { version = "0.9.32", path = "../openssl-sys" }
[dev-dependencies]
tempdir = "0.3"
diff --git a/openssl/build.rs b/openssl/build.rs
index 612322fe..5a5b86f2 100644
--- a/openssl/build.rs
+++ b/openssl/build.rs
@@ -1,25 +1,6 @@
use std::env;
fn main() {
- match env::var("DEP_OPENSSL_VERSION") {
- Ok(ref v) if v == "101" => {
- println!("cargo:rustc-cfg=ossl101");
- println!("cargo:rustc-cfg=ossl10x");
- }
- Ok(ref v) if v == "102" => {
- println!("cargo:rustc-cfg=ossl102");
- println!("cargo:rustc-cfg=ossl10x");
- }
- Ok(ref v) if v == "110" => {
- println!("cargo:rustc-cfg=ossl110");
- }
- Ok(ref v) if v == "111" => {
- println!("cargo:rustc-cfg=ossl110");
- println!("cargo:rustc-cfg=ossl111");
- }
- _ => panic!("Unable to detect OpenSSL version"),
- }
-
if let Ok(_) = env::var("DEP_OPENSSL_LIBRESSL") {
println!("cargo:rustc-cfg=libressl");
}
@@ -37,8 +18,32 @@ fn main() {
if let Ok(version) = env::var("DEP_OPENSSL_VERSION_NUMBER") {
let version = u64::from_str_radix(&version, 16).unwrap();
+ if version >= 0x1_00_01_00_0 {
+ println!("cargo:rustc-cfg=ossl101");
+ }
+ if version >= 0x1_00_02_00_0 {
+ println!("cargo:rustc-cfg=ossl102");
+ }
+ if version >= 0x1_01_00_00_0 {
+ println!("cargo:rustc-cfg=ossl110");
+ }
if version >= 0x1_01_00_07_0 {
println!("cargo:rustc-cfg=ossl110g");
}
+ if version >= 0x1_01_01_00_0 {
+ println!("cargo:rustc-cfg=ossl111");
+ }
+ }
+
+ if let Ok(version) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") {
+ let version = u64::from_str_radix(&version, 16).unwrap();
+
+ if version >= 0x2_06_01_00_0 {
+ println!("cargo:rustc-cfg=libressl261");
+ }
+
+ if version >= 0x2_07_00_00_0 {
+ println!("cargo:rustc-cfg=libressl270");
+ }
}
}
diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs
index f6917aae..03546a4d 100644
--- a/openssl/src/asn1.rs
+++ b/openssl/src/asn1.rs
@@ -32,12 +32,12 @@ use std::ptr;
use std::slice;
use std::str;
-use {cvt, cvt_p};
use bio::MemBio;
use bn::BigNum;
use error::ErrorStack;
use nid::Nid;
use string::OpensslString;
+use {cvt, cvt_p};
foreign_type_and_impl_send_sync! {
type CType = ffi::ASN1_GENERALIZEDTIME;
@@ -162,7 +162,7 @@ impl Asn1StringRef {
///
/// [`as_utf8`]: struct.Asn1String.html#method.as_utf8
pub fn as_slice(&self) -> &[u8] {
- unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr()), self.len()) }
+ unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr()), self.len()) }
}
/// Return the length of the Asn1String (number of bytes)
@@ -241,11 +241,11 @@ foreign_type_and_impl_send_sync! {
impl Asn1BitStringRef {
/// Returns the Asn1BitString as a slice
pub fn as_slice(&self) -> &[u8] {
- unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr() as *mut _), self.len()) }
+ unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) }
}
/// Length of Asn1BitString in number of bytes.
pub fn len(&self) -> usize {
- unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *mut _) as usize }
+ unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *const _) as usize }
}
}
@@ -296,11 +296,13 @@ impl fmt::Display for Asn1ObjectRef {
}
}
-#[cfg(any(ossl101, ossl102))]
-use ffi::ASN1_STRING_data;
-
-#[cfg(ossl110)]
-#[allow(bad_style)]
-unsafe fn ASN1_STRING_data(s: *mut ffi::ASN1_STRING) -> *mut ::libc::c_uchar {
- ffi::ASN1_STRING_get0_data(s) as *mut _
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::ASN1_STRING_get0_data;
+ } else {
+ #[allow(bad_style)]
+ unsafe fn ASN1_STRING_get0_data(s: *mut ffi::ASN1_STRING) -> *const ::libc::c_uchar {
+ ffi::ASN1_STRING_data(s)
+ }
+ }
}
diff --git a/openssl/src/bio.rs b/openssl/src/bio.rs
index 56ba1f3d..51724e3f 100644
--- a/openssl/src/bio.rs
+++ b/openssl/src/bio.rs
@@ -1,8 +1,8 @@
+use ffi;
+use libc::c_int;
use std::marker::PhantomData;
use std::ptr;
use std::slice;
-use libc::c_int;
-use ffi;
use cvt_p;
use error::ErrorStack;
@@ -68,11 +68,13 @@ impl MemBio {
}
}
-#[cfg(not(ossl101))]
-use ffi::BIO_new_mem_buf;
-
-#[cfg(ossl101)]
-#[allow(bad_style)]
-unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO {
- ffi::BIO_new_mem_buf(buf as *mut _, len)
+cfg_if! {
+ if #[cfg(ossl102)] {
+ use ffi::BIO_new_mem_buf;
+ } else {
+ #[allow(bad_style)]
+ unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO {
+ ffi::BIO_new_mem_buf(buf as *mut _, len)
+ }
+ }
}
diff --git a/openssl/src/bn.rs b/openssl/src/bn.rs
index fe662e85..15dd7368 100644
--- a/openssl/src/bn.rs
+++ b/openssl/src/bn.rs
@@ -30,28 +30,39 @@ use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use std::cmp::Ordering;
use std::ffi::CString;
-use std::{fmt, ptr};
use std::ops::{Add, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub};
+use std::{fmt, ptr};
-use {cvt, cvt_n, cvt_p};
use asn1::Asn1Integer;
use error::ErrorStack;
use string::OpensslString;
+use {cvt, cvt_n, cvt_p};
-#[cfg(ossl10x)]
-use ffi::{get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
- get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
- get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536,
- get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048,
- get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072,
- get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096,
- get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144,
- get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192};
-
-#[cfg(ossl110)]
-use ffi::{BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536,
- BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
- BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192};
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::{
+ BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536,
+ BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
+ BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192, BN_is_negative,
+ };
+ } else {
+ use ffi::{
+ get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
+ get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
+ get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536,
+ get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048,
+ get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072,
+ get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096,
+ get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144,
+ get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192,
+ };
+
+ #[allow(bad_style)]
+ unsafe fn BN_is_negative(bn: *const ffi::BIGNUM) -> c_int {
+ (*bn).neg
+ }
+ }
+}
/// Options for the most significant bits of a randomly generated `BigNum`.
pub struct MsbOption(c_int);
@@ -361,17 +372,7 @@ impl BigNumRef {
/// Returns `true` if `self` is negative.
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 }
+ unsafe { BN_is_negative(self.as_ptr()) == 1 }
}
/// Returns the number of significant bits in `self`.
@@ -1218,7 +1219,7 @@ macro_rules! delegate {
$t::$m(self.deref(), oth.deref())
}
}
- }
+ };
}
impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
diff --git a/openssl/src/cms.rs b/openssl/src/cms.rs
index 6ee62fd0..d8d64c00 100644
--- a/openssl/src/cms.rs
+++ b/openssl/src/cms.rs
@@ -13,8 +13,8 @@ use bio::{MemBio, MemBioSlice};
use error::ErrorStack;
use libc::c_uint;
use pkey::{HasPrivate, PKeyRef};
-use stack::Stack;
-use x509::X509;
+use stack::StackRef;
+use x509::{X509, X509Ref};
use {cvt, cvt_p};
bitflags! {
@@ -130,30 +130,25 @@ impl CmsContentInfo {
/// OpenSSL documentation at [`CMS_sign`]
///
/// [`CMS_sign`]: https://www.openssl.org/docs/manmaster/man3/CMS_sign.html
- pub fn sign<T: HasPrivate>(
- signcert: Option<&X509>,
+ pub fn sign<T>(
+ signcert: Option<&X509Ref>,
pkey: Option<&PKeyRef<T>>,
- certs: Option<&Stack<X509>>,
+ certs: Option<&StackRef<X509>>,
data: Option<&[u8]>,
flags: CMSOptions,
- ) -> Result<CmsContentInfo, ErrorStack> {
+ ) -> Result<CmsContentInfo, ErrorStack>
+ where
+ T: HasPrivate,
+ {
unsafe {
- let signcert = match signcert {
- Some(cert) => cert.as_ptr(),
- None => ptr::null_mut(),
- };
- let pkey = match pkey {
- Some(pkey) => pkey.as_ptr(),
- None => ptr::null_mut(),
- };
- let data_bio_ptr = match data {
- Some(data) => MemBioSlice::new(data)?.as_ptr(),
- None => ptr::null_mut(),
- };
- let certs = match certs {
- Some(certs) => certs.as_ptr(),
- None => ptr::null_mut(),
+ let signcert = signcert.map_or(ptr::null_mut(), |p| p.as_ptr());
+ let pkey = pkey.map_or(ptr::null_mut(), |p| p.as_ptr());
+ let data_bio = match data {
+ Some(data) => Some(MemBioSlice::new(data)?),
+ None => None,
};
+ let data_bio_ptr = data_bio.as_ref().map_or(ptr::null_mut(), |p| p.as_ptr());
+ let certs = certs.map_or(ptr::null_mut(), |p| p.as_ptr());
let cms = cvt_p(ffi::CMS_sign(
signcert,
diff --git a/openssl/src/dh.rs b/openssl/src/dh.rs
index a90b10b8..730a5180 100644
--- a/openssl/src/dh.rs
+++ b/openssl/src/dh.rs
@@ -4,9 +4,9 @@ use foreign_types::{ForeignType, ForeignTypeRef};
use std::mem;
use std::ptr;
-use {cvt, cvt_p};
use bn::BigNum;
use pkey::{HasParams, Params};
+use {cvt, cvt_p};
generic_foreign_type_and_impl_send_sync! {
type CType = ffi::DH;
@@ -48,12 +48,7 @@ impl Dh<Params> {
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<Dh<Params>, ErrorStack> {
unsafe {
let dh = Dh::from_ptr(cvt_p(ffi::DH_new())?);
- cvt(compat::DH_set0_pqg(
- dh.0,
- p.as_ptr(),
- q.as_ptr(),
- g.as_ptr(),
- ))?;
+ cvt(DH_set0_pqg(dh.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
mem::forget((p, g, q));
Ok(dh)
}
@@ -111,34 +106,29 @@ impl Dh<Params> {
}
}
-#[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_if! {
+ if #[cfg(ossl110)] {
+ use ffi::DH_set0_pqg;
+ } else {
+ #[allow(bad_style)]
+ unsafe fn DH_set0_pqg(
+ dh: *mut ffi::DH,
+ p: *mut ffi::BIGNUM,
+ q: *mut ffi::BIGNUM,
+ g: *mut ffi::BIGNUM,
+ ) -> ::libc::c_int {
+ (*dh).p = p;
+ (*dh).q = q;
+ (*dh).g = g;
+ 1
+ }
}
}
#[cfg(test)]
mod tests {
- use dh::Dh;
use bn::BigNum;
+ use dh::Dh;
use ssl::{SslContext, SslMethod};
#[test]
diff --git a/openssl/src/dsa.rs b/openssl/src/dsa.rs
index 0a14ccc3..abc2e297 100644
--- a/openssl/src/dsa.rs
+++ b/openssl/src/dsa.rs
@@ -11,10 +11,10 @@ use libc::c_int;
use std::fmt;
use std::ptr;
-use {cvt, cvt_p};
use bn::BigNumRef;
use error::ErrorStack;
use pkey::{HasParams, HasPublic, Private, Public};
+use {cvt, cvt_p};
generic_foreign_type_and_impl_send_sync! {
type CType = ffi::DSA;
@@ -101,7 +101,8 @@ where
/// Returns the DSA prime parameter of `self`.
pub fn p(&self) -> &BigNumRef {
unsafe {
- let p = compat::pqg(self.as_ptr())[0];
+ let mut p = ptr::null();
+ DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut());
BigNumRef::from_ptr(p as *mut _)
}
}
@@ -109,7 +110,8 @@ where
/// Returns the DSA sub-prime parameter of `self`.
pub fn q(&self) -> &BigNumRef {
unsafe {
- let q = compat::pqg(self.as_ptr())[1];
+ let mut q = ptr::null();
+ DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut());
BigNumRef::from_ptr(q as *mut _)
}
}
@@ -117,7 +119,8 @@ where
/// Returns the DSA base parameter of `self`.
pub fn g(&self) -> &BigNumRef {
unsafe {
- let g = compat::pqg(self.as_ptr())[2];
+ let mut g = ptr::null();
+ DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g);
BigNumRef::from_ptr(g as *mut _)
}
}
@@ -184,24 +187,27 @@ impl<T> fmt::Debug for Dsa<T> {
}
}
-#[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]
- }
-}
-
-#[cfg(ossl10x)]
-mod compat {
- use ffi::{BIGNUM, DSA};
-
- pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] {
- [(*d).p, (*d).q, (*d).g]
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::DSA_get0_pqg;
+ } else {
+ #[allow(bad_style)]
+ unsafe fn DSA_get0_pqg(
+ d: *mut ffi::DSA,
+ p: *mut *const ffi::BIGNUM,
+ q: *mut *const ffi::BIGNUM,
+ g: *mut *const ffi::BIGNUM)
+ {
+ if !p.is_null() {
+ *p = (*d).p;
+ }
+ if !q.is_null() {
+ *q = (*d).q;
+ }
+ if !g.is_null() {
+ *g = (*d).g;
+ }
+ }
}
}
diff --git a/openssl/src/ec.rs b/openssl/src/ec.rs
index c4800c73..573d0c00 100644
--- a/openssl/src/ec.rs
+++ b/openssl/src/ec.rs
@@ -33,14 +33,14 @@
//! ```
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
-use std::ptr;
use libc::c_int;
+use std::ptr;
-use {cvt, cvt_n, cvt_p, init};
use bn::{BigNumContextRef, BigNumRef};
use error::ErrorStack;
use nid::Nid;
use pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
+use {cvt, cvt_n, cvt_p, init};
/// Compressed or Uncompressed conversion
///
@@ -803,10 +803,10 @@ impl<T> Clone for EcKey<T> {
#[cfg(test)]
mod test {
+ use super::*;
use bn::{BigNum, BigNumContext};
- use nid::Nid;
use data_encoding::BASE64URL_NOPAD;
- use super::*;
+ use nid::Nid;
#[test]
fn key_new_by_curve_name() {
@@ -823,7 +823,7 @@ mod test {
fn dup() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
- key.clone();
+ drop(key.clone());
}
#[test]
@@ -862,7 +862,8 @@ mod test {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
let mut ctx = BigNumContext::new().unwrap();
- let bytes = key.public_key()
+ let bytes = key
+ .public_key()
.to_bytes(&group, PointConversionForm::COMPRESSED, &mut ctx)
.unwrap();
@@ -877,7 +878,8 @@ mod test {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
- let dup_key = EcKey::from_private_components(&group, key.private_key(), key.public_key()).unwrap();
+ let dup_key =
+ EcKey::from_private_components(&group, key.private_key(), key.public_key()).unwrap();
let res = dup_key.check_key().unwrap();
assert!(res == ());
diff --git a/openssl/src/ecdsa.rs b/openssl/src/ecdsa.rs
index 120f6531..d07dfda4 100644
--- a/openssl/src/ecdsa.rs
+++ b/openssl/src/ecdsa.rs
@@ -3,12 +3,13 @@ use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use std::mem;
+use std::ptr;
use bn::{BigNum, BigNumRef};
-use {cvt, cvt_n, cvt_p};
use ec::EcKeyRef;
use error::ErrorStack;
use pkey::{Private, Public};
+use {cvt_n, cvt_p};
foreign_type_and_impl_send_sync! {
type CType = ffi::ECDSA_SIG;
@@ -53,7 +54,7 @@ impl EcdsaSig {
pub fn from_private_components(r: BigNum, s: BigNum) -> Result<EcdsaSig, ErrorStack> {
unsafe {
let sig = cvt_p(ffi::ECDSA_SIG_new())?;
- cvt(compat::set_numbers(sig, r.as_ptr(), s.as_ptr()))?;
+ ECDSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
mem::forget((r, s));
Ok(EcdsaSig::from_ptr(sig as *mut _))
}
@@ -83,8 +84,9 @@ impl EcdsaSig {
/// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html
pub fn r(&self) -> &BigNumRef {
unsafe {
- let xs = compat::get_numbers(self.as_ptr());
- BigNumRef::from_ptr(xs[0] as *mut _)
+ let mut r = ptr::null();
+ ECDSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
+ BigNumRef::from_ptr(r as *mut _)
}
}
@@ -95,53 +97,50 @@ impl EcdsaSig {
/// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html
pub fn s(&self) -> &BigNumRef {
unsafe {
- let xs = compat::get_numbers(self.as_ptr());
- BigNumRef::from_ptr(xs[1] as *mut _)
+ let mut s = ptr::null();
+ ECDSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
+ BigNumRef::from_ptr(s as *mut _)
}
}
}
-#[cfg(ossl110)]
-mod compat {
- use std::ptr;
-
- use libc::c_int;
- use ffi::{self, BIGNUM, ECDSA_SIG};
-
- pub unsafe fn set_numbers(sig: *mut ECDSA_SIG, r: *mut BIGNUM, s: *mut BIGNUM) -> c_int {
- ffi::ECDSA_SIG_set0(sig, r, s)
- }
-
- pub unsafe fn get_numbers(sig: *mut ECDSA_SIG) -> [*const BIGNUM; 2] {
- let (mut r, mut s) = (ptr::null(), ptr::null());
- ffi::ECDSA_SIG_get0(sig, &mut r, &mut s);
- [r, s]
- }
-}
-
-#[cfg(ossl10x)]
-mod compat {
- use libc::c_int;
- use ffi::{BIGNUM, ECDSA_SIG};
-
- pub unsafe fn set_numbers(sig: *mut ECDSA_SIG, r: *mut BIGNUM, s: *mut BIGNUM) -> c_int {
- (*sig).r = r;
- (*sig).s = s;
- 1
- }
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::{ECDSA_SIG_set0, ECDSA_SIG_get0};
+ } else {
+ #[allow(bad_style)]
+ unsafe fn ECDSA_SIG_set0(
+ sig: *mut ffi::ECDSA_SIG,
+ r: *mut ffi::BIGNUM,
+ s: *mut ffi::BIGNUM,
+ ) -> c_int {
+ (*sig).r = r;
+ (*sig).s = s;
+ 1
+ }
- pub unsafe fn get_numbers(sig: *mut ECDSA_SIG) -> [*const BIGNUM; 2] {
- [(*sig).r, (*sig).s]
+ #[allow(bad_style)]
+ unsafe fn ECDSA_SIG_get0(
+ sig: *const ffi::ECDSA_SIG,
+ pr: *mut *const ffi::BIGNUM,
+ ps: *mut *const ffi::BIGNUM)
+ {
+ if !pr.is_null() {
+ (*pr) = (*sig).r;
+ }
+ if !ps.is_null() {
+ (*ps) = (*sig).s;
+ }
+ }
}
-
}
#[cfg(test)]
mod test {
- use nid::Nid;
+ use super::*;
use ec::EcGroup;
use ec::EcKey;
- use super::*;
+ use nid::Nid;
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
static CURVE_IDENTIFER: Nid = Nid::X9_62_PRIME192V1;
@@ -171,7 +170,8 @@ mod test {
assert!(verification);
// Signature will not be verified using the incorrect data but the correct public key
- let verification2 = res.verify(String::from("hello2").as_bytes(), &public_key)
+ let verification2 = res
+ .verify(String::from("hello2").as_bytes(), &public_key)
.unwrap();
assert!(verification2 == false);
diff --git a/openssl/src/hash.rs b/openssl/src/hash.rs
index 726ebe9c..dd4d136c 100644
--- a/openssl/src/hash.rs
+++ b/openssl/src/hash.rs
@@ -1,22 +1,44 @@
-use std::io::prelude::*;
+use ffi;
+use std::fmt;
use std::io;
+use std::io::prelude::*;
use std::ops::{Deref, DerefMut};
-use std::fmt;
-use ffi;
-#[cfg(ossl110)]
-use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
-#[cfg(any(ossl101, ossl102))]
-use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
-
-use {cvt, cvt_p};
use error::ErrorStack;
+use nid::Nid;
+use {cvt, cvt_p};
+
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
+ } else {
+ use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
+ }
+}
#[derive(Copy, Clone)]
pub struct MessageDigest(*const ffi::EVP_MD);
impl MessageDigest {
- pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self { MessageDigest(x) }
+ pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self {
+ MessageDigest(x)
+ }
+
+ /// Returns the `MessageDigest` corresponding to an `Nid`.
+ ///
+ /// This corresponds to [`EVP_get_digestbynid`].
+ ///
+ /// [`EVP_get_digestbynid`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestInit.html
+ pub fn from_nid(type_: Nid) -> Option<MessageDigest> {
+ unsafe {
+ let ptr = ffi::EVP_get_digestbynid(type_.as_raw());
+ if ptr.is_null() {
+ None
+ } else {
+ Some(MessageDigest(ptr))
+ }
+ }
+ }
pub fn md5() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_md5()) }
@@ -229,8 +251,8 @@ impl Drop for Hasher {
/// store the digest data.
#[derive(Copy)]
pub struct DigestBytes {
- buf: [u8; ffi::EVP_MAX_MD_SIZE as usize],
- len: usize,
+ pub(crate) buf: [u8; ffi::EVP_MAX_MD_SIZE as usize],
+ pub(crate) len: usize,
}
impl Clone for DigestBytes {
@@ -382,12 +404,10 @@ mod tests {
#[test]
fn test_sha256() {
- let tests = [
- (
- "616263",
- "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
- ),
- ];
+ let tests = [(
+ "616263",
+ "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
+ )];
for test in tests.iter() {
hash_test(MessageDigest::sha256(), test);
@@ -402,4 +422,12 @@ mod tests {
hash_test(MessageDigest::ripemd160(), test);
}
}
+
+ #[test]
+ fn from_nid() {
+ assert_eq!(
+ MessageDigest::from_nid(Nid::SHA256).unwrap().as_ptr(),
+ MessageDigest::sha256().as_ptr()
+ );
+ }
}
diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs
index a66a7743..d74ce65f 100644
--- a/openssl/src/lib.rs
+++ b/openssl/src/lib.rs
@@ -3,6 +3,8 @@
#[macro_use]
extern crate bitflags;
#[macro_use]
+extern crate cfg_if;
+#[macro_use]
extern crate foreign_types;
#[macro_use]
extern crate lazy_static;
@@ -53,8 +55,8 @@ pub mod pkcs5;
pub mod pkey;
pub mod rand;
pub mod rsa;
-pub mod sign;
pub mod sha;
+pub mod sign;
pub mod ssl;
pub mod stack;
pub mod string;
diff --git a/openssl/src/nid.rs b/openssl/src/nid.rs
index 7c041236..6f480254 100644
--- a/openssl/src/nid.rs
+++ b/openssl/src/nid.rs
@@ -1,6 +1,23 @@
//! A collection of numerical identifiers for OpenSSL objects.
use ffi;
-use libc::c_int;
+use libc::{c_char, c_int};
+
+use std::ffi::CStr;
+use std::str;
+
+use cvt_p;
+use error::ErrorStack;
+
+/// The digest and public-key algorithms associated with a signature.
+pub struct SignatureAlgorithms {
+ /// The signature's digest.
+ ///
+ /// If the signature does not specify a digest, this will be `NID::UNDEF`.
+ pub digest: Nid,
+
+ /// The signature's public-key.
+ pub pkey: Nid,
+}
/// A numerical identifier for an OpenSSL object.
///
@@ -42,6 +59,46 @@ impl Nid {
self.0
}
+ /// Returns the `Nid`s of the digest and public key algorithms associated with a signature ID.
+ ///
+ /// This corresponds to `OBJ_find_sigid_algs`.
+ pub fn signature_algorithms(&self) -> Option<SignatureAlgorithms> {
+ unsafe {
+ let mut digest = 0;
+ let mut pkey = 0;
+ if ffi::OBJ_find_sigid_algs(self.0, &mut digest, &mut pkey) == 1 {
+ Some(SignatureAlgorithms {
+ digest: Nid(digest),
+ pkey: Nid(pkey),
+ })
+ } else {
+ None
+ }
+ }
+ }
+
+ /// Return the string representation of a `Nid` (long)
+ /// This corresponds to [`OBJ_nid2ln`]
+ ///
+ /// [`OBJ_nid2ln`]: https://www.openssl.org/docs/man1.1.0/crypto/OBJ_nid2ln.html
+ pub fn long_name(&self) -> Result<&'static str, ErrorStack> {
+ unsafe {
+ cvt_p(ffi::OBJ_nid2ln(self.0) as *mut c_char)
+ .map(|nameptr| str::from_utf8(CStr::from_ptr(nameptr).to_bytes()).unwrap())
+ }
+ }
+
+ /// Return the string representation of a `Nid` (short)
+ /// This corresponds to [`OBJ_nid2sn`]
+ ///
+ /// [`OBJ_nid2sn`]: https://www.openssl.org/docs/man1.1.0/crypto/OBJ_nid2sn.html
+ pub fn short_name(&self) -> Result<&'static str, ErrorStack> {
+ unsafe {
+ cvt_p(ffi::OBJ_nid2sn(self.0) as *mut c_char)
+ .map(|nameptr| str::from_utf8(CStr::from_ptr(nameptr).to_bytes()).unwrap())
+ }
+ }
+
pub const UNDEF: Nid = Nid(ffi::NID_undef);
pub const ITU_T: Nid = Nid(ffi::NID_itu_t);
pub const CCITT: Nid = Nid(ffi::NID_ccitt);
@@ -991,3 +1048,73 @@ impl Nid {
pub const AES_192_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_192_cbc_hmac_sha1);
pub const AES_256_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_256_cbc_hmac_sha1);
}
+
+#[cfg(test)]
+mod test {
+ use super::Nid;
+
+ #[test]
+ fn signature_digest() {
+ let algs = Nid::SHA256WITHRSAENCRYPTION.signature_algorithms().unwrap();
+ assert_eq!(algs.digest, Nid::SHA256);
+ assert_eq!(algs.pkey, Nid::RSAENCRYPTION);
+ }
+
+ #[test]
+ fn test_long_name_conversion() {
+ let common_name = Nid::COMMONNAME;
+ let organizational_unit_name = Nid::ORGANIZATIONALUNITNAME;
+ let aes256_cbc_hmac_sha1 = Nid::AES_256_CBC_HMAC_SHA1;
+ let id_cmc_lrapopwitness = Nid::ID_CMC_LRAPOPWITNESS;
+ let ms_ctl_sign = Nid::MS_CTL_SIGN;
+ let undefined_nid = Nid::from_raw(118);
+
+ assert_eq!(common_name.long_name().unwrap(), "commonName");
+ assert_eq!(
+ organizational_unit_name.long_name().unwrap(),
+ "organizationalUnitName"
+ );
+ assert_eq!(
+ aes256_cbc_hmac_sha1.long_name().unwrap(),
+ "aes-256-cbc-hmac-sha1"
+ );
+ assert_eq!(
+ id_cmc_lrapopwitness.long_name().unwrap(),
+ "id-cmc-lraPOPWitness"
+ );
+ assert_eq!(
+ ms_ctl_sign.long_name().unwrap(),
+ "Microsoft Trust List Signing"
+ );
+ assert!(
+ undefined_nid.long_name().is_err(),
+ "undefined_nid should not return a valid value"
+ );
+ }
+
+ #[test]
+ fn test_short_name_conversion() {
+ let common_name = Nid::COMMONNAME;
+ let organizational_unit_name = Nid::ORGANIZATIONALUNITNAME;
+ let aes256_cbc_hmac_sha1 = Nid::AES_256_CBC_HMAC_SHA1;
+ let id_cmc_lrapopwitness = Nid::ID_CMC_LRAPOPWITNESS;
+ let ms_ctl_sign = Nid::MS_CTL_SIGN;
+ let undefined_nid = Nid::from_raw(118);
+
+ assert_eq!(common_name.short_name().unwrap(), "CN");
+ assert_eq!(organizational_unit_name.short_name().unwrap(), "OU");
+ assert_eq!(
+ aes256_cbc_hmac_sha1.short_name().unwrap(),
+ "AES-256-CBC-HMAC-SHA1"
+ );
+ assert_eq!(
+ id_cmc_lrapopwitness.short_name().unwrap(),
+ "id-cmc-lraPOPWitness"
+ );
+ assert_eq!(ms_ctl_sign.short_name().unwrap(), "msCTLSign");
+ assert!(
+ undefined_nid.short_name().is_err(),
+ "undefined_nid should not return a valid value"
+ );
+ }
+}
diff --git a/openssl/src/pkcs12.rs b/openssl/src/pkcs12.rs
index d71a1d82..b98848c8 100644
--- a/openssl/src/pkcs12.rs
+++ b/openssl/src/pkcs12.rs
@@ -3,15 +3,15 @@
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
-use std::ptr;
use std::ffi::CString;
+use std::ptr;
-use {cvt, cvt_p};
-use pkey::{HasPrivate, PKey, PKeyRef, Private};
use error::ErrorStack;
-use x509::{X509, X509Ref};
-use stack::Stack;
use nid::Nid;
+use pkey::{HasPrivate, PKey, PKeyRef, Private};
+use stack::Stack;
+use x509::{X509, X509Ref};
+use {cvt, cvt_p};
foreign_type_and_impl_send_sync! {
type CType = ffi::PKCS12;
@@ -172,7 +172,8 @@ impl Pkcs12Builder {
let friendly_name = CString::new(friendly_name).unwrap();
let pkey = pkey.as_ptr();
let cert = cert.as_ptr();
- let ca = self.ca
+ let ca = self
+ .ca
.as_ref()
.map(|ca| ca.as_ptr())
.unwrap_or(ptr::null_mut());
@@ -206,11 +207,11 @@ mod test {
use hex;
use asn1::Asn1Time;
- use rsa::Rsa;
- use pkey::PKey;
use nid::Nid;
- use x509::{X509, X509Name};
+ use pkey::PKey;
+ use rsa::Rsa;
use x509::extension::KeyUsage;
+ use x509::{X509, X509Name};
use super::*;
@@ -221,14 +222,14 @@ mod test {
let parsed = pkcs12.parse("mypass").unwrap();
assert_eq!(
- hex::encode(parsed.cert.fingerprint(MessageDigest::sha1()).unwrap()),
+ hex::encode(parsed.cert.digest(MessageDigest::sha1()).unwrap()),
"59172d9313e84459bcff27f967e79e6e9217e584"
);
let chain = parsed.chain.unwrap();
assert_eq!(chain.len(), 1);
assert_eq!(
- hex::encode(chain[0].fingerprint(MessageDigest::sha1()).unwrap()),
+ hex::encode(chain[0].digest(MessageDigest::sha1()).unwrap()),
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
);
}
@@ -279,8 +280,8 @@ mod test {
let parsed = pkcs12.parse("mypass").unwrap();
assert_eq!(
- parsed.cert.fingerprint(MessageDigest::sha1()).unwrap(),
- cert.fingerprint(MessageDigest::sha1()).unwrap()
+ &*parsed.cert.digest(MessageDigest::sha1()).unwrap(),
+ &*cert.digest(MessageDigest::sha1()).unwrap()
);
assert!(parsed.pkey.public_eq(&pkey));
}
diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs
index 0ad55b96..92a5799e 100644
--- a/openssl/src/rsa.rs
+++ b/openssl/src/rsa.rs
@@ -189,7 +189,8 @@ where
/// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn d(&self) -> &BigNumRef {
unsafe {
- let d = compat::key(self.as_ptr())[2];
+ let mut d = ptr::null();
+ RSA_get0_key(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut d);
BigNumRef::from_ptr(d as *mut _)
}
}
@@ -201,7 +202,8 @@ where
/// [`RSA_get0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn p(&self) -> Option<&BigNumRef> {
unsafe {
- let p = compat::factors(self.as_ptr())[0];
+ let mut p = ptr::null();
+ RSA_get0_factors(self.as_ptr(), &mut p, ptr::null_mut());
if p.is_null() {
None
} else {
@@ -217,7 +219,8 @@ where
/// [`RSA_get0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn q(&self) -> Option<&BigNumRef> {
unsafe {
- let q = compat::factors(self.as_ptr())[1];
+ let mut q = ptr::null();
+ RSA_get0_factors(self.as_ptr(), ptr::null_mut(), &mut q);
if q.is_null() {
None
} else {
@@ -233,7 +236,8 @@ where
/// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn dmp1(&self) -> Option<&BigNumRef> {
unsafe {
- let dp = compat::crt_params(self.as_ptr())[0];
+ let mut dp = ptr::null();
+ RSA_get0_crt_params(self.as_ptr(), &mut dp, ptr::null_mut(), ptr::null_mut());
if dp.is_null() {
None
} else {
@@ -249,7 +253,8 @@ where
/// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn dmq1(&self) -> Option<&BigNumRef> {
unsafe {
- let dq = compat::crt_params(self.as_ptr())[1];
+ let mut dq = ptr::null();
+ RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), &mut dq, ptr::null_mut());
if dq.is_null() {
None
} else {
@@ -265,7 +270,8 @@ where
/// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn iqmp(&self) -> Option<&BigNumRef> {
unsafe {
- let qi = compat::crt_params(self.as_ptr())[2];
+ let mut qi = ptr::null();
+ RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut qi);
if qi.is_null() {
None
} else {
@@ -391,7 +397,8 @@ where
/// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn n(&self) -> &BigNumRef {
unsafe {
- let n = compat::key(self.as_ptr())[0];
+ let mut n = ptr::null();
+ RSA_get0_key(self.as_ptr(), &mut n, ptr::null_mut(), ptr::null_mut());
BigNumRef::from_ptr(n as *mut _)
}
}
@@ -403,7 +410,8 @@ where
/// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn e(&self) -> &BigNumRef {
unsafe {
- let e = compat::key(self.as_ptr())[1];
+ let mut e = ptr::null();
+ RSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut e, ptr::null_mut());
BigNumRef::from_ptr(e as *mut _)
}
}
@@ -421,15 +429,10 @@ impl Rsa<Public> {
/// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html
pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> {
unsafe {
- let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?);
- cvt(compat::set_key(
- rsa.0,
- n.as_ptr(),
- e.as_ptr(),
- ptr::null_mut(),
- ))?;
+ let rsa = cvt_p(ffi::RSA_new())?;
+ RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), ptr::null_mut());
mem::forget((n, e));
- Ok(rsa)
+ Ok(Rsa::from_ptr(rsa))
}
}
@@ -498,10 +501,12 @@ impl RsaPrivateKeyBuilder {
/// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html
pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
unsafe {
- let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?);
- cvt(compat::set_key(rsa.0, n.as_ptr(), e.as_ptr(), d.as_ptr()))?;
+ let rsa = cvt_p(ffi::RSA_new())?;
+ RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), d.as_ptr());
mem::forget((n, e, d));
- Ok(RsaPrivateKeyBuilder { rsa })
+ Ok(RsaPrivateKeyBuilder {
+ rsa: Rsa::from_ptr(rsa),
+ })
}
}
@@ -512,9 +517,10 @@ impl RsaPrivateKeyBuilder {
/// This correspond to [`RSA_set0_factors`].
///
/// [`RSA_set0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_factors.html
+ // FIXME should be infallible
pub fn set_factors(self, p: BigNum, q: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
unsafe {
- cvt(compat::set_factors(self.rsa.0, p.as_ptr(), q.as_ptr()))?;
+ RSA_set0_factors(self.rsa.as_ptr(), p.as_ptr(), q.as_ptr());
mem::forget((p, q));
}
Ok(self)
@@ -528,6 +534,7 @@ impl RsaPrivateKeyBuilder {
/// This correspond to [`RSA_set0_crt_params`].
///
/// [`RSA_set0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_crt_params.html
+ // FIXME should be infallible
pub fn set_crt_params(
self,
dmp1: BigNum,
@@ -535,12 +542,12 @@ impl RsaPrivateKeyBuilder {
iqmp: BigNum,
) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
unsafe {
- cvt(compat::set_crt_params(
- self.rsa.0,
+ RSA_set0_crt_params(
+ self.rsa.as_ptr(),
dmp1.as_ptr(),
dmq1.as_ptr(),
iqmp.as_ptr(),
- ))?;
+ );
mem::forget((dmp1, dmq1, iqmp));
}
Ok(self)
@@ -637,89 +644,99 @@ impl<T> fmt::Debug for Rsa<T> {
}
}
-#[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 crt_params(r: *const RSA) -> [*const BIGNUM; 3] {
- let (mut dp, mut dq, mut qi) = (ptr::null(), ptr::null(), ptr::null());
- ffi::RSA_get0_crt_params(r, &mut dp, &mut dq, &mut qi);
- [dp, dq, qi]
- }
-
- 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 ffi::{BIGNUM, RSA};
- use libc::c_int;
-
- pub unsafe fn key(r: *const RSA) -> [*const BIGNUM; 3] {
- [(*r).n, (*r).e, (*r).d]
- }
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::{
+ RSA_get0_key, RSA_get0_factors, RSA_get0_crt_params, RSA_set0_key, RSA_set0_factors,
+ RSA_set0_crt_params,
+ };
+ } else {
+ #[allow(bad_style)]
+ unsafe fn RSA_get0_key(
+ r: *const ffi::RSA,
+ n: *mut *const ffi::BIGNUM,
+ e: *mut *const ffi::BIGNUM,
+ d: *mut *const ffi::BIGNUM,
+ ) {
+ if !n.is_null() {
+ *n = (*r).n;
+ }
+ if !e.is_null() {
+ *e = (*r).e;
+ }
+ if !d.is_null() {
+ *d = (*r).d;
+ }
+ }
- pub unsafe fn factors(r: *const RSA) -> [*const BIGNUM; 2] {
- [(*r).p, (*r).q]
- }
+ #[allow(bad_style)]
+ unsafe fn RSA_get0_factors(
+ r: *const ffi::RSA,
+ p: *mut *const ffi::BIGNUM,
+ q: *mut *const ffi::BIGNUM,
+ ) {
+ if !p.is_null() {
+ *p = (*r).p;
+ }
+ if !q.is_null() {
+ *q = (*r).q;
+ }
+ }
- pub unsafe fn crt_params(r: *const RSA) -> [*const BIGNUM; 3] {
- [(*r).dmp1, (*r).dmq1, (*r).iqmp]
- }
+ #[allow(bad_style)]
+ unsafe fn RSA_get0_crt_params(
+ r: *const ffi::RSA,
+ dmp1: *mut *const ffi::BIGNUM,
+ dmq1: *mut *const ffi::BIGNUM,
+ iqmp: *mut *const ffi::BIGNUM,
+ ) {
+ if !dmp1.is_null() {
+ *dmp1 = (*r).dmp1;
+ }
+ if !dmq1.is_null() {
+ *dmq1 = (*r).dmq1;
+ }
+ if !iqmp.is_null() {
+ *iqmp = (*r).iqmp;
+ }
+ }
- 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?
- }
+ #[allow(bad_style)]
+ unsafe fn RSA_set0_key(
+ r: *mut ffi::RSA,
+ n: *mut ffi::BIGNUM,
+ e: *mut ffi::BIGNUM,
+ d: *mut ffi::BIGNUM,
+ ) -> c_int {
+ (*r).n = n;
+ (*r).e = e;
+ (*r).d = d;
+ 1
+ }
- 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?
- }
+ #[allow(bad_style)]
+ unsafe fn RSA_set0_factors(
+ r: *mut ffi::RSA,
+ p: *mut ffi::BIGNUM,
+ q: *mut ffi::BIGNUM,
+ ) -> c_int {
+ (*r).p = p;
+ (*r).q = q;
+ 1
+ }
- 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?
+ #[allow(bad_style)]
+ unsafe fn RSA_set0_crt_params(
+ r: *mut ffi::RSA,
+ dmp1: *mut ffi::BIGNUM,
+ dmq1: *mut ffi::BIGNUM,
+ iqmp: *mut ffi::BIGNUM,
+ ) -> c_int {
+ (*r).dmp1 = dmp1;
+ (*r).dmq1 = dmq1;
+ (*r).iqmp = iqmp;
+ 1
+ }
}
}
@@ -751,7 +768,8 @@ mod test {
#[test]
fn test_to_password() {
let key = Rsa::generate(2048).unwrap();
- let pem = key.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
+ let pem = key
+ .private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
.unwrap();
Rsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
assert!(Rsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
@@ -791,7 +809,8 @@ mod test {
k0.private_encrypt(&msg, &mut emesg, Padding::PKCS1)
.unwrap();
let mut dmesg = vec![0; k1.size() as usize];
- let len = k1.public_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
+ let len = k1
+ .public_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
.unwrap();
assert_eq!(msg, &dmesg[..len]);
}
@@ -807,7 +826,8 @@ mod test {
let mut emesg = vec![0; k0.size() as usize];
k0.public_encrypt(&msg, &mut emesg, Padding::PKCS1).unwrap();
let mut dmesg = vec![0; k1.size() as usize];
- let len = k1.private_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
+ let len = k1
+ .private_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
.unwrap();
assert_eq!(msg, &dmesg[..len]);
}
@@ -883,6 +903,6 @@ mod test {
#[test]
fn clone() {
let key = Rsa::generate(2048).unwrap();
- key.clone();
+ drop(key.clone());
}
}
diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs
index c8032686..849831ed 100644
--- a/openssl/src/sign.rs
+++ b/openssl/src/sign.rs
@@ -63,21 +63,24 @@
//! ```
use ffi;
use foreign_types::ForeignTypeRef;
+use libc::c_int;
use std::io::{self, Write};
use std::marker::PhantomData;
use std::ptr;
-use libc::c_int;
-use {cvt, cvt_p};
+use error::ErrorStack;
use hash::MessageDigest;
use pkey::{HasPrivate, HasPublic, PKeyRef};
-use error::ErrorStack;
use rsa::Padding;
+use {cvt, cvt_p};
-#[cfg(ossl110)]
-use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
-#[cfg(any(ossl101, ossl102))]
-use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
+ } else {
+ use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
+ }
+}
/// Salt lengths that must be used with `set_rsa_pss_saltlen`.
pub struct RsaPssSaltlen(c_int);
@@ -459,7 +462,7 @@ impl<'a> Verifier<'a> {
pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
unsafe {
let r =
- EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len());
+ EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len());
match r {
1 => Ok(true),
0 => {
@@ -501,12 +504,12 @@ mod test {
use hex::{self, FromHex};
use std::iter;
- use hash::MessageDigest;
- use sign::{RsaPssSaltlen, Signer, Verifier};
use ec::{EcGroup, EcKey};
+ use hash::MessageDigest;
use nid::Nid;
- use rsa::{Padding, Rsa};
use pkey::PKey;
+ use rsa::{Padding, Rsa};
+ use sign::{RsaPssSaltlen, Signer, Verifier};
const INPUT: &'static str =
"65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
@@ -673,7 +676,7 @@ mod test {
signer.update(data as &[u8]).unwrap();
let expected = vec![
- 136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19
+ 136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19,
];
assert_eq!(signer.sign_to_vec().unwrap(), expected);
}
diff --git a/openssl/src/ssl/bio.rs b/openssl/src/ssl/bio.rs
index 4b792a75..1a149b6d 100644
--- a/openssl/src/ssl/bio.rs
+++ b/openssl/src/ssl/bio.rs
@@ -1,11 +1,13 @@
+use ffi::{
+ self, BIO_clear_retry_flags, BIO_new, BIO_set_retry_read, BIO_set_retry_write, BIO,
+ BIO_CTRL_FLUSH,
+};
use libc::{c_char, c_int, c_long, c_void, strlen};
-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;
use std::io::prelude::*;
use std::mem;
-use std::panic::{AssertUnwindSafe, catch_unwind};
+use std::panic::{catch_unwind, AssertUnwindSafe};
use std::ptr;
use std::slice;
@@ -19,11 +21,11 @@ pub struct StreamState<S> {
}
/// Safe wrapper for BIO_METHOD
-pub struct BioMethod(compat::BIO_METHOD);
+pub struct BioMethod(BIO_METHOD);
impl BioMethod {
fn new<S: Read + Write>() -> BioMethod {
- BioMethod(compat::BIO_METHOD::new::<S>())
+ BioMethod(BIO_METHOD::new::<S>())
}
}
@@ -41,8 +43,8 @@ pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, BioMethod), ErrorSta
unsafe {
let bio = cvt_p(BIO_new(method.0.get()))?;
- compat::BIO_set_data(bio, Box::into_raw(state) as *mut _);
- compat::BIO_set_init(bio, 1);
+ BIO_set_data(bio, Box::into_raw(state) as *mut _);
+ BIO_set_init(bio, 1);
return Ok((bio, method));
}
@@ -59,7 +61,7 @@ pub unsafe fn take_panic<S>(bio: *mut BIO) -> Option<Box<Any + Send>> {
}
pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S {
- let state: &'a StreamState<S> = mem::transmute(compat::BIO_get_data(bio));
+ let state: &'a StreamState<S> = mem::transmute(BIO_get_data(bio));
&state.stream
}
@@ -68,7 +70,7 @@ 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> {
- &mut *(compat::BIO_get_data(bio) as *mut _)
+ &mut *(BIO_get_data(bio) as *mut _)
}
unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int {
@@ -117,8 +119,7 @@ unsafe extern "C" fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int)
fn retriable_error(err: &io::Error) -> bool {
match err.kind() {
- io::ErrorKind::WouldBlock |
- io::ErrorKind::NotConnected => true,
+ io::ErrorKind::WouldBlock | io::ErrorKind::NotConnected => true,
_ => false,
}
}
@@ -153,10 +154,10 @@ unsafe extern "C" fn ctrl<S: Write>(
}
unsafe extern "C" 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);
+ BIO_set_init(bio, 0);
+ BIO_set_num(bio, 0);
+ BIO_set_data(bio, ptr::null_mut());
+ BIO_set_flags(bio, 0);
1
}
@@ -165,115 +166,110 @@ unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int {
return 0;
}
- let data = compat::BIO_get_data(bio);
+ let data = 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);
+ BIO_set_data(bio, ptr::null_mut());
+ 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(*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(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;
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::{BIO_get_data, BIO_set_data, BIO_set_flags, BIO_set_init};
+
+ #[allow(bad_style)]
+ unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
+
+ #[allow(bad_style)]
+ struct BIO_METHOD(*mut ffi::BIO_METHOD);
+
+ impl BIO_METHOD {
+ 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(ptr);
+ assert!(ffi::BIO_meth_set_write(ptr, bwrite::<S>) != 0);
+ assert!(ffi::BIO_meth_set_read(ptr, bread::<S>) != 0);
+ assert!(ffi::BIO_meth_set_puts(ptr, bputs::<S>) != 0);
+ assert!(ffi::BIO_meth_set_ctrl(ptr, ctrl::<S>) != 0);
+ assert!(ffi::BIO_meth_set_create(ptr, create) != 0);
+ assert!(ffi::BIO_meth_set_destroy(ptr, destroy::<S>) != 0);
+ return ret;
+ }
}
- }
-
- pub fn get(&self) -> *mut ffi::BIO_METHOD {
- self.0
- }
- }
- impl Drop for BIO_METHOD {
- fn drop(&mut self) {
- unsafe {
- ffi::BIO_meth_free(self.0);
+ fn get(&self) -> *mut ffi::BIO_METHOD {
+ self.0
}
}
- }
-}
-#[cfg(ossl10x)]
-#[allow(bad_style)]
-mod compat {
- use std::io::{Read, Write};
-
- use ffi;
- use libc::{c_int, c_void};
-
- pub struct BIO_METHOD(*mut ffi::BIO_METHOD);
-
- impl BIO_METHOD {
- pub fn new<S: Read + Write>() -> BIO_METHOD {
- let ptr = Box::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,
- });
-
- BIO_METHOD(Box::into_raw(ptr))
+ impl Drop for BIO_METHOD {
+ fn drop(&mut self) {
+ unsafe {
+ ffi::BIO_meth_free(self.0);
+ }
+ }
}
+ } else {
+ #[allow(bad_style)]
+ struct BIO_METHOD(*mut ffi::BIO_METHOD);
+
+ impl BIO_METHOD {
+ fn new<S: Read + Write>() -> BIO_METHOD {
+ let ptr = Box::new(ffi::BIO_METHOD {
+ type_: ffi::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,
+ });
+
+ BIO_METHOD(Box::into_raw(ptr))
+ }
- pub fn get(&self) -> *mut ffi::BIO_METHOD {
- self.0
+ fn get(&self) -> *mut ffi::BIO_METHOD {
+ self.0
+ }
}
- }
- impl Drop for BIO_METHOD {
- fn drop(&mut self) {
- unsafe {
- Box::<ffi::BIO_METHOD>::from_raw(self.0);
+ impl Drop for BIO_METHOD {
+ fn drop(&mut self) {
+ unsafe {
+ Box::<ffi::BIO_METHOD>::from_raw(self.0);
+ }
}
}
- }
- pub unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) {
- (*bio).init = init;
- }
+ #[allow(bad_style)]
+ 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;
- }
+ #[allow(bad_style)]
+ 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
- }
+ #[allow(bad_style)]
+ 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;
- }
+ #[allow(bad_style)]
+ 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;
+ #[allow(bad_style)]
+ unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) {
+ (*bio).num = num;
+ }
}
}
diff --git a/openssl/src/ssl/callbacks.rs b/openssl/src/ssl/callbacks.rs
index 887d450c..883befb8 100644
--- a/openssl/src/ssl/callbacks.rs
+++ b/openssl/src/ssl/callbacks.rs
@@ -1,9 +1,12 @@
use ffi;
use foreign_types::ForeignType;
use foreign_types::ForeignTypeRef;
+#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
+use libc::c_char;
#[cfg(ossl111)]
use libc::size_t;
-use libc::{c_char, c_int, c_uchar, c_uint, c_void};
+use libc::{c_int, c_uchar, c_uint, c_void};
+#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
use std::ffi::CStr;
use std::mem;
use std::ptr;
@@ -13,11 +16,11 @@ use std::str;
use std::sync::Arc;
use dh::Dh;
-#[cfg(any(ossl101, ossl102))]
+#[cfg(all(ossl101, not(ossl110)))]
use ec::EcKey;
use error::ErrorStack;
use pkey::Params;
-#[cfg(any(ossl102, ossl110))]
+#[cfg(any(ossl102, libressl261))]
use ssl::AlpnError;
#[cfg(ossl111)]
use ssl::ExtensionContext;
@@ -37,7 +40,8 @@ where
// raw pointer shenanigans to break the borrow of ctx
// the callback can't mess with its own ex_data slot so this is safe
- let verify = ctx.ex_data(ssl_idx)
+ let verify = ctx
+ .ex_data(ssl_idx)
.expect("BUG: store context missing ssl")
.ssl_context()
.ex_data(verify_idx)
@@ -66,7 +70,8 @@ where
let ssl = SslRef::from_ptr_mut(ssl);
let callback_idx = SslContext::cached_ex_index::<F>();
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(callback_idx)
.expect("BUG: psk callback missing") as *const F;
let hint = if hint != ptr::null() {
@@ -130,7 +135,8 @@ where
let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing");
let callback_idx = Ssl::cached_ex_index::<Arc<F>>();
- let callback = ctx.ex_data(ssl_idx)
+ let callback = ctx
+ .ex_data(ssl_idx)
.expect("BUG: store context missing ssl")
.ex_data(callback_idx)
.expect("BUG: ssl verify callback missing")
@@ -146,7 +152,8 @@ where
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: sni callback missing") as *const F;
let mut alert = SslAlert(*al);
@@ -160,7 +167,7 @@ where
}
}
-#[cfg(any(ossl102, ossl110))]
+#[cfg(any(ossl102, libressl261))]
pub extern "C" fn raw_alpn_select<F>(
ssl: *mut ffi::SSL,
out: *mut *const c_uchar,
@@ -174,7 +181,8 @@ where
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: alpn callback missing") as *const F;
let protos = slice::from_raw_parts(inbuf as *const u8, inlen as usize);
@@ -199,7 +207,8 @@ where
F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: tmp dh callback missing") as *const F;
@@ -216,7 +225,7 @@ where
}
}
-#[cfg(any(ossl101, ossl102))]
+#[cfg(all(ossl101, not(ossl110)))]
pub unsafe extern "C" fn raw_tmp_ecdh<F>(
ssl: *mut ffi::SSL,
is_export: c_int,
@@ -226,7 +235,8 @@ where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: tmp ecdh callback missing") as *const F;
@@ -252,7 +262,8 @@ where
F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ex_data(Ssl::cached_ex_index::<Arc<F>>())
+ let callback = ssl
+ .ex_data(Ssl::cached_ex_index::<Arc<F>>())
.expect("BUG: ssl tmp dh callback missing")
.clone();
@@ -269,7 +280,7 @@ where
}
}
-#[cfg(any(ossl101, ossl102))]
+#[cfg(all(ossl101, not(ossl110)))]
pub unsafe extern "C" fn raw_tmp_ecdh_ssl<F>(
ssl: *mut ffi::SSL,
is_export: c_int,
@@ -279,7 +290,8 @@ where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ex_data(Ssl::cached_ex_index::<Arc<F>>())
+ let callback = ssl
+ .ex_data(Ssl::cached_ex_index::<Arc<F>>())
.expect("BUG: ssl tmp ecdh callback missing")
.clone();
@@ -301,7 +313,8 @@ where
F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: ocsp callback missing") as *const F;
let ret = (*callback)(ssl);
@@ -335,7 +348,8 @@ where
F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: new session callback missing") as *const F;
let session = SslSession::from_ptr(session);
@@ -353,7 +367,8 @@ pub unsafe extern "C" fn raw_remove_session<F>(
F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send,
{
let ctx = SslContextRef::from_ptr(ctx);
- let callback = ctx.ex_data(SslContext::cached_ex_index::<F>())
+ let callback = ctx
+ .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: remove session callback missing");
let session = SslSessionRef::from_ptr(session);
@@ -375,7 +390,8 @@ where
F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: get session callback missing") as *const F;
let data = slice::from_raw_parts(data as *const u8, len as usize);
@@ -397,7 +413,8 @@ where
F: Fn(&SslRef, &str) + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr(ssl as *mut _);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: get session callback missing");
let line = CStr::from_ptr(line).to_bytes();
@@ -416,7 +433,8 @@ where
F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: stateless cookie generate callback missing") as *const F;
let slice = slice::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize);
@@ -442,7 +460,8 @@ where
F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: stateless cookie verify callback missing") as *const F;
let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize);
@@ -459,7 +478,8 @@ where
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: cookie generate callback missing") as *const F;
// We subtract 1 from DTLS1_COOKIE_LENGTH as the ostensible value, 256, is erroneous but retained for
@@ -495,7 +515,8 @@ where
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: cookie verify callback missing") as *const F;
let slice =
@@ -528,7 +549,8 @@ where
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: custom ext add callback missing") as *const F;
let ectx = ExtensionContext::from_bits_truncate(context);
@@ -604,7 +626,8 @@ where
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
- let callback = ssl.ssl_context()
+ let callback = ssl
+ .ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: custom ext parse callback missing") as *const F;
let ectx = ExtensionContext::from_bits_truncate(context);
diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs
index 9966a5a0..f10a0e23 100644
--- a/openssl/src/ssl/connector.rs
+++ b/openssl/src/ssl/connector.rs
@@ -3,16 +3,22 @@ use std::ops::{Deref, DerefMut};
use dh::Dh;
use error::ErrorStack;
-use ssl::{HandshakeError, Ssl, SslContext, SslContextBuilder, SslMethod, SslMode, SslOptions,
- SslRef, SslStream, SslVerifyMode};
+use ssl::{
+ HandshakeError, Ssl, SslContext, SslContextBuilder, SslMethod, SslMode, SslOptions, SslRef,
+ SslStream, SslVerifyMode,
+};
use version;
fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
let mut ctx = SslContextBuilder::new(method)?;
- let mut opts = SslOptions::ALL | SslOptions::NO_COMPRESSION | SslOptions::NO_SSLV2
- | SslOptions::NO_SSLV3 | SslOptions::SINGLE_DH_USE
- | SslOptions::SINGLE_ECDH_USE | SslOptions::CIPHER_SERVER_PREFERENCE;
+ let mut opts = SslOptions::ALL
+ | SslOptions::NO_COMPRESSION
+ | SslOptions::NO_SSLV2
+ | SslOptions::NO_SSLV3
+ | SslOptions::SINGLE_DH_USE
+ | SslOptions::SINGLE_ECDH_USE
+ | SslOptions::CIPHER_SERVER_PREFERENCE;
opts &= !SslOptions::DONT_INSERT_EMPTY_FRAGMENTS;
ctx.set_options(opts);
@@ -23,7 +29,7 @@ fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
// This is quite a useful optimization for saving memory, but historically
// caused CVEs in OpenSSL pre-1.0.1h, according to
// https://bugs.python.org/issue25672
- if version::number() >= 0x1000108f {
+ if version::number() >= 0x1_00_01_08_0 {
mode |= SslMode::RELEASE_BUFFERS;
}
@@ -277,226 +283,228 @@ impl DerefMut for SslAcceptorBuilder {
}
}
-#[cfg(ossl101)]
-fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
- use ec::EcKey;
- use nid::Nid;
-
- let curve = EcKey::from_curve_name(Nid::X9_62_PRIME256V1)?;
- ctx.set_tmp_ecdh(&curve)
-}
-
-#[cfg(ossl102)]
-fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
- ctx.set_ecdh_auto(true)
-}
-
-#[cfg(ossl110)]
-fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> {
- Ok(())
-}
-
-#[cfg(any(ossl102, ossl110))]
-fn setup_verify(ctx: &mut SslContextBuilder) {
- ctx.set_verify(SslVerifyMode::PEER);
-}
-
-#[cfg(ossl101)]
-fn setup_verify(ctx: &mut SslContextBuilder) {
- ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback);
-}
-
-#[cfg(any(ossl102, ossl110))]
-fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
- use x509::verify::X509CheckFlags;
+cfg_if! {
+ if #[cfg(ossl110)] {
+ fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> {
+ Ok(())
+ }
+ } else if #[cfg(any(ossl102, libressl))] {
+ fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
+ ctx.set_ecdh_auto(true)
+ }
+ } else {
+ fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
+ use ec::EcKey;
+ use nid::Nid;
- let param = ssl.param_mut();
- param.set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS);
- match domain.parse() {
- Ok(ip) => param.set_ip(ip),
- Err(_) => param.set_host(domain),
+ let curve = EcKey::from_curve_name(Nid::X9_62_PRIME256V1)?;
+ ctx.set_tmp_ecdh(&curve)
+ }
}
}
-#[cfg(ossl101)]
-fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
- let domain = domain.to_string();
- ssl.set_ex_data(*verify::HOSTNAME_IDX, domain);
- Ok(())
-}
-
-#[cfg(ossl101)]
-mod verify {
- use std::net::IpAddr;
- use std::str;
-
- use ex_data::Index;
- use nid::Nid;
- use x509::{GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef,
- X509VerifyResult};
- use stack::Stack;
- use ssl::Ssl;
+cfg_if! {
+ if #[cfg(any(ossl102, libressl261))] {
+ fn setup_verify(ctx: &mut SslContextBuilder) {
+ ctx.set_verify(SslVerifyMode::PEER);
+ }
- lazy_static! {
- pub static ref HOSTNAME_IDX: Index<Ssl, String> = Ssl::new_ex_index().unwrap();
- }
+ fn setup_verify_hostname(ssl: &mut SslRef, domain: &str) -> Result<(), ErrorStack> {
+ use x509::verify::X509CheckFlags;
- pub fn verify_callback(preverify_ok: bool, x509_ctx: &mut X509StoreContextRef) -> bool {
- if !preverify_ok || x509_ctx.error_depth() != 0 {
- return preverify_ok;
+ let param = ssl.param_mut();
+ param.set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS);
+ match domain.parse() {
+ Ok(ip) => param.set_ip(ip),
+ Err(_) => param.set_host(domain),
+ }
+ }
+ } else {
+ fn setup_verify(ctx: &mut SslContextBuilder) {
+ ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback);
}
- let ok = match (
- x509_ctx.current_cert(),
- X509StoreContext::ssl_idx()
- .ok()
- .and_then(|idx| x509_ctx.ex_data(idx))
- .and_then(|ssl| ssl.ex_data(*HOSTNAME_IDX)),
- ) {
- (Some(x509), Some(domain)) => verify_hostname(domain, &x509),
- _ => true,
- };
-
- if !ok {
- x509_ctx.set_error(X509VerifyResult::APPLICATION_VERIFICATION);
+ fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
+ let domain = domain.to_string();
+ ssl.set_ex_data(*verify::HOSTNAME_IDX, domain);
+ Ok(())
}
- ok
- }
+ mod verify {
+ use std::net::IpAddr;
+ use std::str;
+
+ use ex_data::Index;
+ use nid::Nid;
+ use ssl::Ssl;
+ use stack::Stack;
+ use x509::{
+ GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef,
+ X509VerifyResult,
+ };
+
+ lazy_static! {
+ pub static ref HOSTNAME_IDX: Index<Ssl, String> = Ssl::new_ex_index().unwrap();
+ }
- fn verify_hostname(domain: &str, cert: &X509Ref) -> bool {
- match cert.subject_alt_names() {
- Some(names) => verify_subject_alt_names(domain, names),
- None => verify_subject_name(domain, &cert.subject_name()),
- }
- }
+ pub fn verify_callback(preverify_ok: bool, x509_ctx: &mut X509StoreContextRef) -> bool {
+ if !preverify_ok || x509_ctx.error_depth() != 0 {
+ return preverify_ok;
+ }
+
+ let ok = match (
+ x509_ctx.current_cert(),
+ X509StoreContext::ssl_idx()
+ .ok()
+ .and_then(|idx| x509_ctx.ex_data(idx))
+ .and_then(|ssl| ssl.ex_data(*HOSTNAME_IDX)),
+ ) {
+ (Some(x509), Some(domain)) => verify_hostname(domain, &x509),
+ _ => true,
+ };
- fn verify_subject_alt_names(domain: &str, names: Stack<GeneralName>) -> bool {
- let ip = domain.parse();
+ if !ok {
+ x509_ctx.set_error(X509VerifyResult::APPLICATION_VERIFICATION);
+ }
+
+ ok
+ }
- for name in &names {
- match ip {
- Ok(ip) => {
- if let Some(actual) = name.ipaddress() {
- if matches_ip(&ip, actual) {
- return true;
+ fn verify_hostname(domain: &str, cert: &X509Ref) -> bool {
+ match cert.subject_alt_names() {
+ Some(names) => verify_subject_alt_names(domain, names),
+ None => verify_subject_name(domain, &cert.subject_name()),
+ }
+ }
+
+ fn verify_subject_alt_names(domain: &str, names: Stack<GeneralName>) -> bool {
+ let ip = domain.parse();
+
+ for name in &names {
+ match ip {
+ Ok(ip) => {
+ if let Some(actual) = name.ipaddress() {
+ if matches_ip(&ip, actual) {
+ return true;
+ }
+ }
+ }
+ Err(_) => {
+ if let Some(pattern) = name.dnsname() {
+ if matches_dns(pattern, domain) {
+ return true;
+ }
+ }
}
}
}
- Err(_) => {
- if let Some(pattern) = name.dnsname() {
- if matches_dns(pattern, domain) {
- return true;
+
+ false
+ }
+
+ fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool {
+ match subject_name.entries_by_nid(Nid::COMMONNAME).next() {
+ Some(pattern) => {
+ let pattern = match str::from_utf8(pattern.data().as_slice()) {
+ Ok(pattern) => pattern,
+ Err(_) => return false,
+ };
+
+ // Unlike SANs, IP addresses in the subject name don't have a
+ // different encoding.
+ match domain.parse::<IpAddr>() {
+ Ok(ip) => pattern
+ .parse::<IpAddr>()
+ .ok()
+ .map_or(false, |pattern| pattern == ip),
+ Err(_) => matches_dns(pattern, domain),
}
}
+ None => false,
}
}
- }
- false
- }
-
- fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool {
- match subject_name.entries_by_nid(Nid::COMMONNAME).next() {
- Some(pattern) => {
- let pattern = match str::from_utf8(pattern.data().as_slice()) {
- Ok(pattern) => pattern,
- Err(_) => return false,
- };
-
- // Unlike SANs, IP addresses in the subject name don't have a
- // different encoding.
- match domain.parse::<IpAddr>() {
- Ok(ip) => pattern
- .parse::<IpAddr>()
- .ok()
- .map_or(false, |pattern| pattern == ip),
- Err(_) => matches_dns(pattern, domain),
+ fn matches_dns(mut pattern: &str, mut hostname: &str) -> bool {
+ // first strip trailing . off of pattern and hostname to normalize
+ if pattern.ends_with('.') {
+ pattern = &pattern[..pattern.len() - 1];
}
+ if hostname.ends_with('.') {
+ hostname = &hostname[..hostname.len() - 1];
+ }
+
+ matches_wildcard(pattern, hostname).unwrap_or_else(|| pattern == hostname)
}
- None => false,
- }
- }
- fn matches_dns(mut pattern: &str, mut hostname: &str) -> bool {
- // first strip trailing . off of pattern and hostname to normalize
- if pattern.ends_with('.') {
- pattern = &pattern[..pattern.len() - 1];
- }
- if hostname.ends_with('.') {
- hostname = &hostname[..hostname.len() - 1];
- }
+ fn matches_wildcard(pattern: &str, hostname: &str) -> Option<bool> {
+ // internationalized domains can't involved in wildcards
+ if pattern.starts_with("xn--") {
+ return None;
+ }
- matches_wildcard(pattern, hostname).unwrap_or_else(|| pattern == hostname)
- }
+ let wildcard_location = match pattern.find('*') {
+ Some(l) => l,
+ None => return None,
+ };
- fn matches_wildcard(pattern: &str, hostname: &str) -> Option<bool> {
- // internationalized domains can't involved in wildcards
- if pattern.starts_with("xn--") {
- return None;
- }
+ let mut dot_idxs = pattern.match_indices('.').map(|(l, _)| l);
+ let wildcard_end = match dot_idxs.next() {
+ Some(l) => l,
+ None => return None,
+ };
- let wildcard_location = match pattern.find('*') {
- Some(l) => l,
- None => return None,
- };
-
- let mut dot_idxs = pattern.match_indices('.').map(|(l, _)| l);
- let wildcard_end = match dot_idxs.next() {
- Some(l) => l,
- None => return None,
- };
-
- // Never match wildcards if the pattern has less than 2 '.'s (no *.com)
- //
- // This is a bit dubious, as it doesn't disallow other TLDs like *.co.uk.
- // Chrome has a black- and white-list for this, but Firefox (via NSS) does
- // the same thing we do here.
- //
- // The Public Suffix (https://www.publicsuffix.org/) list could
- // potentially be used here, but it's both huge and updated frequently
- // enough that management would be a PITA.
- if dot_idxs.next().is_none() {
- return None;
- }
+ // Never match wildcards if the pattern has less than 2 '.'s (no *.com)
+ //
+ // This is a bit dubious, as it doesn't disallow other TLDs like *.co.uk.
+ // Chrome has a black- and white-list for this, but Firefox (via NSS) does
+ // the same thing we do here.
+ //
+ // The Public Suffix (https://www.publicsuffix.org/) list could
+ // potentially be used here, but it's both huge and updated frequently
+ // enough that management would be a PITA.
+ if dot_idxs.next().is_none() {
+ return None;
+ }
- // Wildcards can only be in the first component
- if wildcard_location > wildcard_end {
- return None;
- }
+ // Wildcards can only be in the first component
+ if wildcard_location > wildcard_end {
+ return None;
+ }
- let hostname_label_end = match hostname.find('.') {
- Some(l) => l,
- None => return None,
- };
+ let hostname_label_end = match hostname.find('.') {
+ Some(l) => l,
+ None => return None,
+ };
- // check that the non-wildcard parts are identical
- if pattern[wildcard_end..] != hostname[hostname_label_end..] {
- return Some(false);
- }
+ // check that the non-wildcard parts are identical
+ if pattern[wildcard_end..] != hostname[hostname_label_end..] {
+ return Some(false);
+ }
- let wildcard_prefix = &pattern[..wildcard_location];
- let wildcard_suffix = &pattern[wildcard_location + 1..wildcard_end];
+ let wildcard_prefix = &pattern[..wildcard_location];
+ let wildcard_suffix = &pattern[wildcard_location + 1..wildcard_end];
- let hostname_label = &hostname[..hostname_label_end];
+ let hostname_label = &hostname[..hostname_label_end];
- // check the prefix of the first label
- if !hostname_label.starts_with(wildcard_prefix) {
- return Some(false);
- }
+ // check the prefix of the first label
+ if !hostname_label.starts_with(wildcard_prefix) {
+ return Some(false);
+ }
- // and the suffix
- if !hostname_label[wildcard_prefix.len()..].ends_with(wildcard_suffix) {
- return Some(false);
- }
+ // and the suffix
+ if !hostname_label[wildcard_prefix.len()..].ends_with(wildcard_suffix) {
+ return Some(false);
+ }
- Some(true)
- }
+ Some(true)
+ }
- fn matches_ip(expected: &IpAddr, actual: &[u8]) -> bool {
- match *expected {
- IpAddr::V4(ref addr) => actual == addr.octets(),
- IpAddr::V6(ref addr) => actual == addr.octets(),
+ fn matches_ip(expected: &IpAddr, actual: &[u8]) -> bool {
+ match *expected {
+ IpAddr::V4(ref addr) => actual == addr.octets(),
+ IpAddr::V6(ref addr) => actual == addr.octets(),
+ }
+ }
}
}
}
diff --git a/openssl/src/ssl/error.rs b/openssl/src/ssl/error.rs
index 18e44cd6..b7e29c15 100644
--- a/openssl/src/ssl/error.rs
+++ b/openssl/src/ssl/error.rs
@@ -99,17 +99,18 @@ impl fmt::Display for Error {
Some(_) => fmt.write_str("a nonblocking read call would have blocked"),
None => fmt.write_str("the operation should be retried"),
},
+ ErrorCode::WANT_WRITE => match self.io_error() {
+ Some(_) => fmt.write_str("a nonblocking write call would have blocked"),
+ None => fmt.write_str("the operation should be retried"),
+ },
ErrorCode::SYSCALL => match self.io_error() {
- Some(err) => write!(fmt, "the inner stream returned an error: {}", err),
+ Some(err) => write!(fmt, "{}", err),
None => fmt.write_str("unexpected EOF"),
},
- ErrorCode::SSL => {
- fmt.write_str("OpenSSL error")?;
- if let Some(ref err) = self.ssl_error() {
- write!(fmt, ": {}", err)?
- }
- Ok(())
- }
+ ErrorCode::SSL => match self.ssl_error() {
+ Some(e) => write!(fmt, "{}", e),
+ None => fmt.write_str("OpenSSL error"),
+ },
ErrorCode(code) => write!(fmt, "unknown error code {}", code),
}
}
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index 37f5086c..b69247db 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -78,23 +78,24 @@ use std::str;
use std::sync::{Arc, Mutex};
use dh::{Dh, DhRef};
-#[cfg(any(ossl101, ossl102))]
+#[cfg(all(ossl101, not(ossl110)))]
use ec::EcKey;
use ec::EcKeyRef;
use error::ErrorStack;
use ex_data::Index;
#[cfg(ossl111)]
use hash::MessageDigest;
+#[cfg(ossl110)]
use nid::Nid;
use pkey::{HasPrivate, PKeyRef, Params, Private};
use ssl::bio::BioMethod;
use ssl::callbacks::*;
use ssl::error::InnerError;
use stack::{Stack, StackRef};
-#[cfg(any(ossl102, ossl110))]
+#[cfg(ossl102)]
use x509::store::X509Store;
use x509::store::{X509StoreBuilderRef, X509StoreRef};
-#[cfg(any(ossl102, ossl110))]
+#[cfg(any(ossl102, libressl261))]
use x509::verify::X509VerifyParamRef;
use x509::{X509, X509Name, X509Ref, X509StoreContextRef, X509VerifyResult};
use {cvt, cvt_n, cvt_p, init};
@@ -284,7 +285,7 @@ impl SslMethod {
/// This corresponds to `TLS_method` on OpenSSL 1.1.0 and `SSLv23_method`
/// on OpenSSL 1.0.x.
pub fn tls() -> SslMethod {
- SslMethod(compat::tls_method())
+ unsafe { SslMethod(TLS_method()) }
}
/// Support all versions of the DTLS protocol.
@@ -292,7 +293,7 @@ impl SslMethod {
/// This corresponds to `DTLS_method` on OpenSSL 1.1.0 and `DTLSv1_method`
/// on OpenSSL 1.0.x.
pub fn dtls() -> SslMethod {
- SslMethod(compat::dtls_method())
+ unsafe { SslMethod(DTLS_method()) }
}
/// Constructs an `SslMethod` from a pointer to the underlying OpenSSL value.
@@ -506,12 +507,12 @@ impl SslAlert {
/// An error returned from an ALPN selection callback.
///
-/// Requires OpenSSL 1.0.2 or newer.
-#[cfg(any(ossl102, ossl110))]
+/// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer.
+#[cfg(any(ossl102, libressl261))]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct AlpnError(c_int);
-#[cfg(any(ossl102, ossl110))]
+#[cfg(any(ossl102, libressl261))]
impl AlpnError {
/// Terminate the handshake with a fatal alert.
///
@@ -767,7 +768,7 @@ impl SslContextBuilder {
/// Requires OpenSSL 1.0.1 or 1.0.2.
///
/// This corresponds to `SSL_CTX_set_tmp_ecdh_callback`.
- #[cfg(any(ossl101, ossl102))]
+ #[cfg(all(ossl101, not(ossl110)))]
pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F)
where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
@@ -976,7 +977,7 @@ impl SslContextBuilder {
/// This corresponds to [`SSL_CTX_set_ecdh_auto`].
///
/// [`SSL_CTX_set_ecdh_auto`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_ecdh_auto.html
- #[cfg(any(ossl102, libressl))]
+ #[cfg(any(libressl, all(ossl102, not(ossl110))))]
pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_CTX_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) }
}
@@ -992,7 +993,7 @@ impl SslContextBuilder {
///
/// [`SSL_CTX_set_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html
pub fn set_options(&mut self, option: SslOptions) -> SslOptions {
- let bits = unsafe { compat::SSL_CTX_set_options(self.as_ptr(), option.bits()) };
+ let bits = unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits()) };
SslOptions { bits }
}
@@ -1002,7 +1003,7 @@ impl SslContextBuilder {
///
/// [`SSL_CTX_get_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html
pub fn options(&self) -> SslOptions {
- let bits = unsafe { compat::SSL_CTX_get_options(self.as_ptr()) };
+ let bits = unsafe { ffi::SSL_CTX_get_options(self.as_ptr()) };
SslOptions { bits }
}
@@ -1012,7 +1013,7 @@ impl SslContextBuilder {
///
/// [`SSL_CTX_clear_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html
pub fn clear_options(&mut self, option: SslOptions) -> SslOptions {
- let bits = unsafe { compat::SSL_CTX_clear_options(self.as_ptr(), option.bits()) };
+ let bits = unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits()) };
SslOptions { bits }
}
@@ -1023,15 +1024,15 @@ impl SslContextBuilder {
///
/// This corresponds to [`SSL_CTX_set_min_proto_version`].
///
- /// Requires OpenSSL 1.1.0 or newer.
+ /// Requires OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer.
///
/// [`SSL_CTX_set_min_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html
- #[cfg(any(ossl110))]
+ #[cfg(any(ossl110, libressl261))]
pub fn set_min_proto_version(&mut self, version: Option<SslVersion>) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::SSL_CTX_set_min_proto_version(
self.as_ptr(),
- version.map_or(0, |v| v.0),
+ version.map_or(0, |v| v.0 as _),
)).map(|_| ())
}
}
@@ -1043,15 +1044,15 @@ impl SslContextBuilder {
///
/// This corresponds to [`SSL_CTX_set_max_proto_version`].
///
- /// Requires OpenSSL 1.1.0 or newer.
+ /// Requires OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer.
///
/// [`SSL_CTX_set_max_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html
- #[cfg(any(ossl110))]
+ #[cfg(any(ossl110, libressl261))]
pub fn set_max_proto_version(&mut self, version: Option<SslVersion>) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::SSL_CTX_set_max_proto_version(
self.as_ptr(),
- version.map_or(0, |v| v.0),
+ version.map_or(0, |v| v.0 as _),
)).map(|_| ())
}
}
@@ -1063,10 +1064,10 @@ impl SslContextBuilder {
///
/// This corresponds to [`SSL_CTX_get_min_proto_version`].
///
- /// Requires OpenSSL 1.1.0g or newer.
+ /// Requires OpenSSL 1.1.0g or LibreSSL 2.7.0 or newer.
///
/// [`SSL_CTX_get_min_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html
- #[cfg(any(ossl110g))]
+ #[cfg(any(ossl110g, libressl270))]
pub fn min_proto_version(&mut self) -> Option<SslVersion> {
unsafe {
let r = ffi::SSL_CTX_get_min_proto_version(self.as_ptr());
@@ -1085,10 +1086,10 @@ impl SslContextBuilder {
///
/// This corresponds to [`SSL_CTX_get_max_proto_version`].
///
- /// Requires OpenSSL 1.1.0g or newer.
+ /// Requires OpenSSL 1.1.0g or LibreSSL 2.7.0 or newer.
///
/// [`SSL_CTX_get_max_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html
- #[cfg(any(ossl110g))]
+ #[cfg(any(ossl110g, libressl270))]
pub fn max_proto_version(&mut self) -> Option<SslVersion> {
unsafe {
let r = ffi::SSL_CTX_get_max_proto_version(self.as_ptr());
@@ -1109,10 +1110,10 @@ impl SslContextBuilder {
///
/// This corresponds to [`SSL_CTX_set_alpn_protos`].
///
- /// Requires OpenSSL 1.0.2 or newer.
+ /// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer.
///
/// [`SSL_CTX_set_alpn_protos`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_alpn_protos.html
- #[cfg(any(ossl102, ossl110))]
+ #[cfg(any(ossl102, libressl261))]
pub fn set_alpn_protos(&mut self, protocols: &[u8]) -> Result<(), ErrorStack> {
unsafe {
assert!(protocols.len() <= c_uint::max_value() as usize);
@@ -1140,12 +1141,12 @@ impl SslContextBuilder {
///
/// This corresponds to [`SSL_CTX_set_alpn_select_cb`].
///
- /// Requires OpenSSL 1.0.2 or newer.
+ /// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer.
///
/// [`SslContextBuilder::set_alpn_protos`]: struct.SslContextBuilder.html#method.set_alpn_protos
/// [`select_next_proto`]: fn.select_next_proto.html
/// [`SSL_CTX_set_alpn_select_cb`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_alpn_protos.html
- #[cfg(any(ossl102, ossl110))]
+ #[cfg(any(ossl102, libressl261))]
pub fn set_alpn_select_callback<F>(&mut self, callback: F)
where
F: for<'a> Fn(&mut SslRef, &'a [u8]) -> Result<&'a [u8], AlpnError> + 'static + Sync + Send,
@@ -1512,6 +1513,24 @@ impl SslContextBuilder {
}
}
+ /// Sets the maximum amount of early data that will be accepted on incoming connections.
+ ///
+ /// Defaults to 0.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_CTX_set_max_early_data`].
+ ///
+ /// [`SSL_CTX_set_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_max_early_data.html
+ #[cfg(ossl111)]
+ pub fn set_max_early_data(&mut self, bytes: u32) -> Result<(), ErrorStack> {
+ if unsafe { ffi::SSL_CTX_set_max_early_data(self.as_ptr(), bytes) } == 1 {
+ Ok(())
+ } else {
+ Err(ErrorStack::get())
+ }
+ }
+
/// Consumes the builder, returning a new `SslContext`.
pub fn build(self) -> SslContext {
self.0
@@ -1537,7 +1556,7 @@ foreign_type_and_impl_send_sync! {
impl Clone for SslContext {
fn clone(&self) -> Self {
unsafe {
- compat::SSL_CTX_up_ref(self.as_ptr());
+ SSL_CTX_up_ref(self.as_ptr());
SslContext::from_ptr(self.as_ptr())
}
}
@@ -1570,7 +1589,7 @@ impl SslContext {
{
unsafe {
ffi::init();
- let idx = cvt_n(compat::get_new_idx(free_data_box::<T>))?;
+ let idx = cvt_n(get_new_idx(free_data_box::<T>))?;
Ok(Index::from_raw(idx))
}
}
@@ -1666,6 +1685,18 @@ impl SslContextRef {
}
}
}
+
+ /// Gets the maximum amount of early data that will be accepted on incoming connections.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_CTX_get_max_early_data`].
+ ///
+ /// [`SSL_CTX_get_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_get_max_early_data.html
+ #[cfg(ossl111)]
+ pub fn max_early_data(&self) -> u32 {
+ unsafe { ffi::SSL_CTX_get_max_early_data(self.as_ptr()) }
+ }
}
/// Information about the state of a cipher.
@@ -1814,7 +1845,7 @@ impl SslCipherRef {
}
}
-foreign_type! {
+foreign_type_and_impl_send_sync! {
type CType = ffi::SSL_SESSION;
fn drop = ffi::SSL_SESSION_free;
@@ -1829,9 +1860,6 @@ foreign_type! {
pub struct SslSessionRef;
}
-unsafe impl Sync for SslSession {}
-unsafe impl Send for SslSession {}
-
impl Clone for SslSession {
fn clone(&self) -> SslSession {
SslSessionRef::to_owned(self)
@@ -1856,7 +1884,7 @@ impl ToOwned for SslSessionRef {
fn to_owned(&self) -> SslSession {
unsafe {
- compat::SSL_SESSION_up_ref(self.as_ptr());
+ SSL_SESSION_up_ref(self.as_ptr());
SslSession(self.as_ptr())
}
}
@@ -1882,7 +1910,7 @@ impl SslSessionRef {
///
/// [`SSL_SESSION_get_master_key`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_SESSION_get_master_key.html
pub fn master_key_len(&self) -> usize {
- unsafe { compat::SSL_SESSION_get_master_key(self.as_ptr(), ptr::null_mut(), 0) }
+ unsafe { SSL_SESSION_get_master_key(self.as_ptr(), ptr::null_mut(), 0) }
}
/// Copies the master key into the provided buffer.
@@ -1893,7 +1921,19 @@ impl SslSessionRef {
///
/// [`SSL_SESSION_get_master_key`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_SESSION_get_master_key.html
pub fn master_key(&self, buf: &mut [u8]) -> usize {
- unsafe { compat::SSL_SESSION_get_master_key(self.as_ptr(), buf.as_mut_ptr(), buf.len()) }
+ unsafe { SSL_SESSION_get_master_key(self.as_ptr(), buf.as_mut_ptr(), buf.len()) }
+ }
+
+ /// Gets the maximum amount of early data that can be sent on this session.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_SESSION_get_max_early_data`].
+ ///
+ /// [`SSL_SESSION_get_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_SESSION_get_max_early_data.html
+ #[cfg(ossl111)]
+ pub fn max_early_data(&self) -> u32 {
+ unsafe { ffi::SSL_SESSION_get_max_early_data(self.as_ptr()) }
}
to_der! {
@@ -1907,7 +1947,7 @@ impl SslSessionRef {
}
}
-foreign_type! {
+foreign_type_and_impl_send_sync! {
type CType = ffi::SSL;
fn drop = ffi::SSL_free;
@@ -1925,9 +1965,6 @@ foreign_type! {
pub struct SslRef;
}
-unsafe impl Sync for Ssl {}
-unsafe impl Send for Ssl {}
-
impl fmt::Debug for Ssl {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, fmt)
@@ -1949,7 +1986,7 @@ impl Ssl {
{
unsafe {
ffi::init();
- let idx = cvt_n(compat::get_new_ssl_idx(free_data_box::<T>))?;
+ let idx = cvt_n(get_new_ssl_idx(free_data_box::<T>))?;
Ok(Index::from_raw(idx))
}
}
@@ -2114,7 +2151,7 @@ impl SslRef {
/// This corresponds to `SSL_set_tmp_ecdh_callback`.
///
/// [`SslContextBuilder::set_tmp_ecdh_callback`]: struct.SslContextBuilder.html#method.set_tmp_ecdh_callback
- #[cfg(any(ossl101, ossl102))]
+ #[cfg(any(all(ossl101, not(ossl110))))]
pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F)
where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
@@ -2134,7 +2171,7 @@ impl SslRef {
///
/// [`SslContextBuilder::set_tmp_ecdh`]: struct.SslContextBuilder.html#method.set_tmp_ecdh
/// [`SSL_set_ecdh_auto`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_set_ecdh_auto.html
- #[cfg(ossl102)]
+ #[cfg(all(ossl102, not(ossl110)))]
pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) }
}
@@ -2234,6 +2271,30 @@ impl SslRef {
}
}
+ /// Returns the verified certificate chani of the peer, including the leaf certificate.
+ ///
+ /// If verification was not successful (i.e. [`verify_result`] does not return
+ /// [`X509VerifyResult::OK`]), this chain may be incomplete or invalid.
+ ///
+ /// Requires OpenSSL 1.1.0 or newer.
+ ///
+ /// This corresponds to [`SSL_get0_verified_chain`].
+ ///
+ /// [`verify_result`]: #method.verify_result
+ /// [`X509VerifyResult::OK`]: ../x509/struct.X509VerifyResult.html#associatedconstant.OK
+ /// [`SSL_get0_verified_chain`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_get0_verified_chain.html
+ #[cfg(ossl110)]
+ pub fn verified_chain(&self) -> Option<&StackRef<X509>> {
+ unsafe {
+ let ptr = ffi::SSL_get0_verified_chain(self.as_ptr());
+ if ptr.is_null() {
+ None
+ } else {
+ Some(StackRef::from_ptr(ptr))
+ }
+ }
+ }
+
/// Like [`SslContext::certificate`].
///
/// This corresponds to `SSL_get_certificate`.
@@ -2306,12 +2367,12 @@ impl SslRef {
/// The protocol's name is returned is an opaque sequence of bytes. It is up to the client
/// to interpret it.
///
- /// Requires OpenSSL 1.0.2 or newer.
+ /// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer.
///
/// This corresponds to [`SSL_get0_alpn_selected`].
///
/// [`SSL_get0_alpn_selected`]: https://www.openssl.org/docs/manmaster/man3/SSL_get0_next_proto_negotiated.html
- #[cfg(any(ossl102, ossl110))]
+ #[cfg(any(ossl102, libressl261))]
pub fn selected_alpn_protocol(&self) -> Option<&[u8]> {
unsafe {
let mut data: *const c_uchar = ptr::null();
@@ -2346,14 +2407,38 @@ impl SslRef {
///
/// This corresponds to [`SSL_get_servername`].
///
+ /// # Note
+ ///
+ /// While the SNI specification requires that servernames be valid domain names (and therefore
+ /// ASCII), OpenSSL does not enforce this restriction. If the servername provided by the client
+ /// is not valid UTF-8, this function will return `None`. The `servername_raw` method returns
+ /// the raw bytes and does not have this restriction.
+ ///
/// [`SSL_get_servername`]: https://www.openssl.org/docs/manmaster/man3/SSL_get_servername.html
+ // FIXME maybe rethink in 0.11?
pub fn servername(&self, type_: NameType) -> Option<&str> {
+ self.servername_raw(type_)
+ .and_then(|b| str::from_utf8(b).ok())
+ }
+
+ /// Returns the servername sent by the client via Server Name Indication (SNI).
+ ///
+ /// It is only useful on the server side.
+ ///
+ /// This corresponds to [`SSL_get_servername`].
+ ///
+ /// # Note
+ ///
+ /// Unlike `servername`, this method does not require the name be valid UTF-8.
+ ///
+ /// [`SSL_get_servername`]: https://www.openssl.org/docs/manmaster/man3/SSL_get_servername.html
+ pub fn servername_raw(&self, type_: NameType) -> Option<&[u8]> {
unsafe {
let name = ffi::SSL_get_servername(self.as_ptr(), type_.0);
if name == ptr::null() {
None
} else {
- Some(str::from_utf8(CStr::from_ptr(name as *const _).to_bytes()).unwrap())
+ Some(CStr::from_ptr(name as *const _).to_bytes())
}
}
}
@@ -2386,7 +2471,7 @@ impl SslRef {
/// This corresponds to [`SSL_get0_param`].
///
/// [`SSL_get0_param`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_get0_param.html
- #[cfg(any(ossl102, ossl110))]
+ #[cfg(any(ossl102, libressl261))]
pub fn param_mut(&mut self) -> &mut X509VerifyParamRef {
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) }
}
@@ -2479,6 +2564,36 @@ impl SslRef {
}
}
+ /// Derives keying material for application use in accordance to RFC 5705.
+ ///
+ /// This function is only usable with TLSv1.3, wherein there is no distinction between an empty context and no
+ /// context. Therefore, unlike `export_keying_material`, `context` must always be supplied.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_export_keying_material_early`].
+ ///
+ /// [`SSL_export_keying_material_early`]: https://www.openssl.org/docs/manmaster/man3/SSL_export_keying_material_early.html
+ #[cfg(ossl111)]
+ pub fn export_keying_material_early(
+ &self,
+ out: &mut [u8],
+ label: &str,
+ context: &[u8],
+ ) -> Result<(), ErrorStack> {
+ unsafe {
+ cvt(ffi::SSL_export_keying_material_early(
+ self.as_ptr(),
+ out.as_mut_ptr() as *mut c_uchar,
+ out.len(),
+ label.as_ptr() as *const c_char,
+ label.len(),
+ context.as_ptr() as *const c_uchar,
+ context.len(),
+ )).map(|_| ())
+ }
+ }
+
/// Sets the session to be used.
///
/// This should be called before the handshake to attempt to reuse a previously established
@@ -2564,7 +2679,7 @@ impl SslRef {
///
/// [`SSL_is_server`]: https://www.openssl.org/docs/manmaster/man3/SSL_is_server.html
pub fn is_server(&self) -> bool {
- unsafe { compat::SSL_is_server(self.as_ptr()) != 0 }
+ unsafe { SSL_is_server(self.as_ptr()) != 0 }
}
/// Sets the extra data at the specified index.
@@ -2617,6 +2732,57 @@ impl SslRef {
}
}
}
+
+ /// Sets the maximum amount of early data that will be accepted on this connection.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_set_max_early_data`].
+ ///
+ /// [`SSL_set_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_set_max_early_data.html
+ #[cfg(ossl111)]
+ pub fn set_max_early_data(&mut self, bytes: u32) -> Result<(), ErrorStack> {
+ if unsafe { ffi::SSL_set_max_early_data(self.as_ptr(), bytes) } == 1 {
+ Ok(())
+ } else {
+ Err(ErrorStack::get())
+ }
+ }
+
+ /// Gets the maximum amount of early data that can be sent on this connection.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_get_max_early_data`].
+ ///
+ /// [`SSL_get_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_get_max_early_data.html
+ #[cfg(ossl111)]
+ pub fn max_early_data(&self) -> u32 {
+ unsafe { ffi::SSL_get_max_early_data(self.as_ptr()) }
+ }
+
+ /// Copies the contents of the last Finished message sent to the peer into the provided buffer.
+ ///
+ /// The total size of the message is returned, so this can be used to determine the size of the
+ /// buffer required.
+ ///
+ /// This corresponds to `SSL_get_finished`.
+ pub fn finished(&self, buf: &mut [u8]) -> usize {
+ unsafe { ffi::SSL_get_finished(self.as_ptr(), buf.as_mut_ptr() as *mut c_void, buf.len()) }
+ }
+
+ /// Copies the contents of the last Finished message received from the peer into the provided
+ /// buffer.
+ ///
+ /// The total size of the message is returned, so this can be used to determine the size of the
+ /// buffer required.
+ ///
+ /// This corresponds to `SSL_get_finished`.
+ pub fn peer_finished(&self, buf: &mut [u8]) -> usize {
+ unsafe {
+ ffi::SSL_get_peer_finished(self.as_ptr(), buf.as_mut_ptr() as *mut c_void, buf.len())
+ }
+ }
}
/// An SSL stream midway through the handshake process.
@@ -2860,7 +3026,8 @@ impl<S: Read + Write> Read for SslStream<S> {
}
Err(ref e) if e.code() == ErrorCode::WANT_READ && e.io_error().is_none() => {}
Err(e) => {
- return Err(e.into_io_error()
+ return Err(e
+ .into_io_error()
.unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e)))
}
}
@@ -2875,7 +3042,8 @@ impl<S: Read + Write> Write for SslStream<S> {
Ok(n) => return Ok(n),
Err(ref e) if e.code() == ErrorCode::WANT_READ && e.io_error().is_none() => {}
Err(e) => {
- return Err(e.into_io_error()
+ return Err(e
+ .into_io_error()
.unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e)))
}
}
@@ -2927,6 +3095,24 @@ where
}
}
+ /// Configure as an outgoing stream from a client.
+ ///
+ /// This corresponds to [`SSL_set_connect_state`].
+ ///
+ /// [`SSL_set_connect_state`]: https://www.openssl.org/docs/manmaster/man3/SSL_set_connect_state.html
+ pub fn set_connect_state(&mut self) {
+ unsafe { ffi::SSL_set_connect_state(self.inner.ssl.as_ptr()) }
+ }
+
+ /// Configure as an incoming stream to a server.
+ ///
+ /// This corresponds to [`SSL_set_accept_state`].
+ ///
+ /// [`SSL_set_accept_state`]: https://www.openssl.org/docs/manmaster/man3/SSL_set_accept_state.html
+ pub fn set_accept_state(&mut self) {
+ unsafe { ffi::SSL_set_accept_state(self.inner.ssl.as_ptr()) }
+ }
+
/// See `Ssl::connect`
pub fn connect(self) -> Result<SslStream<S>, HandshakeError<S>> {
let mut stream = self.inner;
@@ -2967,7 +3153,91 @@ where
}
}
- // Future work: early IO methods
+ /// Initiates the handshake.
+ ///
+ /// This will fail if `set_accept_state` or `set_connect_state` was not called first.
+ ///
+ /// This corresponds to [`SSL_do_handshake`].
+ ///
+ /// [`SSL_do_handshake`]: https://www.openssl.org/docs/manmaster/man3/SSL_do_handshake.html
+ pub fn handshake(self) -> Result<SslStream<S>, HandshakeError<S>> {
+ let mut stream = self.inner;
+ let ret = unsafe { ffi::SSL_do_handshake(stream.ssl.as_ptr()) };
+ if ret > 0 {
+ Ok(stream)
+ } else {
+ let error = stream.make_error(ret);
+ match error.code() {
+ ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => Err(HandshakeError::WouldBlock(
+ MidHandshakeSslStream { stream, error },
+ )),
+ _ => Err(HandshakeError::Failure(MidHandshakeSslStream {
+ stream,
+ error,
+ })),
+ }
+ }
+ }
+
+ /// Read application data transmitted by a client before handshake
+ /// completion.
+ ///
+ /// Useful for reducing latency, but vulnerable to replay attacks. Call
+ /// `set_accept_state` first.
+ ///
+ /// Returns `Ok(0)` if all early data has been read.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_read_early_data`].
+ ///
+ /// [`SSL_read_early_data`]: https://www.openssl.org/docs/manmaster/man3/SSL_read_early_data.html
+ #[cfg(ossl111)]
+ pub fn read_early_data(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
+ let mut read = 0;
+ let ret = unsafe {
+ ffi::SSL_read_early_data(
+ self.inner.ssl.as_ptr(),
+ buf.as_ptr() as *mut c_void,
+ buf.len(),
+ &mut read,
+ )
+ };
+ match ret {
+ ffi::SSL_READ_EARLY_DATA_ERROR => Err(self.inner.make_error(ret)),
+ ffi::SSL_READ_EARLY_DATA_SUCCESS => Ok(read),
+ ffi::SSL_READ_EARLY_DATA_FINISH => Ok(0),
+ _ => unreachable!(),
+ }
+ }
+
+ /// Send data to the server without blocking on handshake completion.
+ ///
+ /// Useful for reducing latency, but vulnerable to replay attacks. Call
+ /// `set_connect_state` first.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_write_early_data`].
+ ///
+ /// [`SSL_write_early_data`]: https://www.openssl.org/docs/manmaster/man3/SSL_write_early_data.html
+ #[cfg(ossl111)]
+ pub fn write_early_data(&mut self, buf: &[u8]) -> Result<usize, Error> {
+ let mut written = 0;
+ let ret = unsafe {
+ ffi::SSL_write_early_data(
+ self.inner.ssl.as_ptr(),
+ buf.as_ptr() as *const c_void,
+ buf.len(),
+ &mut written,
+ )
+ };
+ if ret > 0 {
+ Ok(written as usize)
+ } else {
+ Err(self.inner.make_error(ret))
+ }
+ }
}
impl<S> SslStreamBuilder<S> {
@@ -3008,133 +3278,88 @@ pub enum ShutdownResult {
Received,
}
-#[cfg(ossl110)]
-mod compat {
- use std::ptr;
-
- use ffi;
- use libc::c_int;
-
- pub use ffi::{
- SSL_CTX_clear_options, SSL_CTX_get_options, SSL_CTX_set_options, SSL_CTX_up_ref,
- SSL_SESSION_get_master_key, SSL_SESSION_up_ref, SSL_is_server,
- };
-
- 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 fn tls_method() -> *const ffi::SSL_METHOD {
- unsafe { ffi::TLS_method() }
- }
-
- pub fn dtls_method() -> *const ffi::SSL_METHOD {
- unsafe { ffi::DTLS_method() }
- }
-}
-
-#[cfg(ossl10x)]
-#[allow(bad_style)]
-mod compat {
- use std::ptr;
-
- use ffi;
- use libc::{self, c_int, c_long, c_uchar, c_ulong, size_t};
-
- 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))
- }
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::{
+ SSL_CTX_up_ref,
+ SSL_SESSION_get_master_key, SSL_SESSION_up_ref, SSL_is_server, TLS_method, DTLS_method,
+ };
- 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_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 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
- }
+ 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),
+ )
+ }
+ } else {
+ use ffi::{SSLv23_method as TLS_method, DTLSv1_method as DTLS_method};
- pub unsafe fn SSL_SESSION_get_master_key(
- session: *const ffi::SSL_SESSION,
- out: *mut c_uchar,
- mut outlen: size_t,
- ) -> size_t {
- if outlen == 0 {
- return (*session).master_key_length as size_t;
+ 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))
}
- if outlen > (*session).master_key_length as size_t {
- outlen = (*session).master_key_length as size_t;
+
+ 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))
}
- ptr::copy_nonoverlapping((*session).master_key.as_ptr(), out, outlen);
- outlen
- }
- pub fn tls_method() -> *const ffi::SSL_METHOD {
- unsafe { ffi::SSLv23_method() }
- }
+ #[allow(bad_style)]
+ pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> c_int {
+ ffi::CRYPTO_add_lock(
+ &mut (*ssl).references,
+ 1,
+ ffi::CRYPTO_LOCK_SSL_CTX,
+ "mod.rs\0".as_ptr() as *const _,
+ line!() as c_int,
+ );
+ 0
+ }
- pub fn dtls_method() -> *const ffi::SSL_METHOD {
- unsafe { ffi::DTLSv1_method() }
- }
+ #[allow(bad_style)]
+ pub unsafe fn SSL_SESSION_get_master_key(
+ session: *const ffi::SSL_SESSION,
+ out: *mut c_uchar,
+ mut outlen: usize,
+ ) -> usize {
+ if outlen == 0 {
+ return (*session).master_key_length as usize;
+ }
+ if outlen > (*session).master_key_length as usize {
+ outlen = (*session).master_key_length as usize;
+ }
+ ptr::copy_nonoverlapping((*session).master_key.as_ptr(), out, outlen);
+ outlen
+ }
- pub unsafe fn SSL_is_server(s: *mut ffi::SSL) -> c_int {
- (*s).server
- }
+ #[allow(bad_style)]
+ pub unsafe fn SSL_is_server(s: *mut ffi::SSL) -> c_int {
+ (*s).server
+ }
- pub unsafe fn SSL_SESSION_up_ref(ses: *mut ffi::SSL_SESSION) -> c_int {
- ffi::CRYPTO_add_lock(
- &mut (*ses).references,
- 1,
- ffi::CRYPTO_LOCK_SSL_CTX,
- "mod.rs\0".as_ptr() as *const _,
- line!() as libc::c_int,
- );
- 0
+ #[allow(bad_style)]
+ pub unsafe fn SSL_SESSION_up_ref(ses: *mut ffi::SSL_SESSION) -> c_int {
+ ffi::CRYPTO_add_lock(
+ &mut (*ses).references,
+ 1,
+ ffi::CRYPTO_LOCK_SSL_CTX,
+ "mod.rs\0".as_ptr() as *const _,
+ line!() as c_int,
+ );
+ 0
+ }
}
}
diff --git a/openssl/src/ssl/test.rs b/openssl/src/ssl/test.rs
index 2e906728..f5ec7b29 100644
--- a/openssl/src/ssl/test.rs
+++ b/openssl/src/ssl/test.rs
@@ -19,7 +19,7 @@ use hash::MessageDigest;
use ocsp::{OcspResponse, OcspResponseStatus};
use pkey::PKey;
use ssl;
-#[cfg(any(ossl110, ossl111))]
+#[cfg(any(ossl110, ossl111, libressl261))]
use ssl::SslVersion;
use ssl::{
Error, HandshakeError, MidHandshakeSslStream, ShutdownResult, Ssl, SslAcceptor, SslConnector,
@@ -295,8 +295,8 @@ run_test!(verify_callback_data, |method, stream| {
match cert {
None => false,
Some(cert) => {
- let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
- fingerprint == node_id
+ let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
+ node_id == &*fingerprint
}
}
});
@@ -323,8 +323,8 @@ run_test!(ssl_verify_callback, |method, stream| {
match x509.current_cert() {
None => false,
Some(cert) => {
- let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
- fingerprint == node_id
+ let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
+ node_id == &*fingerprint
}
}
});
@@ -424,10 +424,10 @@ run_test!(get_peer_certificate, |method, stream| {
let ctx = SslContext::builder(method).unwrap();
let stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap();
let cert = stream.ssl().peer_certificate().unwrap();
- let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
+ let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
let node_id = Vec::from_hex(node_hash_str).unwrap();
- assert_eq!(node_id, fingerprint)
+ assert_eq!(node_id, &*fingerprint)
});
#[test]
@@ -481,7 +481,7 @@ fn test_state() {
/// Tests that connecting with the client using ALPN, but the server not does not
/// break the existing connection behavior.
#[test]
-#[cfg(any(ossl102, ossl110))]
+#[cfg(any(ossl102, libressl261))]
fn test_connect_with_unilateral_alpn() {
let (_s, stream) = Server::new();
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
@@ -503,7 +503,7 @@ fn test_connect_with_unilateral_alpn() {
/// 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(any(ossl102, ossl110))]
+#[cfg(any(ossl102, libressl261))]
fn test_connect_with_alpn_successful_multiple_matching() {
let (_s, stream) = Server::new_alpn();
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
@@ -526,7 +526,7 @@ fn test_connect_with_alpn_successful_multiple_matching() {
/// lists of supported protocols have an overlap -- with only ONE protocol
/// being valid for both.
#[test]
-#[cfg(any(ossl102, ossl110))]
+#[cfg(any(ossl102, libressl261))]
fn test_connect_with_alpn_successful_single_match() {
let (_s, stream) = Server::new_alpn();
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
@@ -548,7 +548,7 @@ fn test_connect_with_alpn_successful_single_match() {
/// Tests that when the `SslStream` is created as a server stream, the protocols
/// are correctly advertised to the client.
#[test]
-#[cfg(any(ossl102, ossl110))]
+#[cfg(any(ossl102, libressl261))]
fn test_alpn_server_advertise_multiple() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let localhost = listener.local_addr().unwrap();
@@ -624,7 +624,7 @@ fn test_alpn_server_select_none_fatal() {
}
#[test]
-#[cfg(any(ossl102, ossl110))]
+#[cfg(any(ossl102, libressl261))]
fn test_alpn_server_select_none() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let localhost = listener.local_addr().unwrap();
@@ -1063,7 +1063,7 @@ fn tmp_dh_callback() {
}
#[test]
-#[cfg(any(all(ossl101, not(libressl)), ossl102))]
+#[cfg(all(ossl101, not(ossl110)))]
fn tmp_ecdh_callback() {
use ec::EcKey;
use nid::Nid;
@@ -1137,7 +1137,7 @@ fn tmp_dh_callback_ssl() {
}
#[test]
-#[cfg(any(all(ossl101, not(libressl)), ossl102))]
+#[cfg(all(ossl101, not(ossl110)))]
fn tmp_ecdh_callback_ssl() {
use ec::EcKey;
use nid::Nid;
@@ -1315,7 +1315,7 @@ fn keying_export() {
}
#[test]
-#[cfg(any(ossl110))]
+#[cfg(any(ossl110, libressl261))]
fn no_version_overlap() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap();
@@ -1330,7 +1330,7 @@ fn no_version_overlap() {
ctx.set_max_proto_version(Some(SslVersion::TLS1_1)).unwrap();
#[cfg(ossl110g)]
assert_eq!(ctx.min_proto_version(), None);
- #[cfg(ossl110g)]
+ #[cfg(any(ossl110g, libressl270))]
assert_eq!(ctx.max_proto_version(), Some(SslVersion::TLS1_1));
let ssl = Ssl::new(&ctx.build()).unwrap();
ssl.accept(stream).unwrap_err();
@@ -1339,7 +1339,7 @@ fn no_version_overlap() {
let stream = TcpStream::connect(addr).unwrap();
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_min_proto_version(Some(SslVersion::TLS1_2)).unwrap();
- #[cfg(ossl110g)]
+ #[cfg(any(ossl110g, libressl270))]
assert_eq!(ctx.min_proto_version(), Some(SslVersion::TLS1_2));
#[cfg(ossl110g)]
assert_eq!(ctx.max_proto_version(), None);
diff --git a/openssl/src/stack.rs b/openssl/src/stack.rs
index d8589352..ac1e2a13 100644
--- a/openssl/src/stack.rs
+++ b/openssl/src/stack.rs
@@ -1,23 +1,30 @@
-use foreign_types::{ForeignTypeRef, ForeignType, Opaque};
+use ffi;
+use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
use libc::c_int;
use std::borrow::Borrow;
use std::convert::AsRef;
use std::iter;
use std::marker::PhantomData;
use std::mem;
-use ffi;
-use {cvt, cvt_p};
use error::ErrorStack;
use std::ops::{Deref, DerefMut, Index, IndexMut};
+use {cvt, cvt_p};
-#[cfg(ossl10x)]
-use ffi::{sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num,
- sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK,
- sk_new_null as OPENSSL_sk_new_null, sk_push as OPENSSL_sk_push};
-#[cfg(ossl110)]
-use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK,
- OPENSSL_sk_new_null, OPENSSL_sk_push};
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::{
+ OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK,
+ OPENSSL_sk_new_null, OPENSSL_sk_push,
+ };
+ } else {
+ use ffi::{
+ sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num,
+ sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK,
+ sk_new_null as OPENSSL_sk_new_null, sk_push as OPENSSL_sk_push,
+ };
+ }
+}
/// Trait implemented by types which can be placed in a stack.
///
@@ -33,15 +40,8 @@ pub trait Stackable: ForeignType {
/// An owned stack of `T`.
pub struct Stack<T: Stackable>(*mut T::StackType);
-impl<T: Stackable> Stack<T> {
- pub fn new() -> Result<Stack<T>, ErrorStack> {
- unsafe {
- ffi::init();
- let ptr = cvt_p(OPENSSL_sk_new_null())?;
- Ok(Stack(ptr as *mut _))
- }
- }
-}
+unsafe impl<T: Stackable + Send> Send for Stack<T> {}
+unsafe impl<T: Stackable + Sync> Sync for Stack<T> {}
impl<T: Stackable> Drop for Stack<T> {
fn drop(&mut self) {
@@ -52,6 +52,16 @@ impl<T: Stackable> Drop for Stack<T> {
}
}
+impl<T: Stackable> Stack<T> {
+ pub fn new() -> Result<Stack<T>, ErrorStack> {
+ unsafe {
+ ffi::init();
+ let ptr = cvt_p(OPENSSL_sk_new_null())?;
+ Ok(Stack(ptr as *mut _))
+ }
+ }
+}
+
impl<T: Stackable> iter::IntoIterator for Stack<T> {
type IntoIter = IntoIter<T>;
type Item = T;
@@ -87,7 +97,7 @@ impl<T: Stackable> ForeignType for Stack<T> {
assert!(
!ptr.is_null(),
"Must not instantiate a Stack from a null-ptr - use Stack::new() in \
- that case"
+ that case"
);
Stack(ptr)
}
@@ -157,6 +167,9 @@ impl<T: Stackable> ExactSizeIterator for IntoIter<T> {}
pub struct StackRef<T: Stackable>(Opaque, PhantomData<T>);
+unsafe impl<T: Stackable + Send> Send for StackRef<T> {}
+unsafe impl<T: Stackable + Sync> Sync for StackRef<T> {}
+
impl<T: Stackable> ForeignTypeRef for StackRef<T> {
type CType = T::StackType;
}
@@ -218,9 +231,7 @@ impl<T: Stackable> StackRef<T> {
/// Pushes a value onto the top of the stack.
pub fn push(&mut self, data: T) -> Result<(), ErrorStack> {
unsafe {
- cvt(
- OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _),
- )?;
+ cvt(OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _))?;
mem::forget(data);
Ok(())
}
diff --git a/openssl/src/symm.rs b/openssl/src/symm.rs
index 904fb8de..33655874 100644
--- a/openssl/src/symm.rs
+++ b/openssl/src/symm.rs
@@ -52,14 +52,14 @@
//! println!("Decrypted: '{}'", output_string);
//! ```
+use ffi;
+use libc::c_int;
use std::cmp;
use std::ptr;
-use libc::c_int;
-use ffi;
-use {cvt, cvt_p};
use error::ErrorStack;
use nid::Nid;
+use {cvt, cvt_p};
#[derive(Copy, Clone)]
pub enum Mode {
@@ -718,34 +718,31 @@ pub fn decrypt_aead(
Ok(out)
}
-#[cfg(ossl110)]
-use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, 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
- }
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
+ } else {
+ #[allow(bad_style)]
+ pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
+ (*ptr).iv_len
+ }
- pub unsafe fn EVP_CIPHER_block_size(ptr: *const EVP_CIPHER) -> c_int {
- (*ptr).block_size
- }
+ #[allow(bad_style)]
+ pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> c_int {
+ (*ptr).block_size
+ }
- pub unsafe fn EVP_CIPHER_key_length(ptr: *const EVP_CIPHER) -> c_int {
- (*ptr).key_len
+ #[allow(bad_style)]
+ pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
+ (*ptr).key_len
+ }
}
}
-#[cfg(ossl10x)]
-use self::compat::*;
#[cfg(test)]
mod tests {
- use hex::{self, FromHex};
use super::*;
+ use hex::{self, FromHex};
// Test vectors from FIPS-197:
// http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
diff --git a/openssl/src/version.rs b/openssl/src/version.rs
index 7254d7ba..dc8508d1 100644
--- a/openssl/src/version.rs
+++ b/openssl/src/version.rs
@@ -13,15 +13,21 @@
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, OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR,
- OpenSSL_version_num, OpenSSL_version};
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::{
+ OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR,
+ OpenSSL_version_num, OpenSSL_version,
+ };
+ } else {
+ 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,
+ };
+ }
+}
/// OPENSSL_VERSION_NUMBER is a numeric release version identifier:
///
@@ -51,7 +57,6 @@ pub fn number() -> 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 {
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs
index c1ae3b16..5c1bb23f 100644
--- a/openssl/src/x509/mod.rs
+++ b/openssl/src/x509/mod.rs
@@ -7,9 +7,9 @@
//! Internet protocols, including SSL/TLS, which is the basis for HTTPS,
//! the secure protocol for browsing the web.
-use libc::{c_int, c_long};
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
+use libc::{c_int, c_long};
use std::error::Error;
use std::ffi::{CStr, CString};
use std::fmt;
@@ -20,27 +20,20 @@ use std::ptr;
use std::slice;
use std::str;
-use {cvt, cvt_n, cvt_p};
use asn1::{Asn1BitStringRef, Asn1IntegerRef, Asn1ObjectRef, Asn1StringRef, Asn1TimeRef};
use bio::MemBioSlice;
use conf::ConfRef;
use error::ErrorStack;
use ex_data::Index;
-use hash::MessageDigest;
+use hash::{DigestBytes, MessageDigest};
use nid::Nid;
use pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public};
+use ssl::SslRef;
use stack::{Stack, StackRef, Stackable};
use string::OpensslString;
-use ssl::SslRef;
-
-#[cfg(ossl10x)]
-use ffi::{ASN1_STRING_data, X509_STORE_CTX_get_chain, X509_set_notAfter, X509_set_notBefore};
-#[cfg(ossl110)]
-use ffi::{ASN1_STRING_get0_data as ASN1_STRING_data,
- X509_STORE_CTX_get0_chain as X509_STORE_CTX_get_chain,
- X509_set1_notAfter as X509_set_notAfter, X509_set1_notBefore as X509_set_notBefore};
+use {cvt, cvt_n, cvt_p};
-#[cfg(any(ossl102, ossl110))]
+#[cfg(any(ossl102, libressl261))]
pub mod verify;
pub mod extension;
@@ -215,7 +208,7 @@ impl X509StoreContextRef {
/// [`X509_STORE_CTX_get0_chain`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_STORE_CTX_get0_chain.html
pub fn chain(&self) -> Option<&StackRef<X509>> {
unsafe {
- let chain = X509_STORE_CTX_get_chain(self.as_ptr());
+ let chain = X509_STORE_CTX_get0_chain(self.as_ptr());
if chain.is_null() {
None
@@ -240,12 +233,12 @@ impl X509Builder {
/// Sets the notAfter constraint on the certificate.
pub fn set_not_after(&mut self, not_after: &Asn1TimeRef) -> Result<(), ErrorStack> {
- unsafe { cvt(X509_set_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) }
+ unsafe { cvt(X509_set1_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) }
}
/// Sets the notBefore constraint on the certificate.
pub fn set_not_before(&mut self, not_before: &Asn1TimeRef) -> Result<(), ErrorStack> {
- unsafe { cvt(X509_set_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) }
+ unsafe { cvt(X509_set1_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) }
}
/// Sets the version of the certificate.
@@ -454,27 +447,39 @@ impl X509Ref {
}
}
- /// Returns certificate fingerprint calculated using provided hash
- pub fn fingerprint(&self, hash_type: MessageDigest) -> Result<Vec<u8>, ErrorStack> {
+ /// Returns a digest of the DER representation of the certificate.
+ ///
+ /// This corresponds to [`X509_digest`].
+ ///
+ /// [`X509_digest`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_digest.html
+ pub fn digest(&self, hash_type: MessageDigest) -> Result<DigestBytes, ErrorStack> {
unsafe {
- let evp = hash_type.as_ptr();
+ let mut digest = DigestBytes {
+ buf: [0; ffi::EVP_MAX_MD_SIZE as usize],
+ len: ffi::EVP_MAX_MD_SIZE as usize,
+ };
let mut len = ffi::EVP_MAX_MD_SIZE;
- let mut buf = vec![0u8; len as usize];
cvt(ffi::X509_digest(
self.as_ptr(),
- evp,
- buf.as_mut_ptr() as *mut _,
+ hash_type.as_ptr(),
+ digest.buf.as_mut_ptr() as *mut _,
&mut len,
))?;
- buf.truncate(len as usize);
- Ok(buf)
+ digest.len = len as usize;
+
+ Ok(digest)
}
}
+ #[deprecated(since = "0.10.9", note = "renamed to digest")]
+ pub fn fingerprint(&self, hash_type: MessageDigest) -> Result<Vec<u8>, ErrorStack> {
+ self.digest(hash_type).map(|b| b.to_vec())
+ }
+
/// Returns the certificate's Not After validity period.
pub fn not_after(&self) -> &Asn1TimeRef {
unsafe {
- let date = compat::X509_get_notAfter(self.as_ptr());
+ let date = X509_getm_notAfter(self.as_ptr());
assert!(!date.is_null());
Asn1TimeRef::from_ptr(date)
}
@@ -483,7 +488,7 @@ impl X509Ref {
/// Returns the certificate's Not Before validity period.
pub fn not_before(&self) -> &Asn1TimeRef {
unsafe {
- let date = compat::X509_get_notBefore(self.as_ptr());
+ let date = X509_getm_notBefore(self.as_ptr());
assert!(!date.is_null());
Asn1TimeRef::from_ptr(date)
}
@@ -493,7 +498,7 @@ impl X509Ref {
pub fn signature(&self) -> &Asn1BitStringRef {
unsafe {
let mut signature = ptr::null();
- compat::X509_get0_signature(&mut signature, ptr::null_mut(), self.as_ptr());
+ X509_get0_signature(&mut signature, ptr::null_mut(), self.as_ptr());
assert!(!signature.is_null());
Asn1BitStringRef::from_ptr(signature as *mut _)
}
@@ -503,7 +508,7 @@ impl X509Ref {
pub fn signature_algorithm(&self) -> &X509AlgorithmRef {
unsafe {
let mut algor = ptr::null();
- compat::X509_get0_signature(ptr::null_mut(), &mut algor, self.as_ptr());
+ X509_get0_signature(ptr::null_mut(), &mut algor, self.as_ptr());
assert!(!algor.is_null());
X509AlgorithmRef::from_ptr(algor as *mut _)
}
@@ -564,7 +569,7 @@ impl ToOwned for X509Ref {
fn to_owned(&self) -> X509 {
unsafe {
- compat::X509_up_ref(self.as_ptr());
+ X509_up_ref(self.as_ptr());
X509::from_ptr(self.as_ptr())
}
}
@@ -1054,7 +1059,7 @@ impl X509ReqRef {
///
/// [`X509_REQ_get_version`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_version.html
pub fn version(&self) -> i32 {
- unsafe { compat::X509_REQ_get_version(self.as_ptr()) as i32 }
+ unsafe { X509_REQ_get_version(self.as_ptr()) as i32 }
}
/// Returns the subject name of the certificate request.
@@ -1064,7 +1069,7 @@ impl X509ReqRef {
/// [`X509_REQ_get_subject_name`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_subject_name.html
pub fn subject_name(&self) -> &X509NameRef {
unsafe {
- let name = compat::X509_REQ_get_subject_name(self.as_ptr());
+ let name = X509_REQ_get_subject_name(self.as_ptr());
assert!(!name.is_null());
X509NameRef::from_ptr(name)
}
@@ -1172,7 +1177,7 @@ impl GeneralNameRef {
return None;
}
- let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _);
+ let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d as *mut _);
let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _);
let slice = slice::from_raw_parts(ptr as *const u8, len as usize);
@@ -1205,7 +1210,7 @@ impl GeneralNameRef {
return None;
}
- let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _);
+ let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d as *mut _);
let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _);
Some(slice::from_raw_parts(ptr as *const u8, len as usize))
@@ -1232,79 +1237,86 @@ impl X509AlgorithmRef {
pub fn object(&self) -> &Asn1ObjectRef {
unsafe {
let mut oid = ptr::null();
- compat::X509_ALGOR_get0(&mut oid, ptr::null_mut(), ptr::null_mut(), self.as_ptr());
+ X509_ALGOR_get0(&mut oid, ptr::null_mut(), ptr::null_mut(), self.as_ptr());
assert!(!oid.is_null());
Asn1ObjectRef::from_ptr(oid as *mut _)
}
}
}
-#[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_REQ_get_version;
- pub use ffi::X509_REQ_get_subject_name;
- pub use ffi::X509_get0_signature;
- pub use ffi::X509_ALGOR_get0;
-}
-
-#[cfg(ossl10x)]
-#[allow(bad_style)]
-mod compat {
- use libc::{c_int, c_void};
- 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
- }
+cfg_if! {
+ if #[cfg(ossl110)] {
+ use ffi::{
+ X509_ALGOR_get0, X509_REQ_get_subject_name, X509_REQ_get_version,
+ X509_get0_signature, X509_getm_notAfter, X509_getm_notBefore, X509_up_ref,
+ ASN1_STRING_get0_data, X509_STORE_CTX_get0_chain, X509_set1_notAfter,
+ X509_set1_notBefore,
+ };
+ } else {
+ use ffi::{
+ ASN1_STRING_data as ASN1_STRING_get0_data,
+ X509_STORE_CTX_get_chain as X509_STORE_CTX_get0_chain,
+ X509_set_notAfter as X509_set1_notAfter,
+ X509_set_notBefore as X509_set1_notBefore,
+ };
+
+ #[allow(bad_style)]
+ unsafe fn X509_getm_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
+ (*(*(*x).cert_info).validity).notAfter
+ }
- 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,
- );
- }
+ #[allow(bad_style)]
+ unsafe fn X509_getm_notBefore(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
+ (*(*(*x).cert_info).validity).notBefore
+ }
- pub unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long {
- ::ffi::ASN1_INTEGER_get((*(*x).req_info).version)
- }
+ #[allow(bad_style)]
+ 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_REQ_get_subject_name(x: *mut ffi::X509_REQ) -> *mut ::ffi::X509_NAME {
- (*(*x).req_info).subject
- }
+ #[allow(bad_style)]
+ unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long {
+ ffi::ASN1_INTEGER_get((*(*x).req_info).version)
+ }
- pub unsafe fn X509_get0_signature(
- psig: *mut *const ffi::ASN1_BIT_STRING,
- palg: *mut *const ffi::X509_ALGOR,
- x: *const ffi::X509,
- ) {
- if !psig.is_null() {
- *psig = (*x).signature;
+ #[allow(bad_style)]
+ unsafe fn X509_REQ_get_subject_name(x: *mut ffi::X509_REQ) -> *mut ::ffi::X509_NAME {
+ (*(*x).req_info).subject
}
- if !palg.is_null() {
- *palg = (*x).sig_alg;
+
+ #[allow(bad_style)]
+ unsafe fn X509_get0_signature(
+ psig: *mut *const ffi::ASN1_BIT_STRING,
+ palg: *mut *const ffi::X509_ALGOR,
+ x: *const ffi::X509,
+ ) {
+ if !psig.is_null() {
+ *psig = (*x).signature;
+ }
+ if !palg.is_null() {
+ *palg = (*x).sig_alg;
+ }
}
- }
- pub unsafe fn X509_ALGOR_get0(
- paobj: *mut *const ffi::ASN1_OBJECT,
- pptype: *mut c_int,
- pval: *mut *mut c_void,
- alg: *const ffi::X509_ALGOR,
- ) {
- if !paobj.is_null() {
- *paobj = (*alg).algorithm;
+ #[allow(bad_style)]
+ unsafe fn X509_ALGOR_get0(
+ paobj: *mut *const ffi::ASN1_OBJECT,
+ pptype: *mut c_int,
+ pval: *mut *mut ::libc::c_void,
+ alg: *const ffi::X509_ALGOR,
+ ) {
+ if !paobj.is_null() {
+ *paobj = (*alg).algorithm;
+ }
+ assert!(pptype.is_null());
+ assert!(pval.is_null());
}
- assert!(pptype.is_null());
- assert!(pval.is_null());
}
}
diff --git a/openssl/src/x509/store.rs b/openssl/src/x509/store.rs
index 4d6bc9ab..f533d9c7 100644
--- a/openssl/src/x509/store.rs
+++ b/openssl/src/x509/store.rs
@@ -44,11 +44,11 @@ use ffi;
use foreign_types::ForeignTypeRef;
use std::mem;
-use {cvt, cvt_p};
use error::ErrorStack;
use x509::X509;
+use {cvt, cvt_p};
-foreign_type! {
+foreign_type_and_impl_send_sync! {
type CType = ffi::X509_STORE;
fn drop = ffi::X509_STORE_free;
@@ -82,9 +82,7 @@ impl X509StoreBuilderRef {
/// Adds a certificate to the certificate store.
// FIXME should take an &X509Ref
pub fn add_cert(&mut self, cert: X509) -> Result<(), ErrorStack> {
- unsafe {
- cvt(ffi::X509_STORE_add_cert(self.as_ptr(), cert.as_ptr())).map(|_| ())
- }
+ unsafe { cvt(ffi::X509_STORE_add_cert(self.as_ptr(), cert.as_ptr())).map(|_| ()) }
}
/// Load certificates from their default locations.
@@ -97,7 +95,7 @@ impl X509StoreBuilderRef {
}
}
-foreign_type! {
+foreign_type_and_impl_send_sync! {
type CType = ffi::X509_STORE;
fn drop = ffi::X509_STORE_free;
diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs
index 7ef4d160..42859c97 100644
--- a/openssl/src/x509/tests.rs
+++ b/openssl/src/x509/tests.rs
@@ -7,10 +7,12 @@ use nid::Nid;
use pkey::{PKey, Private};
use rsa::Rsa;
use stack::Stack;
-use x509::{X509, X509Name, X509Req, X509StoreContext, X509VerifyResult};
-use x509::extension::{AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage,
- SubjectAlternativeName, SubjectKeyIdentifier};
+use x509::extension::{
+ AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName,
+ SubjectKeyIdentifier,
+};
use x509::store::X509StoreBuilder;
+use x509::{X509, X509Name, X509Req, X509StoreContext, X509VerifyResult};
fn pkey() -> PKey<Private> {
let rsa = Rsa::generate(2048).unwrap();
@@ -21,12 +23,12 @@ fn pkey() -> PKey<Private> {
fn test_cert_loading() {
let cert = include_bytes!("../../test/cert.pem");
let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
- let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
+ let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
let hash_vec = Vec::from_hex(hash_str).unwrap();
- assert_eq!(fingerprint, hash_vec);
+ assert_eq!(hash_vec, &*fingerprint);
}
#[test]
@@ -197,7 +199,8 @@ fn x509_builder() {
assert!(pkey.public_eq(&x509.public_key().unwrap()));
- let cn = x509.subject_name()
+ let cn = x509
+ .subject_name()
.entries_by_nid(Nid::COMMONNAME)
.next()
.unwrap();
@@ -247,11 +250,11 @@ fn test_stack_from_pem() {
assert_eq!(certs.len(), 2);
assert_eq!(
- hex::encode(certs[0].fingerprint(MessageDigest::sha1()).unwrap()),
+ hex::encode(certs[0].digest(MessageDigest::sha1()).unwrap()),
"59172d9313e84459bcff27f967e79e6e9217e584"
);
assert_eq!(
- hex::encode(certs[1].fingerprint(MessageDigest::sha1()).unwrap()),
+ hex::encode(certs[1].digest(MessageDigest::sha1()).unwrap()),
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
);
}
@@ -291,7 +294,7 @@ fn signature() {
fn clone_x509() {
let cert = include_bytes!("../../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
- cert.clone();
+ drop(cert.clone());
}
#[test]
diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs
index b90c8f58..2eabe38c 100644
--- a/openssl/src/x509/verify.rs
+++ b/openssl/src/x509/verify.rs
@@ -1,6 +1,6 @@
-use libc::c_uint;
use ffi;
use foreign_types::ForeignTypeRef;
+use libc::c_uint;
use std::net::IpAddr;
use cvt;