Support min/max version in LibreSSL

Their implementations of the accessors don't behave expected with no
bounds, so we ignore those bits of the tests.
This commit is contained in:
Steven Fackler 2018-05-19 19:43:02 -07:00
parent 9ba53102f9
commit d991566f2b
13 changed files with 175 additions and 101 deletions

View File

@ -9,6 +9,7 @@ repository = "https://github.com/sfackler/rust-openssl"
readme = "README.md" readme = "README.md"
categories = ["cryptography", "external-ffi-bindings"] categories = ["cryptography", "external-ffi-bindings"]
links = "openssl" links = "openssl"
build = "build/main.rs"
[dependencies] [dependencies]
libc = "0.2" libc = "0.2"

45
openssl-sys/build/cfgs.rs Normal file
View File

@ -0,0 +1,45 @@
pub fn get(openssl_version: Option<u64>, libressl_version: Option<u64>) -> Vec<&'static str> {
let mut cfgs = vec![];
if let Some(libressl_version) = libressl_version {
cfgs.push("libressl");
if libressl_version >= 0x2_05_01_00_0 {
cfgs.push("libressl251");
}
if libressl_version >= 0x2_06_01_00_0 {
cfgs.push("libressl261");
}
if libressl_version >= 0x2_07_00_00_0 {
cfgs.push("libressl270");
}
} else {
let openssl_version = openssl_version.unwrap();
if openssl_version >= 0x1_00_02_08_0 {
cfgs.push("ossl102h");
}
if openssl_version >= 0x1_01_00_07_0 {
cfgs.push("ossl110g");
}
if openssl_version >= 0x1_01_01_00_0 {
cfgs.push("ossl111");
cfgs.push("ossl110");
} else if openssl_version >= 0x1_01_00_06_0 {
cfgs.push("ossl110");
cfgs.push("ossl110f");
} else if openssl_version >= 0x1_01_00_00_0 {
cfgs.push("ossl110");
} else if openssl_version >= 0x1_00_02_00_0 {
cfgs.push("ossl102");
} else if openssl_version >= 0x1_00_01_00_0 {
cfgs.push("ossl101");
}
}
cfgs
}

View File

