1//! Bindings to OpenSSL
2//!
3//! This crate provides a safe interface to the popular OpenSSL cryptography library. OpenSSL versions 1.0.1 through
4//! 3.x.x and LibreSSL versions 2.5 through 3.7.x are supported.
5//!
6//! # Building
7//!
8//! Both OpenSSL libraries and headers are required to build this crate. There are multiple options available to locate
9//! OpenSSL.
10//!
11//! ## Vendored
12//!
13//! If the `vendored` Cargo feature is enabled, the `openssl-src` crate will be used to compile and statically link to
14//! a copy of OpenSSL. The build process requires a C compiler, perl (and perl-core), and make. The OpenSSL version will generally track
15//! the newest OpenSSL release, and changes to the version are *not* considered breaking changes.
16//!
17//! ```toml
18//! [dependencies]
19//! openssl = { version = "0.10", features = ["vendored"] }
20//! ```
21//!
22//! The vendored copy will not be configured to automatically find the system's root certificates, but the
23//! `openssl-probe` crate can be used to do that instead.
24//!
25//! ## Automatic
26//!
27//! The `openssl-sys` crate will automatically detect OpenSSL installations via Homebrew on macOS and vcpkg on Windows.
28//! Additionally, it will use `pkg-config` on Unix-like systems to find the system installation.
29//!
30//! ```not_rust
31//! # macOS (Homebrew)
32//! $ brew install openssl@3
33//!
34//! # macOS (MacPorts)
35//! $ sudo port install openssl
36//!
37//! # macOS (pkgsrc)
38//! $ sudo pkgin install openssl
39//!
40//! # Arch Linux
41//! $ sudo pacman -S pkg-config openssl
42//!
43//! # Debian and Ubuntu
44//! $ sudo apt-get install pkg-config libssl-dev
45//!
46//! # Fedora
47//! $ sudo dnf install pkg-config openssl-devel
48//!
49//! # Alpine Linux
50//! $ apk add pkgconfig openssl-dev
51//! ```
52//!
53//! ## Manual
54//!
55//! A set of environment variables can be used to point `openssl-sys` towards an OpenSSL installation. They will
56//! override the automatic detection logic.
57//!
58//! * `OPENSSL_DIR` - If specified, the directory of an OpenSSL installation. The directory should contain `lib` and
59//!     `include` subdirectories containing the libraries and headers respectively.
60//! * `OPENSSL_LIB_DIR` and `OPENSSL_INCLUDE_DIR` - If specified, the directories containing the OpenSSL libraries and
61//!     headers respectively. This can be used if the OpenSSL installation is split in a nonstandard directory layout.
62//! * `OPENSSL_STATIC` - If set, the crate will statically link to OpenSSL rather than dynamically link.
63//! * `OPENSSL_LIBS` - If set, a `:`-separated list of library names to link to (e.g. `ssl:crypto`). This can be used
64//!     if nonstandard library names were used for whatever reason.
65//! * `OPENSSL_NO_VENDOR` - If set, always find OpenSSL in the system, even if the `vendored` feature is enabled.
66//!
67//! Additionally, these variables can be prefixed with the upper-cased target architecture (e.g.
68//!     `X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR`), which can be useful when cross compiling.
69//!
70//! # Feature Detection
71//!
72//! APIs have been added to and removed from the various supported OpenSSL versions, and this library exposes the
73//! functionality available in the version being linked against. This means that methods, constants, and even modules
74//! will be present when building against one version of OpenSSL but not when building against another! APIs will
75//! document any version-specific availability restrictions.
76//!
77//! A build script can be used to detect the OpenSSL or LibreSSL version at compile time if needed. The `openssl-sys`
78//! crate propagates the version via the `DEP_OPENSSL_VERSION_NUMBER` and `DEP_OPENSSL_LIBRESSL_VERSION_NUMBER`
79//! environment variables to build scripts. The version format is a hex-encoding of the OpenSSL release version:
80//! `0xMNNFFPPS`. For example, version 1.0.2g's encoding is `0x1_00_02_07_0`.
81//!
82//! For example, let's say we want to adjust the TLSv1.3 cipher suites used by a client, but also want to compile
83//! against OpenSSL versions that don't support TLSv1.3:
84//!
85//! Cargo.toml:
86//!
87//! ```toml
88//! [dependencies]
89//! openssl-sys = "0.9"
90//! openssl = "0.10"
91//! ```
92//!
93//! build.rs:
94//!
95//! ```
96//! use std::env;
97//!
98//! fn main() {
99//!     if let Ok(v) = env::var("DEP_OPENSSL_VERSION_NUMBER") {
100//!         let version = u64::from_str_radix(&v, 16).unwrap();
101//!
102//!         if version >= 0x1_01_01_00_0 {
103//!             println!("cargo:rustc-cfg=openssl111");
104//!         }
105//!     }
106//! }
107//! ```
108//!
109//! lib.rs:
110//!
111//! ```
112//! use openssl::ssl::{SslConnector, SslMethod};
113//!
114//! let mut ctx = SslConnector::builder(SslMethod::tls()).unwrap();
115//!
116//! // set_ciphersuites was added in OpenSSL 1.1.1, so we can only call it when linking against that version
117//! #[cfg(openssl111)]
118//! ctx.set_ciphersuites("TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256").unwrap();
119//! ```
120#![doc(html_root_url = "https://docs.rs/openssl/0.10")]
121#![warn(rust_2018_idioms)]
122#![allow(clippy::uninlined_format_args, clippy::needless_doctest_main)]
123
124#[doc(inline)]
125pub use ffi::init;
126
127use libc::c_int;
128
129extern crate openssl_sys as ffi;
130use crate::error::ErrorStack;
131
132#[macro_use]
133mod macros;
134
135mod bio;
136#[macro_use]
137mod util;
138pub mod aes;
139pub mod asn1;
140pub mod base64;
141pub mod bn;
142pub mod cipher;
143pub mod cipher_ctx;
144#[cfg(all(not(boringssl), not(libressl), not(osslconf = "OPENSSL_NO_CMS")))]
145pub mod cms;
146pub mod conf;
147pub mod derive;
148pub mod dh;
149pub mod dsa;
150pub mod ec;
151pub mod ecdsa;
152pub mod encrypt;
153#[cfg(not(boringssl))]
154pub mod envelope;
155pub mod error;
156pub mod ex_data;
157#[cfg(not(any(libressl, ossl300)))]
158pub mod fips;
159pub mod hash;
160#[cfg(ossl300)]
161pub mod lib_ctx;
162pub mod md;
163pub mod md_ctx;
164pub mod memcmp;
165pub mod nid;
166#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_OCSP")))]
167pub mod ocsp;
168pub mod pkcs12;
169pub mod pkcs5;
170#[cfg(not(boringssl))]
171pub mod pkcs7;
172pub mod pkey;
173pub mod pkey_ctx;
174#[cfg(ossl300)]
175pub mod provider;
176pub mod rand;
177pub mod rsa;
178pub mod sha;
179pub mod sign;
180pub mod srtp;
181pub mod ssl;
182pub mod stack;
183pub mod string;
184pub mod symm;
185pub mod version;
186pub mod x509;
187
188#[cfg(boringssl)]
189type LenType = libc::size_t;
190#[cfg(not(boringssl))]
191type LenType = libc::c_int;
192
193#[cfg(boringssl)]
194type SLenType = libc::ssize_t;
195#[cfg(not(boringssl))]
196type SLenType = libc::c_int;
197
198#[inline]
199fn cvt_p<T>(r: *mut T) -> Result<*mut T, ErrorStack> {
200    if r.is_null() {
201        Err(ErrorStack::get())
202    } else {
203        Ok(r)
204    }
205}
206
207#[inline]
208fn cvt(r: c_int) -> Result<c_int, ErrorStack> {
209    if r <= 0 {
210        Err(ErrorStack::get())
211    } else {
212        Ok(r)
213    }
214}
215
216#[inline]
217fn cvt_n(r: c_int) -> Result<c_int, ErrorStack> {
218    if r < 0 {
219        Err(ErrorStack::get())
220    } else {
221        Ok(r)
222    }
223}
224