//! Bindings to OpenSSL
//!
//! This crate provides a safe interface to the popular OpenSSL cryptography library. OpenSSL versions 1.0.1 through
//! 1.1.1 and LibreSSL versions 2.5 through 2.8 are supported.
//!
//! # Building
//!
//! Both OpenSSL libraries and headers are required to build this crate. There are multiple options available to locate
//! OpenSSL.
//!
//! ## Vendored
//!
//! If the `vendored` Cargo feature is enabled, the `openssl-src` crate will be used to compile and statically link to
//! a copy of OpenSSL. The build process requires a C compiler, perl, and make. The OpenSSL version will generally track
//! the newest OpenSSL release, and changes to the version are *not* considered breaking changes.
//!
//! ```toml
//! [dependencies]
//! openssl = { version = "0.10", features = ["vendored"] }
//! ```
//!
//! The vendored copy will not be configured to automatically find the system's root certificates, but the
//! `openssl-probe` crate can be used to do that instead.
//!
//! ## Automatic
//!
//! The `openssl-sys` crate will automatically detect OpenSSL installations via Homebrew on macOS and vcpkg on Windows.
//! Additionally, it will use `pkg-config` on Unix-like systems to find the system installation.
//!
//! ```not_rust
//! # macOS
//! $ brew install openssl@1.1
//!
//! # Arch Linux
//! $ sudo pacman -S pkg-config openssl
//!
//! # Debian and Ubuntu
//! $ sudo apt-get install pkg-config libssl-dev
//!
//! # Fedora
//! $ sudo dnf install pkg-config openssl-devel
//! ```
//!
//! ## Manual
//!
//! A set of environment variables can be used to point `openssl-sys` towards an OpenSSL installation. They will
//! override the automatic detection logic.
//!
//! * `OPENSSL_DIR` - If specified, the directory of an OpenSSL installation. The directory should contain `lib` and
//! `include` subdirectories containing the libraries and headers respectively.
//! * `OPENSSL_LIB_DIR` and `OPENSSL_INCLUDE_DIR` - If specified, the directories containing the OpenSSL libraries and
//! headers respectively. This can be used if the OpenSSL installation is split in a nonstandard directory layout.
//! * `OPENSSL_STATIC` - If set, the crate will statically link to OpenSSL rather than dynamically link.
//! * `OPENSSL_LIBS` - If set, a `:`-separated list of library names to link to (e.g. `ssl:crypto`). This can be used
//! if nonstandard library names were used for whatever reason.
//!
//! Additionally, these variables can be prefixed with the upper-cased target architecture (e.g.
//! `X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR`), which can be useful when cross compiling.
//!
//! # Feature Detection
//!
//! APIs have been added to and removed from the various supported OpenSSL versions, and this library exposes the
//! functionality available in the version being linked against. This means that methods, constants, and even modules
//! will be present when building against one version of OpenSSL but not when building against another! APIs will
//! document any version-specific availability restrictions.
//!
//! A build script can be used to detect the OpenSSL or LibreSSL version at compile time if needed. The `openssl-sys`
//! crate propagates the version via the `DEP_OPENSSL_VERSION_NUMBER` and `DEP_OPENSSL_LIBRESSL_VERSION_NUMBER`
//! environment variables to build scripts. The version format is a hex-encoding of the OpenSSL release version:
//! `0xMNNFFPPS`. For example, version 1.0.2g's encoding is `0x1_00_02_07_0`.
//!
//! For example, let's say we want to adjust the TLSv1.3 cipher suites used by a client, but also want to compile
//! against OpenSSL versions that don't support TLSv1.3:
//!
//! Cargo.toml:
//!
//! ```toml
//! [dependencies]
//! openssl-sys = "0.9"
//! openssl = "0.10"
//! ```
//!
//! build.rs:
//!
//! ```
//! use std::env;
//!
//! fn main() {
//! if let Ok(v) = env::var("DEP_OPENSSL_VERSION_NUMBER") {
//! let version = u64::from_str_radix(&v, 16).unwrap();
//!
//! if version >= 0x1_01_01_00_0 {
//! println!("cargo:rustc-cfg=openssl111");
//! }
//! }
//! }
//! ```
//!
//! lib.rs:
//!
//! ```
//! use openssl::ssl::{SslConnector, SslMethod};
//!
//! let mut ctx = SslConnector::builder(SslMethod::tls()).unwrap();
//!
//! // set_ciphersuites was added in OpenSSL 1.1.1, so we can only call it when linking against that version
//! #[cfg(openssl111)]
//! ctx.set_ciphersuites("TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256").unwrap();
//! ```
extern crate bitflags;
extern crate cfg_if;
extern crate foreign_types;
extern crate lazy_static;
extern crate libc;
extern crate openssl_sys as ffi;
extern crate hex;
extern crate tempdir;
pub use init;
use c_int;
use ErrorStack;