@ -11,6 +11,8 @@ use std::io::{BufWriter, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
mod cfgs;
// The set of `OPENSSL_NO_<FOO>`s that we care about. // The set of `OPENSSL_NO_<FOO>`s that we care about.
const DEFINES: &'static [&'static str] = &[ const DEFINES: &'static [&'static str] = &[
"OPENSSL_NO_BUF_FREELISTS", "OPENSSL_NO_BUF_FREELISTS",
@ -427,6 +429,10 @@ See rust-openssl README for more information:
} }
println!("cargo:conf={}", enabled.join(",")); println!("cargo:conf={}", enabled.join(","));
for cfg in cfgs::get(openssl_version, libressl_version) {
println!("cargo:rustc-cfg={}", cfg);
}
if let Some(libressl_version) = libressl_version { if let Some(libressl_version) = libressl_version {
println!("cargo:libressl_version_number={:x}", libressl_version); println!("cargo:libressl_version_number={:x}", libressl_version);
@ -445,8 +451,6 @@ See rust-openssl README for more information:
_ => version_error(), _ => version_error(),
}; };
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl2{}{}", minor, fix);
println!("cargo:libressl=true"); println!("cargo:libressl=true");
println!("cargo:libressl_version=2{}{}", minor, fix); println!("cargo:libressl_version=2{}{}", minor, fix);
println!("cargo:version=101"); println!("cargo:version=101");
@ -455,37 +459,22 @@ See rust-openssl README for more information:
let openssl_version = openssl_version.unwrap(); let openssl_version = openssl_version.unwrap();
println!("cargo:version_number={:x}", openssl_version); println!("cargo:version_number={:x}", openssl_version);
if openssl_version >= 0x1_00_02_08_0 {
println!("cargo:rustc-cfg=ossl102h");
}
if openssl_version >= 0x1_01_00_07_0 {
println!("cargo:rustc-cfg=ossl110g");
}
if openssl_version >= 0x1_01_02_00_0 { if openssl_version >= 0x1_01_02_00_0 {
version_error() version_error()
} else if openssl_version >= 0x1_01_01_00_0 { } else if openssl_version >= 0x1_01_01_00_0 {
println!("cargo:rustc-cfg=ossl111");
println!("cargo:rustc-cfg=ossl110");
println!("cargo:version=111"); println!("cargo:version=111");
Version::Openssl11x Version::Openssl11x
} else if openssl_version >= 0x1_01_00_06_0 { } else if openssl_version >= 0x1_01_00_06_0 {
println!("cargo:rustc-cfg=ossl110");
println!("cargo:rustc-cfg=ossl110f");
println!("cargo:version=110"); println!("cargo:version=110");
println!("cargo:patch=f"); println!("cargo:patch=f");
Version::Openssl11x Version::Openssl11x
} else if openssl_version >= 0x1_01_00_00_0 { } else if openssl_version >= 0x1_01_00_00_0 {
println!("cargo:rustc-cfg=ossl110");
println!("cargo:version=110"); println!("cargo:version=110");
Version::Openssl11x Version::Openssl11x
} else if openssl_version >= 0x1_00_02_00_0 { } else if openssl_version >= 0x1_00_02_00_0 {
println!("cargo:rustc-cfg=ossl102");
println!("cargo:version=102"); println!("cargo:version=102");
Version::Openssl10x Version::Openssl10x
} else if openssl_version >= 0x1_00_01_00_0 { } else if openssl_version >= 0x1_00_01_00_0 {
println!("cargo:rustc-cfg=ossl101");
println!("cargo:version=101"); println!("cargo:version=101");
Version::Openssl10x Version::Openssl10x
} else { } else {
@ -542,10 +531,12 @@ fn determine_mode(libdir: &Path, libs: &[&str]) -> &'static str {
.map(|e| e.file_name()) .map(|e| e.file_name())
.filter_map(|e| e.into_string().ok()) .filter_map(|e| e.into_string().ok())
.collect::<HashSet<_>>(); .collect::<HashSet<_>>();
let can_static = libs.iter() let can_static = libs
.iter()
.all(|l| files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l))); .all(|l| files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l)));
let can_dylib = libs.iter().all(|l| { let can_dylib = libs.iter().all(|l| {
files.contains(&format!("lib{}.so", l)) || files.contains(&format!("{}.dll", l)) files.contains(&format!("lib{}.so", l))
|| files.contains(&format!("{}.dll", l))
|| files.contains(&format!("lib{}.dylib", l)) || files.contains(&format!("lib{}.dylib", l))
}); });
match (can_static, can_dylib) { match (can_static, can_dylib) {
@ -567,8 +558,6 @@ fn determine_mode(libdir: &Path, libs: &[&str]) -> &'static str {
"dylib" "dylib"
} }
fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option<String> { fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option<String> {
let out = Command::new(cmd).args(args).output(); let out = Command::new(cmd).args(args).output();
if let Ok(ref r1) = out { if let Ok(ref r1) = out {
@ -581,4 +570,3 @@ fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option<String> {
} }
return None; return None;
} }

View File

@ -236,8 +236,10 @@ pub const EVP_PKEY_OP_VERIFYCTX: c_int = 1 << 7;
pub const EVP_PKEY_OP_ENCRYPT: c_int = 1 << 8; pub const EVP_PKEY_OP_ENCRYPT: c_int = 1 << 8;
pub const EVP_PKEY_OP_DECRYPT: c_int = 1 << 9; pub const EVP_PKEY_OP_DECRYPT: c_int = 1 << 9;
pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN
| EVP_PKEY_OP_VERIFYRECOVER | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFY
| EVP_PKEY_OP_VERIFYRECOVER
| EVP_PKEY_OP_SIGNCTX
| EVP_PKEY_OP_VERIFYCTX; | EVP_PKEY_OP_VERIFYCTX;
pub const EVP_PKEY_OP_TYPE_CRYPT: c_int = EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT; pub const EVP_PKEY_OP_TYPE_CRYPT: c_int = EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT;
@ -1259,21 +1261,23 @@ pub const SSL_VERIFY_NONE: c_int = 0;
pub const SSL_VERIFY_PEER: c_int = 1; pub const SSL_VERIFY_PEER: c_int = 1;
pub const SSL_VERIFY_FAIL_IF_NO_PEER_CERT: c_int = 2; pub const SSL_VERIFY_FAIL_IF_NO_PEER_CERT: c_int = 2;
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x, ossl101)))] #[cfg(not(any(libressl261, ossl101)))]
pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x00000010; pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x00000010;
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))] #[cfg(libressl261)]
pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x0; pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x0;
pub const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: c_ulong = 0x00000800; pub const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: c_ulong = 0x00000800;
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x)))] #[cfg(not(libressl261))]
pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x80000000; pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x80000000;
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))] #[cfg(libressl261)]
pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x0; pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x0;
pub const SSL_OP_LEGACY_SERVER_CONNECT: c_ulong = 0x00000004; pub const SSL_OP_LEGACY_SERVER_CONNECT: c_ulong = 0x00000004;
#[cfg(not(any(libressl, ossl110f, ossl111)))] #[cfg(not(any(libressl, ossl110f, ossl111)))]
pub const SSL_OP_ALL: c_ulong = 0x80000BFF; pub const SSL_OP_ALL: c_ulong = 0x80000BFF;
#[cfg(any(ossl110f, ossl111))] #[cfg(any(ossl110f, ossl111))]
pub const SSL_OP_ALL: c_ulong = SSL_OP_CRYPTOPRO_TLSEXT_BUG | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS pub const SSL_OP_ALL: c_ulong = SSL_OP_CRYPTOPRO_TLSEXT_BUG
| SSL_OP_LEGACY_SERVER_CONNECT | SSL_OP_TLSEXT_PADDING | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
| SSL_OP_LEGACY_SERVER_CONNECT
| SSL_OP_TLSEXT_PADDING
| SSL_OP_SAFARI_ECDHE_ECDSA_BUG; | SSL_OP_SAFARI_ECDHE_ECDSA_BUG;
pub const SSL_OP_NO_QUERY_MTU: c_ulong = 0x00001000; pub const SSL_OP_NO_QUERY_MTU: c_ulong = 0x00001000;
pub const SSL_OP_COOKIE_EXCHANGE: c_ulong = 0x00002000; pub const SSL_OP_COOKIE_EXCHANGE: c_ulong = 0x00002000;
@ -1289,8 +1293,11 @@ pub const SSL_OP_NO_TLSv1_2: c_ulong = 0x08000000;
pub const SSL_OP_NO_SSL_MASK: c_ulong = pub const SSL_OP_NO_SSL_MASK: c_ulong =
SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2; SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
#[cfg(ossl111)] #[cfg(ossl111)]
pub const SSL_OP_NO_SSL_MASK: c_ulong = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 pub const SSL_OP_NO_SSL_MASK: c_ulong = SSL_OP_NO_SSLv2
| SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_SSLv3
| SSL_OP_NO_TLSv1
| SSL_OP_NO_TLSv1_1
| SSL_OP_NO_TLSv1_2
| SSL_OP_NO_TLSv1_3; | SSL_OP_NO_TLSv1_3;
pub const SSL_FILETYPE_PEM: c_int = X509_FILETYPE_PEM; pub const SSL_FILETYPE_PEM: c_int = X509_FILETYPE_PEM;

