Loading .travis.yml +6 −6 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ matrix: # ARM-bit version compat - env: > TARGET=arm-unknown-linux-gnueabihf BUILD_OPENSSL_VERSION=1.0.2h BUILD_OPENSSL_VERSION=1.0.2k CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf RUST_TEST_THREADS=1 Loading @@ -32,7 +32,7 @@ matrix: - binfmt-support - env: > TARGET=arm-unknown-linux-gnueabihf BUILD_OPENSSL_VERSION=1.1.0c BUILD_OPENSSL_VERSION=1.1.0d CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf RUST_TEST_THREADS=1 Loading @@ -52,8 +52,8 @@ matrix: - rust: nightly # 64-bit version compat - env: BUILD_OPENSSL_VERSION=1.0.2h - env: BUILD_OPENSSL_VERSION=1.1.0c - env: BUILD_OPENSSL_VERSION=1.0.2k - env: BUILD_OPENSSL_VERSION=1.1.0d # 32-bit version compat - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.0.1u Loading @@ -61,12 +61,12 @@ matrix: apt: packages: - gcc-multilib - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.0.2h - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.0.2k addons: apt: packages: - gcc-multilib - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.1.0c - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.1.0d addons: apt: packages: Loading appveyor.yml +4 −4 Original line number Diff line number Diff line Loading @@ -5,20 +5,20 @@ environment: - TARGET: i686-pc-windows-gnu BITS: 32 MSYS2: 1 OPENSSL_VERSION: 1_1_0c OPENSSL_VERSION: 1_1_0d - TARGET: x86_64-pc-windows-msvc BITS: 64 OPENSSL_VERSION: 1_1_0c OPENSSL_VERSION: 1_1_0d OPENSSL_DIR: C:\OpenSSL # 1.0.2, 64/32 bit - TARGET: x86_64-pc-windows-gnu BITS: 64 MSYS2: 1 OPENSSL_VERSION: 1_0_2j OPENSSL_VERSION: 1_0_2k - TARGET: i686-pc-windows-msvc BITS: 32 OPENSSL_VERSION: 1_0_2j OPENSSL_VERSION: 1_0_2k OPENSSL_DIR: C:\OpenSSL install: # install OpenSSL Loading openssl-sys/Cargo.toml +2 −1 Original line number Diff line number Diff line Loading @@ -16,11 +16,12 @@ libc = "0.2" [build-dependencies] pkg-config = "0.3.9" gcc = "0.3.42" [target.'cfg(windows)'.dependencies] user32-sys = "0.2" gdi32-sys = "0.2" # We don't actually use metadeps for annoying reasons but this is still hear for tooling # We don't actually use metadeps for annoying reasons but this is still here for tooling [package.metadata.pkg-config] openssl = "1.0.1" openssl-sys/build.rs +132 −165 Original line number Diff line number Diff line extern crate pkg_config; extern crate gcc; use std::collections::HashSet; use std::env; use std::ffi::OsString; use std::fs::File; use std::io::Read; use std::io::{BufWriter, Write}; use std::path::{Path, PathBuf}; use std::panic::{self, AssertUnwindSafe}; use std::process::Command; // The set of `OPENSSL_NO_<FOO>`s that we care about. const DEFINES: &'static [&'static str] = &[ "OPENSSL_NO_BUF_FREELISTS", "OPENSSL_NO_COMP", "OPENSSL_NO_EC", "OPENSSL_NO_ENGINE", "OPENSSL_NO_KRB5", "OPENSSL_NO_NEXTPROTONEG", "OPENSSL_NO_PSK", "OPENSSL_NO_RFC3779", "OPENSSL_NO_SHA", "OPENSSL_NO_SRP", "OPENSSL_NO_SSL3_METHOD", "OPENSSL_NO_TLSEXT", ]; enum Version { Openssl110, Openssl102, Openssl101, Libressl, } fn main() { let target = env::var("TARGET").unwrap(); Loading Loading @@ -38,17 +63,14 @@ fn main() { println!("cargo:rustc-link-search=native={}", lib_dir.to_string_lossy()); println!("cargo:include={}", include_dir.to_string_lossy()); let version = validate_headers(&[include_dir.clone().into()], &[lib_dir.clone().into()]); let version = validate_headers(&[include_dir.clone().into()]); let libs = if (version.contains("0x10001") || version.contains("0x10002")) && target.contains("windows") { let libs = match version { Version::Openssl101 | Version::Openssl102 if target.contains("windows") => { ["ssleay32", "libeay32"] } else if target.contains("windows") { ["libssl", "libcrypto"] } else { ["ssl", "crypto"] } Version::Openssl110 if target.contains("windows") => ["libssl", "libcrypto"], _ => ["ssl", "crypto"], }; let kind = determine_mode(Path::new(&lib_dir), &libs); Loading Loading @@ -168,29 +190,79 @@ fn try_pkg_config() { return } // We're going to be looking at header files, so show us all the system // cflags dirs for showing us lots of `-I`. env::set_var("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS", "1"); // This is more complex than normal because we need to track down opensslconf.h. // To do that, we need the inlude paths even if they're on the default search path, but the // linkage directories emitted from that cause all kinds of issues if other libraries happen to // live in them. So, we run pkg-config twice, once asking for system dirs but not emitting // metadata, and a second time emitting metadata but not asking for system dirs. Yay. let lib = match pkg_config::Config::new() .cargo_metadata(false) .print_system_libs(true) .find("openssl") { Ok(lib) => lib, Err(_) => return, }; let lib = pkg_config::Config::new() .print_system_libs(false) .find("openssl") .unwrap(); if lib.include_paths.len() == 0 { panic!(" validate_headers(&lib.include_paths); for include in lib.include_paths.iter() { println!("cargo:include={}", include.display()); } Used pkg-config to discover the OpenSSL installation, but pkg-config did not return any include paths for the installation. This crate needs to take a peek at the header files so it cannot proceed unless they're found. std::process::exit(0); } /// Validates the header files found in `include_dir` and then returns the /// version string of OpenSSL. fn validate_headers(include_dirs: &[PathBuf]) -> Version { // This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, and 1.1.0. To // correctly expose the right API from this crate, take a look at // `opensslv.h` to see what version OpenSSL claims to be. // // OpenSSL has a number of build-time configuration options which affect // various structs and such. Since OpenSSL 1.1.0 this isn't really a problem // as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem. // // To handle all this conditional compilation we slurp up the configuration // file of OpenSSL, `opensslconf.h`, and then dump out everything it defines // as our own #[cfg] directives. That way the `ossl10x.rs` bindings can // account for compile differences and such. let mut path = PathBuf::from(env::var_os("OUT_DIR").unwrap()); path.push("expando.c"); let mut file = BufWriter::new(File::create(&path).unwrap()); write!(file, "\ #include <openssl/opensslv.h> #include <openssl/opensslconf.h> #ifdef LIBRESSL_VERSION_NUMBER RUST_LIBRESSL #elif OPENSSL_VERSION_NUMBER >= 0x10200000 RUST_OPENSSL_NEW #elif OPENSSL_VERSION_NUMBER >= 0x10100000 RUST_OPENSSL_110 #elif OPENSSL_VERSION_NUMBER >= 0x10002000 RUST_OPENSSL_102 #elif OPENSSL_VERSION_NUMBER >= 0x10001000 RUST_OPENSSL_101 #else RUST_OPENSSL_OLD #endif ").unwrap(); for define in DEFINES { write!(file, "\ #ifdef {define} RUST_{define} #endif ", define = define).unwrap(); } file.flush().unwrap(); drop(file); let mut gcc = gcc::Config::new(); for include_dir in include_dirs { gcc.include(include_dir); } // https://github.com/alexcrichton/gcc-rs/issues/133 let expanded = match panic::catch_unwind(AssertUnwindSafe(|| gcc.file(&path).expand())) { Ok(expanded) => expanded, Err(_) => { panic!(" Failed to find OpenSSL development headers. You can try fixing this setting the `OPENSSL_DIR` environment variable pointing to your OpenSSL installation or installing OpenSSL headers package Loading @@ -208,149 +280,44 @@ See rust-openssl README for more information: https://github.com/sfackler/rust-openssl#linux "); } }; let expanded = String::from_utf8(expanded).unwrap(); validate_headers(&lib.include_paths, &lib.link_paths); for include in lib.include_paths.iter() { println!("cargo:include={}", include.display()); let mut enabled = vec![]; for &define in DEFINES { if expanded.contains(&format!("RUST_{}", define)) { println!("cargo:rustc-cfg=osslconf=\"{}\"", define); enabled.push(define); } pkg_config::Config::new() .print_system_libs(false) .find("openssl") .unwrap(); std::process::exit(0); } println!("cargo:conf={}", enabled.join(",")); /// Validates the header files found in `include_dir` and then returns the /// version string of OpenSSL. fn validate_headers(include_dirs: &[PathBuf], libdirs: &[PathBuf]) -> String { // This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, and 1.1.0. To // correctly expose the right API from this crate, take a look at // `opensslv.h` to see what version OpenSSL claims to be. let mut version_header = String::new(); let mut include = include_dirs.iter() .map(|p| p.join("openssl/opensslv.h")) .filter(|p| p.exists()); let mut f = match include.next() { Some(f) => File::open(f).unwrap(), None => { panic!("failed to open header file at `openssl/opensslv.h` to learn about OpenSSL's version number, looked inside:\n\n{:#?}\n\n", include_dirs); } }; f.read_to_string(&mut version_header).unwrap(); // Do a bit of string parsing to find `#define OPENSSL_VERSION_NUMBER ...` let version_line = version_header.lines().find(|l| { l.contains("define ") && l.contains("OPENSSL_VERSION_NUMBER") }).and_then(|line| { let start = match line.find("0x") { Some(start) => start, None => return None, }; Some(line[start..].trim()) }); let version_text = match version_line { Some(text) => text, None => { panic!("header file at `{}` did not include `OPENSSL_VERSION_NUMBER` \ that this crate recognized, failed to learn about the \ OpenSSL version number"); } }; if version_text.contains("0x10001") { println!("cargo:rustc-cfg=ossl101"); if expanded.contains("RUST_LIBRESSL") { println!("cargo:rustc-cfg=libressl"); println!("cargo:libressl=true"); println!("cargo:version=101"); } else if version_text.contains("0x10002") { println!("cargo:rustc-cfg=ossl102"); println!("cargo:version=102"); } else if version_text.contains("0x10100") { Version::Libressl } else if expanded.contains("RUST_OPENSSL_110") { println!("cargo:rustc-cfg=ossl110"); println!("cargo:version=110"); } else if version_text.contains("0x20000000L") { // Check if it is really LibreSSL if version_header.lines().any(|l| { l.contains("define ") && l.contains("LIBRESSL_VERSION_NUMBER") }) { println!("cargo:rustc-cfg=libressl"); println!("cargo:libressl=true"); Version::Openssl110 } else if expanded.contains("RUST_OPENSSL_102") { println!("cargo:rustc-cfg=ossl102"); println!("cargo:version=102"); Version::Openssl102 } else if expanded.contains("RUST_OPENSSL_101") { println!("cargo:rustc-cfg=ossl101"); println!("cargo:version=101"); } Version::Openssl101 } else { panic!(" This crate is only compatible with OpenSSL 1.0.1, 1.0.2, and 1.1.0, but a different version of OpenSSL was found: This crate is only compatible with OpenSSL 1.0.1, 1.0.2, and 1.1.0, or LibreSSL, but a different version of OpenSSL was found. The build is now aborting due to this version mismatch. {} The build is now aborting due to this version mismatch. ", version_text); } // OpenSSL has a number of build-time configuration options which affect // various structs and such. Since OpenSSL 1.1.0 this isn't really a problem // as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem. // // To handle all this conditional compilation we slurp up the configuration // file of OpenSSL, `opensslconf.h`, and then dump out everything it defines // as our own #[cfg] directives. That way the `ossl10x.rs` bindings can // account for compile differences and such. let mut conf_header = String::new(); let mut include = include_dirs.iter() .map(|p| p.join("openssl/opensslconf.h")) .filter(|p| p.exists()); let mut f = match include.next() { Some(f) => File::open(f).unwrap(), None => { // It's been seen that on linux the include dir printed out by // `pkg-config` doesn't actually have opensslconf.h. Instead // it's in an architecture-specific include directory. // // Try to detect that case to see if it exists. let mut libdirs = libdirs.iter().map(|p| { p.iter() .map(|p| if p == "lib" {"include".as_ref()} else {p}) .collect::<PathBuf>() }).map(|p| { p.join("openssl/opensslconf.h") }).filter(|p| p.exists()); match libdirs.next() { Some(f) => File::open(f).unwrap(), None => { panic!("failed to open header file at `openssl/opensslconf.h` to learn about \ OpenSSL's version number, looked \ inside:\n\n{:#?}\n\n", include_dirs); } } } }; f.read_to_string(&mut conf_header).unwrap(); // Look for `#define OPENSSL_FOO`, print out everything as our own // #[cfg] flag. let mut vars = vec![]; for line in conf_header.lines() { let i = match line.find("define ") { Some(i) => i, None => continue, }; let var = line[i + "define ".len()..].trim(); if var.starts_with("OPENSSL") && !var.contains(" ") { println!("cargo:rustc-cfg=osslconf=\"{}\"", var); vars.push(var); } "); } println!("cargo:conf={}", vars.join(",")); return version_text.to_string() } /// Given a libdir for OpenSSL (where artifacts are located) as well as the name Loading openssl-sys/src/lib.rs +18 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,12 @@ pub const EVP_PKEY_DSA: c_int = NID_dsa; pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement; pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey; pub const EVP_PKEY_ALG_CTRL: c_int = 0x1000; pub const EVP_PKEY_CTRL_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 1; pub const EVP_PKEY_CTRL_GET_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 6; pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9; pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10; pub const EVP_CTRL_GCM_SET_TAG: c_int = 0x11; Loading Loading @@ -1303,6 +1309,15 @@ pub unsafe fn BIO_set_retry_write(b: *mut BIO) { BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY) } // EVP_PKEY_CTX_ctrl macros pub unsafe fn EVP_PKEY_CTX_set_rsa_padding(ctx: *mut EVP_PKEY_CTX, pad: c_int) -> c_int { EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, ptr::null_mut()) } pub unsafe fn EVP_PKEY_CTX_get_rsa_padding(ctx: *mut EVP_PKEY_CTX, ppad: *mut c_int) -> c_int { EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad as *mut c_void) } pub unsafe fn SSL_CTX_set_mode(ctx: *mut SSL_CTX, op: c_long) -> c_long { SSL_CTX_ctrl(ctx, SSL_CTRL_MODE, op, ptr::null_mut()) } Loading Loading @@ -1632,6 +1647,9 @@ extern { key: *const c_uchar, keylen: c_int) -> *mut EVP_PKEY; pub fn EVP_PKEY_CTX_ctrl(ctx: *mut EVP_PKEY_CTX, keytype: c_int, optype: c_int, cmd: c_int, p1: c_int, p2: *mut c_void) -> c_int; pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int; pub fn OCSP_BASICRESP_new() -> *mut OCSP_BASICRESP; Loading Loading
.travis.yml +6 −6 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ matrix: # ARM-bit version compat - env: > TARGET=arm-unknown-linux-gnueabihf BUILD_OPENSSL_VERSION=1.0.2h BUILD_OPENSSL_VERSION=1.0.2k CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf RUST_TEST_THREADS=1 Loading @@ -32,7 +32,7 @@ matrix: - binfmt-support - env: > TARGET=arm-unknown-linux-gnueabihf BUILD_OPENSSL_VERSION=1.1.0c BUILD_OPENSSL_VERSION=1.1.0d CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf RUST_TEST_THREADS=1 Loading @@ -52,8 +52,8 @@ matrix: - rust: nightly # 64-bit version compat - env: BUILD_OPENSSL_VERSION=1.0.2h - env: BUILD_OPENSSL_VERSION=1.1.0c - env: BUILD_OPENSSL_VERSION=1.0.2k - env: BUILD_OPENSSL_VERSION=1.1.0d # 32-bit version compat - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.0.1u Loading @@ -61,12 +61,12 @@ matrix: apt: packages: - gcc-multilib - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.0.2h - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.0.2k addons: apt: packages: - gcc-multilib - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.1.0c - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.1.0d addons: apt: packages: Loading
appveyor.yml +4 −4 Original line number Diff line number Diff line Loading @@ -5,20 +5,20 @@ environment: - TARGET: i686-pc-windows-gnu BITS: 32 MSYS2: 1 OPENSSL_VERSION: 1_1_0c OPENSSL_VERSION: 1_1_0d - TARGET: x86_64-pc-windows-msvc BITS: 64 OPENSSL_VERSION: 1_1_0c OPENSSL_VERSION: 1_1_0d OPENSSL_DIR: C:\OpenSSL # 1.0.2, 64/32 bit - TARGET: x86_64-pc-windows-gnu BITS: 64 MSYS2: 1 OPENSSL_VERSION: 1_0_2j OPENSSL_VERSION: 1_0_2k - TARGET: i686-pc-windows-msvc BITS: 32 OPENSSL_VERSION: 1_0_2j OPENSSL_VERSION: 1_0_2k OPENSSL_DIR: C:\OpenSSL install: # install OpenSSL Loading
openssl-sys/Cargo.toml +2 −1 Original line number Diff line number Diff line Loading @@ -16,11 +16,12 @@ libc = "0.2" [build-dependencies] pkg-config = "0.3.9" gcc = "0.3.42" [target.'cfg(windows)'.dependencies] user32-sys = "0.2" gdi32-sys = "0.2" # We don't actually use metadeps for annoying reasons but this is still hear for tooling # We don't actually use metadeps for annoying reasons but this is still here for tooling [package.metadata.pkg-config] openssl = "1.0.1"
openssl-sys/build.rs +132 −165 Original line number Diff line number Diff line extern crate pkg_config; extern crate gcc; use std::collections::HashSet; use std::env; use std::ffi::OsString; use std::fs::File; use std::io::Read; use std::io::{BufWriter, Write}; use std::path::{Path, PathBuf}; use std::panic::{self, AssertUnwindSafe}; use std::process::Command; // The set of `OPENSSL_NO_<FOO>`s that we care about. const DEFINES: &'static [&'static str] = &[ "OPENSSL_NO_BUF_FREELISTS", "OPENSSL_NO_COMP", "OPENSSL_NO_EC", "OPENSSL_NO_ENGINE", "OPENSSL_NO_KRB5", "OPENSSL_NO_NEXTPROTONEG", "OPENSSL_NO_PSK", "OPENSSL_NO_RFC3779", "OPENSSL_NO_SHA", "OPENSSL_NO_SRP", "OPENSSL_NO_SSL3_METHOD", "OPENSSL_NO_TLSEXT", ]; enum Version { Openssl110, Openssl102, Openssl101, Libressl, } fn main() { let target = env::var("TARGET").unwrap(); Loading Loading @@ -38,17 +63,14 @@ fn main() { println!("cargo:rustc-link-search=native={}", lib_dir.to_string_lossy()); println!("cargo:include={}", include_dir.to_string_lossy()); let version = validate_headers(&[include_dir.clone().into()], &[lib_dir.clone().into()]); let version = validate_headers(&[include_dir.clone().into()]); let libs = if (version.contains("0x10001") || version.contains("0x10002")) && target.contains("windows") { let libs = match version { Version::Openssl101 | Version::Openssl102 if target.contains("windows") => { ["ssleay32", "libeay32"] } else if target.contains("windows") { ["libssl", "libcrypto"] } else { ["ssl", "crypto"] } Version::Openssl110 if target.contains("windows") => ["libssl", "libcrypto"], _ => ["ssl", "crypto"], }; let kind = determine_mode(Path::new(&lib_dir), &libs); Loading Loading @@ -168,29 +190,79 @@ fn try_pkg_config() { return } // We're going to be looking at header files, so show us all the system // cflags dirs for showing us lots of `-I`. env::set_var("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS", "1"); // This is more complex than normal because we need to track down opensslconf.h. // To do that, we need the inlude paths even if they're on the default search path, but the // linkage directories emitted from that cause all kinds of issues if other libraries happen to // live in them. So, we run pkg-config twice, once asking for system dirs but not emitting // metadata, and a second time emitting metadata but not asking for system dirs. Yay. let lib = match pkg_config::Config::new() .cargo_metadata(false) .print_system_libs(true) .find("openssl") { Ok(lib) => lib, Err(_) => return, }; let lib = pkg_config::Config::new() .print_system_libs(false) .find("openssl") .unwrap(); if lib.include_paths.len() == 0 { panic!(" validate_headers(&lib.include_paths); for include in lib.include_paths.iter() { println!("cargo:include={}", include.display()); } Used pkg-config to discover the OpenSSL installation, but pkg-config did not return any include paths for the installation. This crate needs to take a peek at the header files so it cannot proceed unless they're found. std::process::exit(0); } /// Validates the header files found in `include_dir` and then returns the /// version string of OpenSSL. fn validate_headers(include_dirs: &[PathBuf]) -> Version { // This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, and 1.1.0. To // correctly expose the right API from this crate, take a look at // `opensslv.h` to see what version OpenSSL claims to be. // // OpenSSL has a number of build-time configuration options which affect // various structs and such. Since OpenSSL 1.1.0 this isn't really a problem // as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem. // // To handle all this conditional compilation we slurp up the configuration // file of OpenSSL, `opensslconf.h`, and then dump out everything it defines // as our own #[cfg] directives. That way the `ossl10x.rs` bindings can // account for compile differences and such. let mut path = PathBuf::from(env::var_os("OUT_DIR").unwrap()); path.push("expando.c"); let mut file = BufWriter::new(File::create(&path).unwrap()); write!(file, "\ #include <openssl/opensslv.h> #include <openssl/opensslconf.h> #ifdef LIBRESSL_VERSION_NUMBER RUST_LIBRESSL #elif OPENSSL_VERSION_NUMBER >= 0x10200000 RUST_OPENSSL_NEW #elif OPENSSL_VERSION_NUMBER >= 0x10100000 RUST_OPENSSL_110 #elif OPENSSL_VERSION_NUMBER >= 0x10002000 RUST_OPENSSL_102 #elif OPENSSL_VERSION_NUMBER >= 0x10001000 RUST_OPENSSL_101 #else RUST_OPENSSL_OLD #endif ").unwrap(); for define in DEFINES { write!(file, "\ #ifdef {define} RUST_{define} #endif ", define = define).unwrap(); } file.flush().unwrap(); drop(file); let mut gcc = gcc::Config::new(); for include_dir in include_dirs { gcc.include(include_dir); } // https://github.com/alexcrichton/gcc-rs/issues/133 let expanded = match panic::catch_unwind(AssertUnwindSafe(|| gcc.file(&path).expand())) { Ok(expanded) => expanded, Err(_) => { panic!(" Failed to find OpenSSL development headers. You can try fixing this setting the `OPENSSL_DIR` environment variable pointing to your OpenSSL installation or installing OpenSSL headers package Loading @@ -208,149 +280,44 @@ See rust-openssl README for more information: https://github.com/sfackler/rust-openssl#linux "); } }; let expanded = String::from_utf8(expanded).unwrap(); validate_headers(&lib.include_paths, &lib.link_paths); for include in lib.include_paths.iter() { println!("cargo:include={}", include.display()); let mut enabled = vec![]; for &define in DEFINES { if expanded.contains(&format!("RUST_{}", define)) { println!("cargo:rustc-cfg=osslconf=\"{}\"", define); enabled.push(define); } pkg_config::Config::new() .print_system_libs(false) .find("openssl") .unwrap(); std::process::exit(0); } println!("cargo:conf={}", enabled.join(",")); /// Validates the header files found in `include_dir` and then returns the /// version string of OpenSSL. fn validate_headers(include_dirs: &[PathBuf], libdirs: &[PathBuf]) -> String { // This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, and 1.1.0. To // correctly expose the right API from this crate, take a look at // `opensslv.h` to see what version OpenSSL claims to be. let mut version_header = String::new(); let mut include = include_dirs.iter() .map(|p| p.join("openssl/opensslv.h")) .filter(|p| p.exists()); let mut f = match include.next() { Some(f) => File::open(f).unwrap(), None => { panic!("failed to open header file at `openssl/opensslv.h` to learn about OpenSSL's version number, looked inside:\n\n{:#?}\n\n", include_dirs); } }; f.read_to_string(&mut version_header).unwrap(); // Do a bit of string parsing to find `#define OPENSSL_VERSION_NUMBER ...` let version_line = version_header.lines().find(|l| { l.contains("define ") && l.contains("OPENSSL_VERSION_NUMBER") }).and_then(|line| { let start = match line.find("0x") { Some(start) => start, None => return None, }; Some(line[start..].trim()) }); let version_text = match version_line { Some(text) => text, None => { panic!("header file at `{}` did not include `OPENSSL_VERSION_NUMBER` \ that this crate recognized, failed to learn about the \ OpenSSL version number"); } }; if version_text.contains("0x10001") { println!("cargo:rustc-cfg=ossl101"); if expanded.contains("RUST_LIBRESSL") { println!("cargo:rustc-cfg=libressl"); println!("cargo:libressl=true"); println!("cargo:version=101"); } else if version_text.contains("0x10002") { println!("cargo:rustc-cfg=ossl102"); println!("cargo:version=102"); } else if version_text.contains("0x10100") { Version::Libressl } else if expanded.contains("RUST_OPENSSL_110") { println!("cargo:rustc-cfg=ossl110"); println!("cargo:version=110"); } else if version_text.contains("0x20000000L") { // Check if it is really LibreSSL if version_header.lines().any(|l| { l.contains("define ") && l.contains("LIBRESSL_VERSION_NUMBER") }) { println!("cargo:rustc-cfg=libressl"); println!("cargo:libressl=true"); Version::Openssl110 } else if expanded.contains("RUST_OPENSSL_102") { println!("cargo:rustc-cfg=ossl102"); println!("cargo:version=102"); Version::Openssl102 } else if expanded.contains("RUST_OPENSSL_101") { println!("cargo:rustc-cfg=ossl101"); println!("cargo:version=101"); } Version::Openssl101 } else { panic!(" This crate is only compatible with OpenSSL 1.0.1, 1.0.2, and 1.1.0, but a different version of OpenSSL was found: This crate is only compatible with OpenSSL 1.0.1, 1.0.2, and 1.1.0, or LibreSSL, but a different version of OpenSSL was found. The build is now aborting due to this version mismatch. {} The build is now aborting due to this version mismatch. ", version_text); } // OpenSSL has a number of build-time configuration options which affect // various structs and such. Since OpenSSL 1.1.0 this isn't really a problem // as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem. // // To handle all this conditional compilation we slurp up the configuration // file of OpenSSL, `opensslconf.h`, and then dump out everything it defines // as our own #[cfg] directives. That way the `ossl10x.rs` bindings can // account for compile differences and such. let mut conf_header = String::new(); let mut include = include_dirs.iter() .map(|p| p.join("openssl/opensslconf.h")) .filter(|p| p.exists()); let mut f = match include.next() { Some(f) => File::open(f).unwrap(), None => { // It's been seen that on linux the include dir printed out by // `pkg-config` doesn't actually have opensslconf.h. Instead // it's in an architecture-specific include directory. // // Try to detect that case to see if it exists. let mut libdirs = libdirs.iter().map(|p| { p.iter() .map(|p| if p == "lib" {"include".as_ref()} else {p}) .collect::<PathBuf>() }).map(|p| { p.join("openssl/opensslconf.h") }).filter(|p| p.exists()); match libdirs.next() { Some(f) => File::open(f).unwrap(), None => { panic!("failed to open header file at `openssl/opensslconf.h` to learn about \ OpenSSL's version number, looked \ inside:\n\n{:#?}\n\n", include_dirs); } } } }; f.read_to_string(&mut conf_header).unwrap(); // Look for `#define OPENSSL_FOO`, print out everything as our own // #[cfg] flag. let mut vars = vec![]; for line in conf_header.lines() { let i = match line.find("define ") { Some(i) => i, None => continue, }; let var = line[i + "define ".len()..].trim(); if var.starts_with("OPENSSL") && !var.contains(" ") { println!("cargo:rustc-cfg=osslconf=\"{}\"", var); vars.push(var); } "); } println!("cargo:conf={}", vars.join(",")); return version_text.to_string() } /// Given a libdir for OpenSSL (where artifacts are located) as well as the name Loading
openssl-sys/src/lib.rs +18 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,12 @@ pub const EVP_PKEY_DSA: c_int = NID_dsa; pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement; pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey; pub const EVP_PKEY_ALG_CTRL: c_int = 0x1000; pub const EVP_PKEY_CTRL_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 1; pub const EVP_PKEY_CTRL_GET_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 6; pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9; pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10; pub const EVP_CTRL_GCM_SET_TAG: c_int = 0x11; Loading Loading @@ -1303,6 +1309,15 @@ pub unsafe fn BIO_set_retry_write(b: *mut BIO) { BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY) } // EVP_PKEY_CTX_ctrl macros pub unsafe fn EVP_PKEY_CTX_set_rsa_padding(ctx: *mut EVP_PKEY_CTX, pad: c_int) -> c_int { EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, ptr::null_mut()) } pub unsafe fn EVP_PKEY_CTX_get_rsa_padding(ctx: *mut EVP_PKEY_CTX, ppad: *mut c_int) -> c_int { EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad as *mut c_void) } pub unsafe fn SSL_CTX_set_mode(ctx: *mut SSL_CTX, op: c_long) -> c_long { SSL_CTX_ctrl(ctx, SSL_CTRL_MODE, op, ptr::null_mut()) } Loading Loading @@ -1632,6 +1647,9 @@ extern { key: *const c_uchar, keylen: c_int) -> *mut EVP_PKEY; pub fn EVP_PKEY_CTX_ctrl(ctx: *mut EVP_PKEY_CTX, keytype: c_int, optype: c_int, cmd: c_int, p1: c_int, p2: *mut c_void) -> c_int; pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int; pub fn OCSP_BASICRESP_new() -> *mut OCSP_BASICRESP; Loading