diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..5b064754 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "openssl-sys/deps/boringssl"] + path = openssl-sys/deps/boringssl + url = https://github.com/google/boringssl.git + ignore = dirty \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 3ad379d5..ea6b6572 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,5 @@ [workspace] members = [ "openssl", - "openssl-errors", "openssl-sys", - "systest", ] diff --git a/openssl-errors/CHANGELOG.md b/openssl-errors/CHANGELOG.md deleted file mode 100644 index 6d33fa1f..00000000 --- a/openssl-errors/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -# Change Log - -## [Unreleased] - -## v0.1.0 - 2019-03-14 - -Initial release - -[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-errors-v0.1.0...master diff --git a/openssl-errors/Cargo.toml b/openssl-errors/Cargo.toml deleted file mode 100644 index 45181ddc..00000000 --- a/openssl-errors/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "openssl-errors" -version = "0.1.0" -authors = ["Steven Fackler "] -edition = "2018" -license = "MIT/Apache-2.0" -description = "Custom error library support for the openssl crate." -repository = "https://github.com/sfackler/rust-openssl" -readme = "README.md" -categories = ["api-bindings"] - -[dependencies] -libc = "0.2" - -openssl-sys = { version = "0.9.42", path = "../openssl-sys" } - -[dev-dependencies] -openssl = { version = "0.10.19", path = "../openssl" } diff --git a/openssl-errors/LICENSE-APACHE b/openssl-errors/LICENSE-APACHE deleted file mode 100644 index 8f71f43f..00000000 --- a/openssl-errors/LICENSE-APACHE +++ /dev/null @@ -1,202 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/openssl-errors/LICENSE-MIT b/openssl-errors/LICENSE-MIT deleted file mode 100644 index 7c3deb5b..00000000 --- a/openssl-errors/LICENSE-MIT +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2019 Steven Fackler - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/openssl-errors/README.md b/openssl-errors/README.md deleted file mode 120000 index 32d46ee8..00000000 --- a/openssl-errors/README.md +++ /dev/null @@ -1 +0,0 @@ -../README.md \ No newline at end of file diff --git a/openssl-errors/src/lib.rs b/openssl-errors/src/lib.rs deleted file mode 100644 index bb8d05bf..00000000 --- a/openssl-errors/src/lib.rs +++ /dev/null @@ -1,286 +0,0 @@ -//! Custom error library support for the `openssl` crate. -//! -//! OpenSSL allows third-party libraries to integrate with its error API. This crate provides a safe interface to that. -//! -//! # Examples -//! -//! ``` -//! use openssl_errors::{openssl_errors, put_error}; -//! use openssl::error::Error; -//! -//! // Errors are organized at the top level into "libraries". The -//! // openssl_errors! macro can define these. -//! // -//! // Libraries contain a set of functions and reasons. The library itself, -//! // its functions, and its definitions all all have an associated message -//! // string. This string is what's shown in OpenSSL errors. -//! // -//! // The macro creates a type for each library with associated constants for -//! // its functions and reasons. -//! openssl_errors! { -//! pub library MyLib("my cool library") { -//! functions { -//! FIND_PRIVATE_KEY("find_private_key"); -//! } -//! -//! reasons { -//! IO_ERROR("IO error"); -//! BAD_PASSWORD("invalid private key password"); -//! } -//! } -//! } -//! -//! // The put_error! macro pushes errors onto the OpenSSL error stack. -//! put_error!(MyLib::FIND_PRIVATE_KEY, MyLib::BAD_PASSWORD); -//! -//! // Prints `error:80001002:my cool library:find_private_key:invalid private key password:src/lib.rs:27:` -//! println!("{}", Error::get().unwrap()); -//! -//! // You can also optionally attach an extra string of context using the -//! // standard Rust format syntax. -//! let tries = 2; -//! put_error!(MyLib::FIND_PRIVATE_KEY, MyLib::IO_ERROR, "tried {} times", tries); -//! -//! // Prints `error:80001001:my cool library:find_private_key:IO error:src/lib.rs:34:tried 2 times` -//! println!("{}", Error::get().unwrap()); -//! ``` -#![warn(missing_docs)] -#![doc(html_root_url = "https://docs.rs/openssl-errors/0.1")] - -use libc::{c_char, c_int}; -use std::borrow::Cow; -use std::marker::PhantomData; -use std::ptr; - -#[doc(hidden)] -pub mod export { - pub use libc::{c_char, c_int}; - pub use openssl_sys::{ - init, ERR_get_next_error_library, ERR_load_strings, ERR_PACK, ERR_STRING_DATA, - }; - pub use std::borrow::Cow; - pub use std::option::Option; - pub use std::ptr::null; - pub use std::sync::Once; -} - -/// An OpenSSL error library. -pub trait Library { - /// Returns the ID assigned to this library by OpenSSL. - fn id() -> c_int; -} - -/// A function declaration, parameterized by its error library. -pub struct Function(c_int, PhantomData); - -impl Function { - /// Creates a function from its raw identifier. - #[inline] - pub const fn from_raw(raw: c_int) -> Function { - Function(raw, PhantomData) - } - - /// Returns the function's raw identifier. - #[inline] - pub const fn as_raw(&self) -> c_int { - self.0 - } -} - -/// A reason declaration, parameterized by its error library. -pub struct Reason(c_int, PhantomData); - -impl Reason { - /// Creates a reason from its raw identifier. - #[inline] - pub const fn from_raw(raw: c_int) -> Reason { - Reason(raw, PhantomData) - } - - /// Returns the reason's raw identifier. - #[inline] - pub const fn as_raw(&self) -> c_int { - self.0 - } -} - -/// This is not considered part of this crate's public API. It is subject to change at any time. -/// -/// # Safety -/// -/// `file` and `message` must be null-terminated. -#[doc(hidden)] -pub unsafe fn __put_error( - func: Function, - reason: Reason, - file: &'static str, - line: u32, - message: Option>, -) where - T: Library, -{ - openssl_sys::ERR_put_error( - T::id(), - func.as_raw(), - reason.as_raw(), - file.as_ptr() as *const c_char, - line as c_int, - ); - let data = match message { - Some(Cow::Borrowed(s)) => Some((s.as_ptr() as *const c_char as *mut c_char, 0)), - Some(Cow::Owned(s)) => { - let ptr = openssl_sys::CRYPTO_malloc( - s.len() as _, - concat!(file!(), "\0").as_ptr() as *const c_char, - line!() as c_int, - ) as *mut c_char; - if ptr.is_null() { - None - } else { - ptr::copy_nonoverlapping(s.as_ptr(), ptr as *mut u8, s.len()); - Some((ptr, openssl_sys::ERR_TXT_MALLOCED)) - } - } - None => None, - }; - if let Some((ptr, flags)) = data { - openssl_sys::ERR_set_error_data(ptr, flags | openssl_sys::ERR_TXT_STRING); - } -} - -/// Pushes an error onto the OpenSSL error stack. -/// -/// A function and reason are required, and must be associated with the same error library. An additional formatted -/// message string can also optionally be provided. -#[macro_export] -macro_rules! put_error { - ($function:expr, $reason:expr) => { - unsafe { - $crate::__put_error( - $function, - $reason, - concat!(file!(), "\0"), - line!(), - $crate::export::Option::None, - ); - } - }; - ($function:expr, $reason:expr, $message:expr) => { - unsafe { - $crate::__put_error( - $function, - $reason, - concat!(file!(), "\0"), - line!(), - $crate::export::Option::Some($crate::export::Cow::Borrowed( - concat!($message, "\0"), - )), - ); - } - }; - ($function:expr, $reason:expr, $message:expr, $($args:tt)*) => { - unsafe { - $crate::__put_error( - $function, - $reason, - concat!(file!(), "\0"), - line!(), - $crate::export::Option::Some($crate::export::Cow::Owned( - format!(concat!($message, "\0"), $($args)*)), - ), - ); - } - }; -} - -/// Defines custom OpenSSL error libraries. -/// -/// The created libraries can be used with the `put_error!` macro to create custom OpenSSL errors. -#[macro_export] -macro_rules! openssl_errors { - ($( - $(#[$lib_attr:meta])* - $lib_vis:vis library $lib_name:ident($lib_str:expr) { - functions { - $( - $(#[$func_attr:meta])* - $func_name:ident($func_str:expr); - )* - } - - reasons { - $( - $(#[$reason_attr:meta])* - $reason_name:ident($reason_str:expr); - )* - } - } - )*) => {$( - $(#[$lib_attr])* - $lib_vis enum $lib_name {} - - impl $crate::Library for $lib_name { - fn id() -> $crate::export::c_int { - static INIT: $crate::export::Once = $crate::export::Once::new(); - static mut LIB_NUM: $crate::export::c_int = 0; - static mut STRINGS: [ - $crate::export::ERR_STRING_DATA; - 2 + $crate::openssl_errors!(@count $($func_name;)* $($reason_name;)*) - ] = [ - $crate::export::ERR_STRING_DATA { - error: 0, - string: concat!($lib_str, "\0").as_ptr() as *const $crate::export::c_char, - }, - $( - $crate::export::ERR_STRING_DATA { - error: $crate::export::ERR_PACK(0, $lib_name::$func_name.as_raw(), 0), - string: concat!($func_str, "\0").as_ptr() as *const $crate::export::c_char, - }, - )* - $( - $crate::export::ERR_STRING_DATA { - error: $crate::export::ERR_PACK(0, 0, $lib_name::$reason_name.as_raw()), - string: concat!($reason_str, "\0").as_ptr() as *const $crate::export::c_char, - }, - )* - $crate::export::ERR_STRING_DATA { - error: 0, - string: $crate::export::null(), - } - ]; - - unsafe { - INIT.call_once(|| { - $crate::export::init(); - LIB_NUM = $crate::export::ERR_get_next_error_library(); - STRINGS[0].error = $crate::export::ERR_PACK(LIB_NUM, 0, 0); - $crate::export::ERR_load_strings(LIB_NUM, STRINGS.as_mut_ptr()); - }); - - LIB_NUM - } - } - } - - impl $lib_name { - $crate::openssl_errors!(@func_consts $lib_name; 1; $($(#[$func_attr])* $func_name;)*); - $crate::openssl_errors!(@reason_consts $lib_name; 1; $($(#[$reason_attr])* $reason_name;)*); - } - )*}; - (@func_consts $lib_name:ident; $n:expr; $(#[$attr:meta])* $name:ident; $($tt:tt)*) => { - $(#[$attr])* - pub const $name: $crate::Function<$lib_name> = $crate::Function::from_raw($n); - $crate::openssl_errors!(@func_consts $lib_name; $n + 1; $($tt)*); - }; - (@func_consts $lib_name:ident; $n:expr;) => {}; - (@reason_consts $lib_name:ident; $n:expr; $(#[$attr:meta])* $name:ident; $($tt:tt)*) => { - $(#[$attr])* - pub const $name: $crate::Reason<$lib_name> = $crate::Reason::from_raw($n); - $crate::openssl_errors!(@reason_consts $lib_name; $n + 1; $($tt)*); - }; - (@reason_consts $lib_name:ident; $n:expr;) => {}; - (@count $i:ident; $($tt:tt)*) => { - 1 + $crate::openssl_errors!(@count $($tt)*) - }; - (@count) => { 0 }; -} diff --git a/openssl-errors/tests/test.rs b/openssl-errors/tests/test.rs deleted file mode 100644 index cb44cf92..00000000 --- a/openssl-errors/tests/test.rs +++ /dev/null @@ -1,66 +0,0 @@ -use openssl::error::Error; - -openssl_errors::openssl_errors! { - library Test("test library") { - functions { - FOO("function foo"); - BAR("function bar"); - } - - reasons { - NO_MILK("out of milk"); - NO_BACON("out of bacon"); - } - } -} - -#[test] -fn basic() { - openssl_errors::put_error!(Test::FOO, Test::NO_MILK); - - let error = Error::get().unwrap(); - assert_eq!(error.library().unwrap(), "test library"); - assert_eq!(error.function().unwrap(), "function foo"); - assert_eq!(error.reason().unwrap(), "out of milk"); - // Replace Windows `\` separators with `/` - assert_eq!( - error.file().replace(r"\", "/"), - "openssl-errors/tests/test.rs" - ); - assert_eq!(error.line(), 19); - assert_eq!(error.data(), None); -} - -#[test] -fn static_data() { - openssl_errors::put_error!(Test::BAR, Test::NO_BACON, "foobar"); - - let error = Error::get().unwrap(); - assert_eq!(error.library().unwrap(), "test library"); - assert_eq!(error.function().unwrap(), "function bar"); - assert_eq!(error.reason().unwrap(), "out of bacon"); - // Replace Windows `\` separators with `/` - assert_eq!( - error.file().replace(r"\", "/"), - "openssl-errors/tests/test.rs" - ); - assert_eq!(error.line(), 36); - assert_eq!(error.data(), Some("foobar")); -} - -#[test] -fn dynamic_data() { - openssl_errors::put_error!(Test::BAR, Test::NO_MILK, "hello {}", "world"); - - let error = Error::get().unwrap(); - assert_eq!(error.library().unwrap(), "test library"); - assert_eq!(error.function().unwrap(), "function bar"); - assert_eq!(error.reason().unwrap(), "out of milk"); - // Replace Windows `\` separators with `/` - assert_eq!( - error.file().replace(r"\", "/"), - "openssl-errors/tests/test.rs" - ); - assert_eq!(error.line(), 53); - assert_eq!(error.data(), Some("hello world")); -} diff --git a/openssl-sys/Cargo.toml b/openssl-sys/Cargo.toml index 89c798bc..f6d2e116 100644 --- a/openssl-sys/Cargo.toml +++ b/openssl-sys/Cargo.toml @@ -8,24 +8,9 @@ description = "FFI bindings to OpenSSL" repository = "https://github.com/sfackler/rust-openssl" readme = "README.md" categories = ["cryptography", "external-ffi-bindings"] -links = "openssl" -build = "build/main.rs" - -[features] -vendored = ['openssl-src'] [dependencies] libc = "0.2" [build-dependencies] -cc = "1.0" -openssl-src = { version = "111.0.1", optional = true } -pkg-config = "0.3.9" -autocfg = "1.0" - -[target.'cfg(target_env = "msvc")'.build-dependencies] -vcpkg = "0.2.8" - -# We don't actually use metadeps for annoying reasons but this is still here for tooling -[package.metadata.pkg-config] -openssl = "1.0.1" +cmake = "0.1" diff --git a/openssl-sys/build.rs b/openssl-sys/build.rs new file mode 100644 index 00000000..adae852a --- /dev/null +++ b/openssl-sys/build.rs @@ -0,0 +1,209 @@ +// Additional parameters for Android build of BoringSSL. +// +// Android NDK < 18 with GCC. +const CMAKE_PARAMS_ANDROID_NDK_OLD_GCC: &[(&str, &[(&str, &str)])] = &[ + ( + "aarch64", + &[("ANDROID_TOOLCHAIN_NAME", "aarch64-linux-android-4.9")], + ), + ( + "arm", + &[("ANDROID_TOOLCHAIN_NAME", "arm-linux-androideabi-4.9")], + ), + ( + "x86", + &[("ANDROID_TOOLCHAIN_NAME", "x86-linux-android-4.9")], + ), + ( + "x86_64", + &[("ANDROID_TOOLCHAIN_NAME", "x86_64-linux-android-4.9")], + ), +]; + +// Android NDK >= 19. +const CMAKE_PARAMS_ANDROID_NDK: &[(&str, &[(&str, &str)])] = &[ + ("aarch64", &[("ANDROID_ABI", "arm64-v8a")]), + ("arm", &[("ANDROID_ABI", "armeabi-v7a")]), + ("x86", &[("ANDROID_ABI", "x86")]), + ("x86_64", &[("ANDROID_ABI", "x86_64")]), +]; + +const CMAKE_PARAMS_IOS: &[(&str, &[(&str, &str)])] = &[ + ( + "aarch64", + &[ + ("CMAKE_OSX_ARCHITECTURES", "arm64"), + ("CMAKE_OSX_SYSROOT", "iphoneos"), + ], + ), + ( + "x86_64", + &[ + ("CMAKE_OSX_ARCHITECTURES", "x86_64"), + ("CMAKE_OSX_SYSROOT", "iphonesimulator"), + ], + ), +]; + +/// Returns the platform-specific output path for lib. +/// +/// MSVC generator on Windows place static libs in a target sub-folder, +/// so adjust library location based on platform and build target. +/// See issue: https://github.com/alexcrichton/cmake-rs/issues/18 +fn get_boringssl_platform_output_path() -> String { + if cfg!(windows) { + // Code under this branch should match the logic in cmake-rs + let debug_env_var = std::env::var("DEBUG").expect("DEBUG variable not defined in env"); + + let deb_info = match &debug_env_var[..] { + "false" => false, + "true" => true, + unknown => panic!("Unknown DEBUG={} env var.", unknown), + }; + + let opt_env_var = + std::env::var("OPT_LEVEL").expect("OPT_LEVEL variable not defined in env"); + + let subdir = match &opt_env_var[..] { + "0" => "Debug", + "1" | "2" | "3" => { + if deb_info { + "RelWithDebInfo" + } else { + "Release" + } + } + "s" | "z" => "MinSizeRel", + unknown => panic!("Unknown OPT_LEVEL={} env var.", unknown), + }; + + subdir.to_string() + } else { + "".to_string() + } +} + +/// Returns a new cmake::Config for building BoringSSL. +/// +/// It will add platform-specific parameters if needed. +fn get_boringssl_cmake_config() -> cmake::Config { + let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); + let pwd = std::env::current_dir().unwrap(); + + let mut boringssl_cmake = cmake::Config::new("deps/boringssl"); + + // Add platform-specific parameters. + match os.as_ref() { + "android" => { + let cmake_params_android = if cfg!(feature = "ndk-old-gcc") { + CMAKE_PARAMS_ANDROID_NDK_OLD_GCC + } else { + CMAKE_PARAMS_ANDROID_NDK + }; + + // We need ANDROID_NDK_HOME to be set properly. + let android_ndk_home = std::env::var("ANDROID_NDK_HOME") + .expect("Please set ANDROID_NDK_HOME for Android build"); + let android_ndk_home = std::path::Path::new(&android_ndk_home); + for (android_arch, params) in cmake_params_android { + if *android_arch == arch { + for (name, value) in *params { + eprintln!("android arch={} add {}={}", arch, name, value); + boringssl_cmake.define(name, value); + } + } + } + let toolchain_file = android_ndk_home.join("build/cmake/android.toolchain.cmake"); + let toolchain_file = toolchain_file.to_str().unwrap(); + eprintln!("android toolchain={}", toolchain_file); + boringssl_cmake.define("CMAKE_TOOLCHAIN_FILE", toolchain_file); + + // 21 is the minimum level tested. You can give higher value. + boringssl_cmake.define("ANDROID_NATIVE_API_LEVEL", "21"); + boringssl_cmake.define("ANDROID_STL", "c++_shared"); + + boringssl_cmake + } + + "ios" => { + for (ios_arch, params) in CMAKE_PARAMS_IOS { + if *ios_arch == arch { + for (name, value) in *params { + eprintln!("ios arch={} add {}={}", arch, name, value); + boringssl_cmake.define(name, value); + } + } + } + + // Bitcode is always on. + let bitcode_cflag = "-fembed-bitcode"; + + // Hack for Xcode 10.1. + let target_cflag = if arch == "x86_64" { + "-target x86_64-apple-ios-simulator" + } else { + "" + }; + + let cflag = format!("{} {}", bitcode_cflag, target_cflag); + + boringssl_cmake.define("CMAKE_ASM_FLAGS", &cflag); + boringssl_cmake.cflag(&cflag); + + boringssl_cmake + } + + _ => { + // Configure BoringSSL for building on 32-bit non-windows platforms. + if arch == "x86" && os != "windows" { + boringssl_cmake.define( + "CMAKE_TOOLCHAIN_FILE", + pwd.join("deps/boringssl/src/util/32-bit-toolchain.cmake") + .as_os_str(), + ); + } + + boringssl_cmake + } + } +} + +fn main() { + let bssl_dir = std::env::var("QUICHE_BSSL_PATH").unwrap_or_else(|_| { + let mut cfg = get_boringssl_cmake_config(); + + if cfg!(feature = "fuzzing") { + cfg.cxxflag("-DBORINGSSL_UNSAFE_DETERMINISTIC_MODE") + .cxxflag("-DBORINGSSL_UNSAFE_FUZZER_MODE"); + } + + cfg.build_target("bssl").build().display().to_string() + }); + + let build_path = get_boringssl_platform_output_path(); + let build_dir = format!("{}/build/{}", bssl_dir, build_path); + println!("cargo:rustc-link-search=native={}", build_dir); + + let mut cfgs = vec![]; + + cfgs.push("ossl101"); + cfgs.push("ossl102"); + cfgs.push("ossl102f"); + cfgs.push("ossl102h"); + cfgs.push("ossl110"); + cfgs.push("ossl110f"); + cfgs.push("ossl110g"); + + for cfg in cfgs { + println!("cargo:rustc-cfg={}", cfg); + } + + println!("cargo:rustc-link-lib=static=crypto"); + println!("cargo:rustc-link-lib=static=ssl"); + + // MacOS: Allow cdylib to link with undefined symbols + if cfg!(target_os = "macos") { + println!("cargo:rustc-cdylib-link-arg=-Wl,-undefined,dynamic_lookup"); + } +} diff --git a/openssl-sys/build/cfgs.rs b/openssl-sys/build/cfgs.rs deleted file mode 100644 index 13aa0895..00000000 --- a/openssl-sys/build/cfgs.rs +++ /dev/null @@ -1,71 +0,0 @@ -#[allow(clippy::inconsistent_digit_grouping)] -pub fn get(openssl_version: Option, libressl_version: Option) -> 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"); - } - if libressl_version >= 0x2_07_01_00_0 { - cfgs.push("libressl271"); - } - if libressl_version >= 0x2_07_03_00_0 { - cfgs.push("libressl273"); - } - if libressl_version >= 0x2_08_00_00_0 { - cfgs.push("libressl280"); - } - if libressl_version >= 0x2_08_01_00_0 { - cfgs.push("libressl281"); - } - if libressl_version >= 0x2_09_01_00_0 { - cfgs.push("libressl291"); - } - } else { - let openssl_version = openssl_version.unwrap(); - - if openssl_version >= 0x1_00_01_00_0 { - cfgs.push("ossl101"); - } - if openssl_version >= 0x1_00_02_00_0 { - cfgs.push("ossl102"); - } - if openssl_version >= 0x1_00_02_06_0 { - cfgs.push("ossl102f"); - } - if openssl_version >= 0x1_00_02_08_0 { - cfgs.push("ossl102h"); - } - if openssl_version >= 0x1_01_00_00_0 { - cfgs.push("ossl110"); - } - if openssl_version >= 0x1_01_00_06_0 { - cfgs.push("ossl110f"); - } - if openssl_version >= 0x1_01_00_07_0 { - cfgs.push("ossl110g"); - } - if openssl_version >= 0x1_01_00_08_0 { - cfgs.push("ossl110h"); - } - if openssl_version >= 0x1_01_01_00_0 { - cfgs.push("ossl111"); - } - if openssl_version >= 0x1_01_01_02_0 { - cfgs.push("ossl111b"); - } - if openssl_version >= 0x1_01_01_03_0 { - cfgs.push("ossl111c"); - } - } - - cfgs -} diff --git a/openssl-sys/build/expando.c b/openssl-sys/build/expando.c deleted file mode 100644 index c8bfac87..00000000 --- a/openssl-sys/build/expando.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include - -#define VERSION2(n, v) RUST_VERSION_##n##_##v -#define VERSION(n, v) VERSION2(n, v) - -#ifdef LIBRESSL_VERSION_NUMBER -VERSION(LIBRESSL, LIBRESSL_VERSION_NUMBER) -#else -VERSION(OPENSSL, OPENSSL_VERSION_NUMBER) -#endif - -#ifdef OPENSSL_NO_BUF_FREELISTS -RUST_CONF_OPENSSL_NO_BUF_FREELISTS -#endif - -#ifdef OPENSSL_NO_COMP -RUST_CONF_OPENSSL_NO_COMP -#endif - -#ifdef OPENSSL_NO_EC -RUST_CONF_OPENSSL_NO_EC -#endif - -#ifdef OPENSSL_NO_EC2M -RUST_CONF_OPENSSL_NO_EC2M -#endif - -#ifdef OPENSSL_NO_ENGINE -RUST_CONF_OPENSSL_NO_ENGINE -#endif - -#ifdef OPENSSL_NO_KRB5 -RUST_CONF_OPENSSL_NO_KRB5 -#endif - -#ifdef OPENSSL_NO_NEXTPROTONEG -RUST_CONF_OPENSSL_NO_NEXTPROTONEG -#endif - -#ifdef OPENSSL_NO_PSK -RUST_CONF_OPENSSL_NO_PSK -#endif - -#ifdef OPENSSL_NO_RFC3779 -RUST_CONF_OPENSSL_NO_RFC3779 -#endif - -#ifdef OPENSSL_NO_SHA -RUST_CONF_OPENSSL_NO_SHA -#endif - -#ifdef OPENSSL_NO_SRP -RUST_CONF_OPENSSL_NO_SRP -#endif - -#ifdef OPENSSL_NO_SSL3_METHOD -RUST_CONF_OPENSSL_NO_SSL3_METHOD -#endif - -#ifdef OPENSSL_NO_TLSEXT -RUST_CONF_OPENSSL_NO_TLSEXT -#endif - -#ifdef OPENSSL_NO_STDIO -RUST_CONF_OPENSSL_NO_STDIO -#endif diff --git a/openssl-sys/build/find_normal.rs b/openssl-sys/build/find_normal.rs deleted file mode 100644 index f7978923..00000000 --- a/openssl-sys/build/find_normal.rs +++ /dev/null @@ -1,241 +0,0 @@ -use pkg_config; -use std::ffi::OsString; -use std::path::{Path, PathBuf}; -use std::process::{self, Command}; - -use super::env; - -pub fn get_openssl(target: &str) -> (PathBuf, PathBuf) { - let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from); - let include_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from); - - match (lib_dir, include_dir) { - (Some(lib_dir), Some(include_dir)) => (lib_dir, include_dir), - (lib_dir, include_dir) => { - let openssl_dir = env("OPENSSL_DIR").unwrap_or_else(|| find_openssl_dir(&target)); - let openssl_dir = Path::new(&openssl_dir); - let lib_dir = lib_dir.unwrap_or_else(|| openssl_dir.join("lib")); - let include_dir = include_dir.unwrap_or_else(|| openssl_dir.join("include")); - (lib_dir, include_dir) - } - } -} - -fn find_openssl_dir(target: &str) -> OsString { - let host = env::var("HOST").unwrap(); - - if host == target && target.contains("apple-darwin") { - // Check up default Homebrew installation location first - // for quick resolution if possible. - let homebrew = Path::new("/usr/local/opt/openssl@1.1"); - if homebrew.exists() { - return homebrew.to_path_buf().into(); - } - let homebrew = Path::new("/usr/local/opt/openssl"); - if homebrew.exists() { - return homebrew.to_path_buf().into(); - } - // Calling `brew --prefix ` command usually slow and - // takes seconds, and will be used only as a last resort. - let output = execute_command_and_get_output("brew", &["--prefix", "openssl@1.1"]); - if let Some(ref output) = output { - let homebrew = Path::new(&output); - if homebrew.exists() { - return homebrew.to_path_buf().into(); - } - } - let output = execute_command_and_get_output("brew", &["--prefix", "openssl"]); - if let Some(ref output) = output { - let homebrew = Path::new(&output); - if homebrew.exists() { - return homebrew.to_path_buf().into(); - } - } - } - - try_pkg_config(); - try_vcpkg(); - - // FreeBSD ships with OpenSSL but doesn't include a pkg-config file :( - if host == target && target.contains("freebsd") { - return OsString::from("/usr"); - } - - // DragonFly has libressl (or openssl) in ports, but this doesn't include a pkg-config file - if host == target && target.contains("dragonfly") { - return OsString::from("/usr/local"); - } - - let mut msg = format!( - " - -Could not find directory of OpenSSL installation, and this `-sys` crate cannot -proceed without this knowledge. If OpenSSL is installed and this crate had -trouble finding it, you can set the `OPENSSL_DIR` environment variable for the -compilation process. - -Make sure you also have the development packages of openssl installed. -For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora. - -If you're in a situation where you think the directory *should* be found -automatically, please open a bug at https://github.com/sfackler/rust-openssl -and include information about your system as well as this message. - -$HOST = {} -$TARGET = {} -openssl-sys = {} - -", - host, - target, - env!("CARGO_PKG_VERSION") - ); - - if host.contains("apple-darwin") && target.contains("apple-darwin") { - let system = Path::new("/usr/lib/libssl.0.9.8.dylib"); - if system.exists() { - msg.push_str( - " - -It looks like you're compiling on macOS, where the system contains a version of -OpenSSL 0.9.8. This crate no longer supports OpenSSL 0.9.8. - -As a consumer of this crate, you can fix this error by using Homebrew to -install the `openssl` package, or as a maintainer you can use the openssl-sys -0.7 crate for support with OpenSSL 0.9.8. - -Unfortunately though the compile cannot continue, so aborting. - -", - ); - } - } - - if host.contains("unknown-linux") - && target.contains("unknown-linux-gnu") - && Command::new("pkg-config").output().is_err() - { - msg.push_str( - " -It looks like you're compiling on Linux and also targeting Linux. Currently this -requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config` -could not be found. If you have OpenSSL installed you can likely fix this by -installing `pkg-config`. - -", - ); - } - - if host.contains("windows") && target.contains("windows-gnu") { - msg.push_str( - " -It looks like you're compiling for MinGW but you may not have either OpenSSL or -pkg-config installed. You can install these two dependencies with: - -pacman -S openssl-devel pkg-config - -and try building this crate again. - -", - ); - } - - if host.contains("windows") && target.contains("windows-msvc") { - msg.push_str( - " -It looks like you're compiling for MSVC but we couldn't detect an OpenSSL -installation. If there isn't one installed then you can try the rust-openssl -README for more information about how to download precompiled binaries of -OpenSSL: - -https://github.com/sfackler/rust-openssl#windows - -", - ); - } - - panic!(msg); -} - -/// Attempt to find OpenSSL through pkg-config. -/// -/// Note that if this succeeds then the function does not return as pkg-config -/// typically tells us all the information that we need. -fn try_pkg_config() { - let target = env::var("TARGET").unwrap(); - let host = env::var("HOST").unwrap(); - - // If we're going to windows-gnu we can use pkg-config, but only so long as - // we're coming from a windows host. - // - // Otherwise if we're going to windows we probably can't use pkg-config. - if target.contains("windows-gnu") && host.contains("windows") { - env::set_var("PKG_CONFIG_ALLOW_CROSS", "1"); - } else if target.contains("windows") { - return; - } - - let lib = match pkg_config::Config::new() - .print_system_libs(false) - .find("openssl") - { - Ok(lib) => lib, - Err(e) => { - println!("run pkg_config fail: {:?}", e); - return; - } - }; - - super::validate_headers(&lib.include_paths); - - for include in lib.include_paths.iter() { - println!("cargo:include={}", include.display()); - } - - process::exit(0); -} - -/// Attempt to find OpenSSL through vcpkg. -/// -/// Note that if this succeeds then the function does not return as vcpkg -/// should emit all of the cargo metadata that we need. -#[cfg(target_env = "msvc")] -fn try_vcpkg() { - // vcpkg will not emit any metadata if it can not find libraries - // appropriate for the target triple with the desired linkage. - - let lib = vcpkg::Config::new() - .emit_includes(true) - .find_package("openssl"); - - if let Err(e) = lib { - println!("note: vcpkg did not find openssl: {}", e); - return; - } - - let lib = lib.unwrap(); - super::validate_headers(&lib.include_paths); - - println!("cargo:rustc-link-lib=user32"); - println!("cargo:rustc-link-lib=gdi32"); - println!("cargo:rustc-link-lib=crypt32"); - - process::exit(0); -} - -#[cfg(not(target_env = "msvc"))] -fn try_vcpkg() {} - -fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option { - let out = Command::new(cmd).args(args).output(); - if let Ok(ref r1) = out { - if r1.status.success() { - let r2 = String::from_utf8(r1.stdout.clone()); - if let Ok(r3) = r2 { - return Some(r3.trim().to_string()); - } - } - } - - None -} diff --git a/openssl-sys/build/find_vendored.rs b/openssl-sys/build/find_vendored.rs deleted file mode 100644 index 45ccfe44..00000000 --- a/openssl-sys/build/find_vendored.rs +++ /dev/null @@ -1,16 +0,0 @@ -use openssl_src; -use std::path::PathBuf; - -pub fn get_openssl(_target: &str) -> (PathBuf, PathBuf) { - let artifacts = openssl_src::Build::new().build(); - println!("cargo:vendored=1"); - println!( - "cargo:root={}", - artifacts.lib_dir().parent().unwrap().display() - ); - - ( - artifacts.lib_dir().to_path_buf(), - artifacts.include_dir().to_path_buf(), - ) -} diff --git a/openssl-sys/build/main.rs b/openssl-sys/build/main.rs deleted file mode 100644 index b9f47a7b..00000000 --- a/openssl-sys/build/main.rs +++ /dev/null @@ -1,334 +0,0 @@ -#![allow(clippy::inconsistent_digit_grouping)] - -extern crate autocfg; -extern crate cc; -#[cfg(feature = "vendored")] -extern crate openssl_src; -extern crate pkg_config; -#[cfg(target_env = "msvc")] -extern crate vcpkg; - -use std::collections::HashSet; -use std::env; -use std::ffi::OsString; -use std::path::{Path, PathBuf}; - -mod cfgs; - -mod find_normal; -#[cfg(feature = "vendored")] -mod find_vendored; - -enum Version { - Openssl11x, - Openssl10x, - Libressl, -} - -fn env_inner(name: &str) -> Option { - let var = env::var_os(name); - println!("cargo:rerun-if-env-changed={}", name); - - match var { - Some(ref v) => println!("{} = {}", name, v.to_string_lossy()), - None => println!("{} unset", name), - } - - var -} - -fn env(name: &str) -> Option { - let prefix = env::var("TARGET").unwrap().to_uppercase().replace("-", "_"); - let prefixed = format!("{}_{}", prefix, name); - env_inner(&prefixed).or_else(|| env_inner(name)) -} - -fn find_openssl(target: &str) -> (PathBuf, PathBuf) { - #[cfg(feature = "vendored")] - { - // vendor if the feature is present, unless - // OPENSSL_NO_VENDOR exists and isn't `0` - if env("OPENSSL_NO_VENDOR").map_or(true, |s| s == "0") { - return find_vendored::get_openssl(target); - } - } - find_normal::get_openssl(target) -} - -fn main() { - check_rustc_versions(); - - let target = env::var("TARGET").unwrap(); - - let (lib_dir, include_dir) = find_openssl(&target); - - if !Path::new(&lib_dir).exists() { - panic!( - "OpenSSL library directory does not exist: {}", - lib_dir.to_string_lossy() - ); - } - if !Path::new(&include_dir).exists() { - panic!( - "OpenSSL include directory does not exist: {}", - include_dir.to_string_lossy() - ); - } - - 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]); - - let libs_env = env("OPENSSL_LIBS"); - let libs = match libs_env.as_ref().and_then(|s| s.to_str()) { - Some(ref v) => v.split(':').collect(), - None => match version { - Version::Openssl10x if target.contains("windows") => vec!["ssleay32", "libeay32"], - Version::Openssl11x if target.contains("windows-msvc") => vec!["libssl", "libcrypto"], - _ => vec!["ssl", "crypto"], - }, - }; - - let kind = determine_mode(Path::new(&lib_dir), &libs); - for lib in libs.into_iter() { - println!("cargo:rustc-link-lib={}={}", kind, lib); - } - - if kind == "static" && target.contains("windows") { - println!("cargo:rustc-link-lib=dylib=gdi32"); - println!("cargo:rustc-link-lib=dylib=user32"); - println!("cargo:rustc-link-lib=dylib=crypt32"); - println!("cargo:rustc-link-lib=dylib=ws2_32"); - println!("cargo:rustc-link-lib=dylib=advapi32"); - } -} - -fn check_rustc_versions() { - let cfg = autocfg::new(); - - if cfg.probe_rustc_version(1, 31) { - println!("cargo:rustc-cfg=const_fn"); - } -} - -/// 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 gcc = cc::Build::new(); - for include_dir in include_dirs { - gcc.include(include_dir); - } - let expanded = match gcc.file("build/expando.c").try_expand() { - Ok(expanded) => expanded, - Err(e) => { - panic!( - " -Header expansion error: -{:?} - -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 -specific to your distribution: - - # On Ubuntu - sudo apt-get install libssl-dev - # On Arch Linux - sudo pacman -S openssl - # On Fedora - sudo dnf install openssl-devel - -See rust-openssl README for more information: - - https://github.com/sfackler/rust-openssl#linux -", - e - ); - } - }; - let expanded = String::from_utf8(expanded).unwrap(); - - let mut enabled = vec![]; - let mut openssl_version = None; - let mut libressl_version = None; - for line in expanded.lines() { - let line = line.trim(); - - let openssl_prefix = "RUST_VERSION_OPENSSL_"; - let libressl_prefix = "RUST_VERSION_LIBRESSL_"; - let conf_prefix = "RUST_CONF_"; - if line.starts_with(openssl_prefix) { - let version = &line[openssl_prefix.len()..]; - openssl_version = Some(parse_version(version)); - } else if line.starts_with(libressl_prefix) { - let version = &line[libressl_prefix.len()..]; - libressl_version = Some(parse_version(version)); - } else if line.starts_with(conf_prefix) { - enabled.push(&line[conf_prefix.len()..]); - } - } - - for enabled in &enabled { - println!("cargo:rustc-cfg=osslconf=\"{}\"", enabled); - } - 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 { - println!("cargo:libressl_version_number={:x}", libressl_version); - - let major = (libressl_version >> 28) as u8; - let minor = (libressl_version >> 20) as u8; - let fix = (libressl_version >> 12) as u8; - let (major, minor, fix) = match (major, minor, fix) { - (2, 5, 0) => ('2', '5', '0'), - (2, 5, 1) => ('2', '5', '1'), - (2, 5, 2) => ('2', '5', '2'), - (2, 5, _) => ('2', '5', 'x'), - (2, 6, 0) => ('2', '6', '0'), - (2, 6, 1) => ('2', '6', '1'), - (2, 6, 2) => ('2', '6', '2'), - (2, 6, _) => ('2', '6', 'x'), - (2, 7, _) => ('2', '7', 'x'), - (2, 8, 0) => ('2', '8', '0'), - (2, 8, 1) => ('2', '8', '1'), - (2, 8, _) => ('2', '8', 'x'), - (2, 9, 0) => ('2', '9', '0'), - (2, 9, _) => ('2', '9', 'x'), - (3, 0, 0) => ('3', '0', '0'), - (3, 0, 1) => ('3', '0', '1'), - (3, 0, _) => ('3', '0', 'x'), - (3, 1, 0) => ('3', '1', '0'), - (3, 1, _) => ('3', '1', 'x'), - (3, 2, 0) => ('3', '2', '0'), - _ => version_error(), - }; - - println!("cargo:libressl=true"); - println!("cargo:libressl_version={}{}{}", major, minor, fix); - println!("cargo:version=101"); - Version::Libressl - } else { - let openssl_version = openssl_version.unwrap(); - println!("cargo:version_number={:x}", openssl_version); - - if openssl_version >= 0x1_01_02_00_0 { - version_error() - } else if openssl_version >= 0x1_01_01_00_0 { - println!("cargo:version=111"); - Version::Openssl11x - } else if openssl_version >= 0x1_01_00_06_0 { - println!("cargo:version=110"); - println!("cargo:patch=f"); - Version::Openssl11x - } else if openssl_version >= 0x1_01_00_00_0 { - println!("cargo:version=110"); - Version::Openssl11x - } else if openssl_version >= 0x1_00_02_00_0 { - println!("cargo:version=102"); - Version::Openssl10x - } else if openssl_version >= 0x1_00_01_00_0 { - println!("cargo:version=101"); - Version::Openssl10x - } else { - version_error() - } - } -} - -fn version_error() -> ! { - panic!( - " - -This crate is only compatible with OpenSSL 1.0.1 through 1.1.1, or LibreSSL 2.5 -through 3.2.0, but a different version of OpenSSL was found. The build is now aborting -due to this version mismatch. - -" - ); -} - -// parses a string that looks like "0x100020cfL" -#[allow(deprecated)] // trim_right_matches is now trim_end_matches -#[allow(clippy::match_like_matches_macro)] // matches macro requires rust 1.42.0 -fn parse_version(version: &str) -> u64 { - // cut off the 0x prefix - assert!(version.starts_with("0x")); - let version = &version[2..]; - - // and the type specifier suffix - let version = version.trim_right_matches(|c: char| match c { - '0'..='9' | 'a'..='f' | 'A'..='F' => false, - _ => true, - }); - - u64::from_str_radix(version, 16).unwrap() -} - -/// Given a libdir for OpenSSL (where artifacts are located) as well as the name -/// of the libraries we're linking to, figure out whether we should link them -/// statically or dynamically. -fn determine_mode(libdir: &Path, libs: &[&str]) -> &'static str { - // First see if a mode was explicitly requested - let kind = env("OPENSSL_STATIC"); - match kind.as_ref().and_then(|s| s.to_str()).map(|s| &s[..]) { - Some("0") => return "dylib", - Some(_) => return "static", - None => {} - } - - // Next, see what files we actually have to link against, and see what our - // possibilities even are. - let files = libdir - .read_dir() - .unwrap() - .map(|e| e.unwrap()) - .map(|e| e.file_name()) - .filter_map(|e| e.into_string().ok()) - .collect::>(); - let can_static = libs - .iter() - .all(|l| files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l))); - let can_dylib = libs.iter().all(|l| { - files.contains(&format!("lib{}.so", l)) - || files.contains(&format!("{}.dll", l)) - || files.contains(&format!("lib{}.dylib", l)) - }); - match (can_static, can_dylib) { - (true, false) => return "static", - (false, true) => return "dylib", - (false, false) => { - panic!( - "OpenSSL libdir at `{}` does not contain the required files \ - to either statically or dynamically link OpenSSL", - libdir.display() - ); - } - (true, true) => {} - } - - // Ok, we've got not explicit preference and can *either* link statically or - // link dynamically. In the interest of "security upgrades" and/or "best - // practices with security libs", let's link dynamically. - "dylib" -} diff --git a/openssl-sys/deps/boringssl b/openssl-sys/deps/boringssl new file mode 160000 index 00000000..30c88d66 --- /dev/null +++ b/openssl-sys/deps/boringssl @@ -0,0 +1 @@ +Subproject commit 30c88d6607b09df5d8bf2a143fbb74e383af85e9 diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index a54833d5..efd1a25d 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -16,7 +16,6 @@ v102 = [] v110 = [] v111 = [] -vendored = ['openssl-sys/vendored'] [dependencies] bitflags = "1.0" diff --git a/openssl/build.rs b/openssl/build.rs index 5ec03a70..4efd86e0 100644 --- a/openssl/build.rs +++ b/openssl/build.rs @@ -1,67 +1,15 @@ -#![allow(clippy::inconsistent_digit_grouping)] - -use std::env; - fn main() { - if env::var("DEP_OPENSSL_LIBRESSL").is_ok() { - println!("cargo:rustc-cfg=libressl"); - } + let mut cfgs = vec![]; - if let Ok(v) = env::var("DEP_OPENSSL_LIBRESSL_VERSION") { - println!("cargo:rustc-cfg=libressl{}", v); - } + cfgs.push("ossl101"); + cfgs.push("ossl102"); + cfgs.push("ossl102f"); + cfgs.push("ossl102h"); + cfgs.push("ossl110"); + cfgs.push("ossl110f"); + cfgs.push("ossl110g"); - if let Ok(vars) = env::var("DEP_OPENSSL_CONF") { - for var in vars.split(',') { - println!("cargo:rustc-cfg=osslconf=\"{}\"", var); - } - } - - 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"); - } - - if version >= 0x2_07_01_00_0 { - println!("cargo:rustc-cfg=libressl271"); - } - - if version >= 0x2_07_03_00_0 { - println!("cargo:rustc-cfg=libressl273"); - } - - if version >= 0x2_08_00_00_0 { - println!("cargo:rustc-cfg=libressl280"); - } - - if version >= 0x2_09_01_00_0 { - println!("cargo:rustc-cfg=libressl291"); - } + for cfg in cfgs { + println!("cargo:rustc-cfg={}", cfg); } } diff --git a/systest/Cargo.toml b/systest/Cargo.toml deleted file mode 100644 index bea35574..00000000 --- a/systest/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "systest" -version = "0.1.0" -authors = ["Alex Crichton "] - -[dependencies] -libc = "0.2" -openssl-sys = { path = "../openssl-sys" } - -[build-dependencies] -ctest = "0.2" - -[features] -vendored = ['openssl-sys/vendored'] diff --git a/systest/build.rs b/systest/build.rs deleted file mode 100644 index 0c84bc33..00000000 --- a/systest/build.rs +++ /dev/null @@ -1,141 +0,0 @@ -extern crate ctest; - -use std::env; - -#[path = "../openssl-sys/build/cfgs.rs"] -mod cfgs; - -fn main() { - let mut cfg = ctest::TestGenerator::new(); - let target = env::var("TARGET").unwrap(); - - if let Ok(out) = env::var("DEP_OPENSSL_INCLUDE") { - cfg.include(&out); - } - - // Needed to get OpenSSL to correctly undef symbols that are already on - // Windows like X509_NAME - if target.contains("windows") { - cfg.header("windows.h"); - - // weird "different 'const' qualifiers" error on Windows, maybe a cl.exe - // thing? - if target.contains("msvc") { - cfg.flag("/wd4090"); - } - - // https://github.com/sfackler/rust-openssl/issues/889 - cfg.define("WIN32_LEAN_AND_MEAN", None); - } - - let openssl_version = env::var("DEP_OPENSSL_VERSION_NUMBER") - .ok() - .map(|v| u64::from_str_radix(&v, 16).unwrap()); - let libressl_version = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") - .ok() - .map(|v| u64::from_str_radix(&v, 16).unwrap()); - - for c in cfgs::get(openssl_version, libressl_version) { - cfg.cfg(c, None); - } - - if let Ok(vars) = env::var("DEP_OPENSSL_CONF") { - for var in vars.split(',') { - cfg.cfg("osslconf", Some(var)); - } - } - - cfg.header("openssl/comp.h") - .header("openssl/dh.h") - .header("openssl/ossl_typ.h") - .header("openssl/stack.h") - .header("openssl/x509.h") - .header("openssl/bio.h") - .header("openssl/x509v3.h") - .header("openssl/safestack.h") - .header("openssl/hmac.h") - .header("openssl/ssl.h") - .header("openssl/err.h") - .header("openssl/rand.h") - .header("openssl/pkcs12.h") - .header("openssl/bn.h") - .header("openssl/aes.h") - .header("openssl/ocsp.h") - .header("openssl/evp.h") - .header("openssl/x509_vfy.h"); - - if openssl_version.is_some() { - cfg.header("openssl/cms.h"); - } - - #[allow(clippy::if_same_then_else)] - cfg.type_name(|s, is_struct, _is_union| { - // Add some `*` on some callback parameters to get function pointer to - // typecheck in C, especially on MSVC. - if s == "PasswordCallback" { - "pem_password_cb*".to_string() - } else if s == "bio_info_cb" { - "bio_info_cb*".to_string() - } else if s == "_STACK" { - "struct stack_st".to_string() - // This logic should really be cleaned up - } else if is_struct - && s != "point_conversion_form_t" - && s.chars().next().unwrap().is_lowercase() - { - format!("struct {}", s) - } else if s.starts_with("stack_st_") { - format!("struct {}", s) - } else { - s.to_string() - } - }); - cfg.skip_type(|s| { - // function pointers are declared without a `*` in openssl so their - // sizeof is 1 which isn't what we want. - s == "PasswordCallback" - || s == "pem_password_cb" - || s == "bio_info_cb" - || s.starts_with("CRYPTO_EX_") - }); - cfg.skip_struct(|s| { - s == "ProbeResult" || s == "X509_OBJECT_data" // inline union - }); - cfg.skip_fn(move |s| { - s == "CRYPTO_memcmp" || // uses volatile - - // Skip some functions with function pointers on windows, not entirely - // sure how to get them to work out... - (target.contains("windows") && { - s.starts_with("PEM_read_bio_") || - (s.starts_with("PEM_write_bio_") && s.ends_with("PrivateKey")) || - s == "d2i_PKCS8PrivateKey_bio" || - s == "SSL_get_ex_new_index" || - s == "SSL_CTX_get_ex_new_index" || - s == "CRYPTO_get_ex_new_index" - }) - }); - cfg.skip_field_type(|s, field| { - (s == "EVP_PKEY" && field == "pkey") || // union - (s == "GENERAL_NAME" && field == "d") || // union - (s == "X509_OBJECT" && field == "data") // union - }); - cfg.skip_signededness(|s| { - s.ends_with("_cb") - || s.ends_with("_CB") - || 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| { - if field == "type_" { - "type".to_string() - } else { - field.to_string() - } - }); - cfg.fn_cname(|rust, link_name| link_name.unwrap_or(rust).to_string()); - cfg.generate("../openssl-sys/src/lib.rs", "all.rs"); -} diff --git a/systest/src/main.rs b/systest/src/main.rs deleted file mode 100644 index 3e5888c8..00000000 --- a/systest/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow(bad_style, clippy::all)] - -extern crate libc; -extern crate openssl_sys; - -use libc::*; -use openssl_sys::*; - -include!(concat!(env!("OUT_DIR"), "/all.rs"));