View File

@ -1,19 +1,18 @@
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t};
use std::mem; use std::mem;
use std::ptr; use std::ptr;
use std::sync::{Mutex, MutexGuard}; use std::sync::{Mutex, MutexGuard};
use std::sync::{Once, ONCE_INIT}; use std::sync::{Once, ONCE_INIT};
#[cfg(libressl250)] #[cfg(not(libressl251))]
pub use libressl::v250::*; pub use libressl::v250::*;
#[cfg(not(libressl250))] #[cfg(libressl251)]
pub use libressl::v25x::*; pub use libressl::v251::*;
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t}; #[cfg(not(libressl251))]
#[cfg(libressl250)]
mod v250; mod v250;
#[cfg(not(libressl250))] #[cfg(libressl251)]
mod v25x; mod v251;
#[repr(C)] #[repr(C)]
pub struct stack_st_ASN1_OBJECT { pub struct stack_st_ASN1_OBJECT {
@ -337,9 +336,9 @@ pub const SSL_CTRL_OPTIONS: c_int = 32;
pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77; pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77;
pub const SSL_CTRL_SET_ECDH_AUTO: c_int = 94; pub const SSL_CTRL_SET_ECDH_AUTO: c_int = 94;
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))] #[cfg(libressl261)]
pub const SSL_OP_ALL: c_ulong = 0x4; pub const SSL_OP_ALL: c_ulong = 0x4;
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x)))] #[cfg(not(libressl261))]
pub const SSL_OP_ALL: c_ulong = 0x80000014; pub const SSL_OP_ALL: c_ulong = 0x80000014;
pub const SSL_OP_CISCO_ANYCONNECT: c_ulong = 0x0; pub const SSL_OP_CISCO_ANYCONNECT: c_ulong = 0x0;
pub const SSL_OP_NO_COMPRESSION: c_ulong = 0x0; pub const SSL_OP_NO_COMPRESSION: c_ulong = 0x0;
@ -352,9 +351,9 @@ pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: c_ulong = 0x0;
pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: c_ulong = 0x0; pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: c_ulong = 0x0;
pub const SSL_OP_TLS_D5_BUG: c_ulong = 0x0; pub const SSL_OP_TLS_D5_BUG: c_ulong = 0x0;
pub const SSL_OP_TLS_BLOCK_PADDING_BUG: c_ulong = 0x0; pub const SSL_OP_TLS_BLOCK_PADDING_BUG: c_ulong = 0x0;
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))] #[cfg(libressl261)]
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x0; pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x0;
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x)))] #[cfg(not(libressl261))]
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00080000; pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00080000;
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000; pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000;
pub const SSL_OP_NO_SSLv2: c_ulong = 0x0; pub const SSL_OP_NO_SSLv2: c_ulong = 0x0;
@ -540,6 +539,15 @@ extern "C" {
unsafe extern "C" fn(*mut ::SSL, *mut c_uchar, c_int, *mut c_int) -> *mut SSL_SESSION, unsafe extern "C" fn(*mut ::SSL, *mut c_uchar, c_int, *mut c_int) -> *mut SSL_SESSION,
>, >,
); );
#[cfg(libressl261)]
pub fn SSL_CTX_set_min_proto_version(ctx: *mut ::SSL_CTX, version: u16) -> c_int;
#[cfg(libressl261)]
pub fn SSL_CTX_set_max_proto_version(ctx: *mut ::SSL_CTX, version: u16) -> c_int;
#[cfg(libressl270)]
pub fn SSL_CTX_get_min_proto_version(ctx: *mut ::SSL_CTX) -> c_int;
#[cfg(libressl270)]
pub fn SSL_CTX_get_max_proto_version(ctx: *mut ::SSL_CTX) -> c_int;
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME; pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
pub fn X509_get_issuer_name(x: *mut ::X509) -> *mut ::X509_NAME; pub fn X509_get_issuer_name(x: *mut ::X509) -> *mut ::X509_NAME;
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int; pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;

View File

@ -1,4 +1,4 @@
use libc::{c_int, c_char, c_void, c_long, c_uchar, size_t, c_uint, c_ulong, time_t}; use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t, time_t};
use super::*; use super::*;
@ -84,6 +84,6 @@ pub struct X509_VERIFY_PARAM {
pub purpose: c_int, pub purpose: c_int,
pub trust: c_int, pub trust: c_int,
pub depth: c_int, pub depth: c_int,
policies: *mut stack_st_ASN1_OBJECT, pub policies: *mut stack_st_ASN1_OBJECT,
id: *mut c_void, id: *mut c_void,
} }

View File

@ -41,4 +41,16 @@ fn main() {
println!("cargo:rustc-cfg=ossl110g"); println!("cargo:rustc-cfg=ossl110g");
} }
} }
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");
}
}
} }

View File

@ -33,14 +33,14 @@
//! ``` //! ```
use ffi; use ffi;
use foreign_types::{ForeignType, ForeignTypeRef}; use foreign_types::{ForeignType, ForeignTypeRef};
use std::ptr;
use libc::c_int; use libc::c_int;
use std::ptr;
use {cvt, cvt_n, cvt_p, init};
use bn::{BigNumContextRef, BigNumRef}; use bn::{BigNumContextRef, BigNumRef};
use error::ErrorStack; use error::ErrorStack;
use nid::Nid; use nid::Nid;
use pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public}; use pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
use {cvt, cvt_n, cvt_p, init};
/// Compressed or Uncompressed conversion /// Compressed or Uncompressed conversion
/// ///
@ -803,10 +803,10 @@ impl<T> Clone for EcKey<T> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use bn::{BigNum, BigNumContext};
use nid::Nid;
use data_encoding::BASE64URL_NOPAD;
use super::*; use super::*;
use bn::{BigNum, BigNumContext};
use data_encoding::BASE64URL_NOPAD;
use nid::Nid;
#[test] #[test]
fn key_new_by_curve_name() { fn key_new_by_curve_name() {
@ -823,7 +823,7 @@ mod test {
fn dup() { fn dup() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap(); let key = EcKey::generate(&group).unwrap();
key.clone(); drop(key.clone());
} }
#[test] #[test]
@ -862,7 +862,8 @@ mod test {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap(); let key = EcKey::generate(&group).unwrap();
let mut ctx = BigNumContext::new().unwrap(); let mut ctx = BigNumContext::new().unwrap();
let bytes = key.public_key() let bytes = key
.public_key()
.to_bytes(&group, PointConversionForm::COMPRESSED, &mut ctx) .to_bytes(&group, PointConversionForm::COMPRESSED, &mut ctx)
.unwrap(); .unwrap();
@ -877,7 +878,8 @@ mod test {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).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(); let res = dup_key.check_key().unwrap();
assert!(res == ()); assert!(res == ());

View File

@ -751,7 +751,8 @@ mod test {
#[test] #[test]
fn test_to_password() { fn test_to_password() {
let key = Rsa::generate(2048).unwrap(); 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(); .unwrap();
Rsa::private_key_from_pem_passphrase(&pem, 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()); assert!(Rsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
@ -791,7 +792,8 @@ mod test {
k0.private_encrypt(&msg, &mut emesg, Padding::PKCS1) k0.private_encrypt(&msg, &mut emesg, Padding::PKCS1)
.unwrap(); .unwrap();
let mut dmesg = vec![0; k1.size() as usize]; 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(); .unwrap();
assert_eq!(msg, &dmesg[..len]); assert_eq!(msg, &dmesg[..len]);
} }
@ -807,7 +809,8 @@ mod test {
let mut emesg = vec![0; k0.size() as usize]; let mut emesg = vec![0; k0.size() as usize];
k0.public_encrypt(&msg, &mut emesg, Padding::PKCS1).unwrap(); k0.public_encrypt(&msg, &mut emesg, Padding::PKCS1).unwrap();
let mut dmesg = vec![0; k1.size() as usize]; 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(); .unwrap();
assert_eq!(msg, &dmesg[..len]); assert_eq!(msg, &dmesg[..len]);
} }
@ -883,6 +886,6 @@ mod test {
#[test] #[test]
fn clone() { fn clone() {
let key = Rsa::generate(2048).unwrap(); let key = Rsa::generate(2048).unwrap();
key.clone(); drop(key.clone());
} }
} }

View File

@ -1023,15 +1023,15 @@ impl SslContextBuilder {
/// ///
/// This corresponds to [`SSL_CTX_set_min_proto_version`]. /// 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 /// [`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> { pub fn set_min_proto_version(&mut self, version: Option<SslVersion>) -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt(ffi::SSL_CTX_set_min_proto_version( cvt(ffi::SSL_CTX_set_min_proto_version(
self.as_ptr(), self.as_ptr(),
version.map_or(0, |v| v.0), version.map_or(0, |v| v.0 as _),
)).map(|_| ()) )).map(|_| ())
} }
} }
@ -1043,15 +1043,15 @@ impl SslContextBuilder {
/// ///
/// This corresponds to [`SSL_CTX_set_max_proto_version`]. /// 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 /// [`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> { pub fn set_max_proto_version(&mut self, version: Option<SslVersion>) -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt(ffi::SSL_CTX_set_max_proto_version( cvt(ffi::SSL_CTX_set_max_proto_version(
self.as_ptr(), self.as_ptr(),
version.map_or(0, |v| v.0), version.map_or(0, |v| v.0 as _),
)).map(|_| ()) )).map(|_| ())
} }
} }
@ -1063,10 +1063,10 @@ impl SslContextBuilder {
/// ///
/// This corresponds to [`SSL_CTX_get_min_proto_version`]. /// 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 /// [`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> { pub fn min_proto_version(&mut self) -> Option<SslVersion> {
unsafe { unsafe {
let r = ffi::SSL_CTX_get_min_proto_version(self.as_ptr()); let r = ffi::SSL_CTX_get_min_proto_version(self.as_ptr());
@ -1085,10 +1085,10 @@ impl SslContextBuilder {
/// ///
/// This corresponds to [`SSL_CTX_get_max_proto_version`]. /// 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 /// [`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> { pub fn max_proto_version(&mut self) -> Option<SslVersion> {
unsafe { unsafe {
let r = ffi::SSL_CTX_get_max_proto_version(self.as_ptr()); let r = ffi::SSL_CTX_get_max_proto_version(self.as_ptr());
@ -2837,7 +2837,8 @@ impl<S: Read + Write> Read for SslStream<S> {
} }
Err(ref e) if e.code() == ErrorCode::WANT_READ && e.io_error().is_none() => {} Err(ref e) if e.code() == ErrorCode::WANT_READ && e.io_error().is_none() => {}
Err(e) => { 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))) .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e)))
} }
} }
@ -2852,7 +2853,8 @@ impl<S: Read + Write> Write for SslStream<S> {
Ok(n) => return Ok(n), Ok(n) => return Ok(n),
Err(ref e) if e.code() == ErrorCode::WANT_READ && e.io_error().is_none() => {} Err(ref e) if e.code() == ErrorCode::WANT_READ && e.io_error().is_none() => {}
Err(e) => { 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))) .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e)))
} }
} }

View File

@ -19,7 +19,7 @@ use hash::MessageDigest;
use ocsp::{OcspResponse, OcspResponseStatus}; use ocsp::{OcspResponse, OcspResponseStatus};
use pkey::PKey; use pkey::PKey;
use ssl; use ssl;
#[cfg(any(ossl110, ossl111))] #[cfg(any(ossl110, ossl111, libressl261))]
use ssl::SslVersion; use ssl::SslVersion;
use ssl::{ use ssl::{
Error, HandshakeError, MidHandshakeSslStream, ShutdownResult, Ssl, SslAcceptor, SslConnector, Error, HandshakeError, MidHandshakeSslStream, ShutdownResult, Ssl, SslAcceptor, SslConnector,
@ -1315,7 +1315,7 @@ fn keying_export() {
} }
#[test] #[test]
#[cfg(any(ossl110))] #[cfg(any(ossl110, libressl261))]
fn no_version_overlap() { fn no_version_overlap() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().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(); ctx.set_max_proto_version(Some(SslVersion::TLS1_1)).unwrap();
#[cfg(ossl110g)] #[cfg(ossl110g)]
assert_eq!(ctx.min_proto_version(), None); assert_eq!(ctx.min_proto_version(), None);
#[cfg(ossl110g)] #[cfg(any(ossl110g, libressl270))]
assert_eq!(ctx.max_proto_version(), Some(SslVersion::TLS1_1)); assert_eq!(ctx.max_proto_version(), Some(SslVersion::TLS1_1));
let ssl = Ssl::new(&ctx.build()).unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap();
ssl.accept(stream).unwrap_err(); ssl.accept(stream).unwrap_err();
@ -1339,7 +1339,7 @@ fn no_version_overlap() {
let stream = TcpStream::connect(addr).unwrap(); let stream = TcpStream::connect(addr).unwrap();
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_min_proto_version(Some(SslVersion::TLS1_2)).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)); assert_eq!(ctx.min_proto_version(), Some(SslVersion::TLS1_2));
#[cfg(ossl110g)] #[cfg(ossl110g)]
assert_eq!(ctx.max_proto_version(), None); assert_eq!(ctx.max_proto_version(), None);

View File

@ -7,10 +7,12 @@ use nid::Nid;
use pkey::{PKey, Private}; use pkey::{PKey, Private};
use rsa::Rsa; use rsa::Rsa;
use stack::Stack; use stack::Stack;
use x509::{X509, X509Name, X509Req, X509StoreContext, X509VerifyResult}; use x509::extension::{
use x509::extension::{AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName,
SubjectAlternativeName, SubjectKeyIdentifier}; SubjectKeyIdentifier,
};
use x509::store::X509StoreBuilder; use x509::store::X509StoreBuilder;
use x509::{X509, X509Name, X509Req, X509StoreContext, X509VerifyResult};
fn pkey() -> PKey<Private> { fn pkey() -> PKey<Private> {
let rsa = Rsa::generate(2048).unwrap(); let rsa = Rsa::generate(2048).unwrap();
@ -197,7 +199,8 @@ fn x509_builder() {
assert!(pkey.public_eq(&x509.public_key().unwrap())); assert!(pkey.public_eq(&x509.public_key().unwrap()));
let cn = x509.subject_name() let cn = x509
.subject_name()
.entries_by_nid(Nid::COMMONNAME) .entries_by_nid(Nid::COMMONNAME)
.next() .next()
.unwrap(); .unwrap();
@ -291,7 +294,7 @@ fn signature() {
fn clone_x509() { fn clone_x509() {
let cert = include_bytes!("../../test/cert.pem"); let cert = include_bytes!("../../test/cert.pem");
let cert = X509::from_pem(cert).unwrap(); let cert = X509::from_pem(cert).unwrap();
cert.clone(); drop(cert.clone());
} }
#[test] #[test]

View File

@ -2,10 +2,12 @@ extern crate ctest;
use std::env; use std::env;
#[path = "../openssl-sys/build/cfgs.rs"]
mod cfgs;
fn main() { fn main() {
let mut cfg = ctest::TestGenerator::new(); let mut cfg = ctest::TestGenerator::new();
let target = env::var("TARGET").unwrap(); let target = env::var("TARGET").unwrap();
let mut is_libressl = false;
if let Ok(out) = env::var("DEP_OPENSSL_INCLUDE") { if let Ok(out) = env::var("DEP_OPENSSL_INCLUDE") {
cfg.include(&out); cfg.include(&out);
@ -26,21 +28,17 @@ fn main() {
cfg.define("WIN32_LEAN_AND_MEAN", None); cfg.define("WIN32_LEAN_AND_MEAN", None);
} }
if let Ok(_) = env::var("DEP_OPENSSL_LIBRESSL") { let openssl_version = env::var("DEP_OPENSSL_VERSION_NUMBER")
cfg.cfg("libressl", None); .ok()
is_libressl = true; .map(|v| u64::from_str_radix(&v, 16).unwrap());
} else if let Ok(version) = env::var("DEP_OPENSSL_VERSION") { let libressl_version = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER")
cfg.cfg(&format!("ossl{}", version), None); .ok()
if version == "111" { .map(|v| u64::from_str_radix(&v, 16).unwrap());
cfg.cfg("ossl110", None);
} for c in cfgs::get(openssl_version, libressl_version) {
} cfg.cfg(c, None);
if let (Ok(version), Ok(patch)) = (
env::var("DEP_OPENSSL_VERSION"),
env::var("DEP_OPENSSL_PATCH"),
) {
cfg.cfg(&format!("ossl{}{}", version, patch), None);
} }
if let Ok(vars) = env::var("DEP_OPENSSL_CONF") { if let Ok(vars) = env::var("DEP_OPENSSL_CONF") {
for var in vars.split(",") { for var in vars.split(",") {
cfg.cfg("osslconf", Some(var)); cfg.cfg("osslconf", Some(var));
@ -65,7 +63,7 @@ fn main() {
.header("openssl/ocsp.h") .header("openssl/ocsp.h")
.header("openssl/evp.h"); .header("openssl/evp.h");
if !is_libressl { if openssl_version.is_some() {
cfg.header("openssl/cms.h"); cfg.header("openssl/cms.h");
} }
@ -79,7 +77,8 @@ fn main() {
} else if s == "_STACK" { } else if s == "_STACK" {
format!("struct stack_st") format!("struct stack_st")
// This logic should really be cleaned up // This logic should really be cleaned up
} else if is_struct && s != "point_conversion_form_t" } else if is_struct
&& s != "point_conversion_form_t"
&& s.chars().next().unwrap().is_lowercase() && s.chars().next().unwrap().is_lowercase()
{ {
format!("struct {}", s) format!("struct {}", s)
@ -111,9 +110,13 @@ fn main() {
(s == "GENERAL_NAME" && field == "d") // union (s == "GENERAL_NAME" && field == "d") // union
}); });
cfg.skip_signededness(|s| { cfg.skip_signededness(|s| {
s.ends_with("_cb") || s.ends_with("_CB") || s.ends_with("_cb_fn") s.ends_with("_cb")
|| s.starts_with("CRYPTO_") || s == "PasswordCallback" || s.ends_with("_CB")
|| s.ends_with("_cb_func") || s.ends_with("_cb_ex") || s.ends_with("_cb_fn")
|| s.starts_with("CRYPTO_")
|| s == "PasswordCallback"
|| s.ends_with("_cb_func")
|| s.ends_with("_cb_ex")
}); });
cfg.field_name(|_s, field| { cfg.field_name(|_s, field| {
if field == "type_" { if field == "type_" {