openssl_sys/
lib.rs

1#![allow(
2    clippy::missing_safety_doc,
3    dead_code,
4    non_camel_case_types,
5    non_snake_case,
6    non_upper_case_globals,
7    unused_imports
8)]
9#![doc(html_root_url = "https://docs.rs/openssl-sys/0.9")]
10#![recursion_limit = "128"] // configure fixed limit across all rust versions
11
12extern crate libc;
13pub use libc::c_int;
14
15#[cfg(feature = "unstable_boringssl")]
16extern crate bssl_sys;
17
18#[cfg(boringssl)]
19#[path = "."]
20mod boringssl {
21    #[cfg(feature = "unstable_boringssl")]
22    pub use bssl_sys::*;
23    #[cfg(not(feature = "unstable_boringssl"))]
24    include!(concat!(env!("OUT_DIR"), "/bindgen.rs"));
25
26    // BoringSSL does not require initialization.
27    pub fn init() {}
28}
29#[cfg(boringssl)]
30pub use boringssl::*;
31
32#[cfg(feature = "aws-lc")]
33extern crate aws_lc_sys;
34
35#[cfg(awslc)]
36#[path = "."]
37mod aws_lc {
38    #[cfg(all(feature = "aws-lc", not(feature = "aws-lc-fips")))]
39    pub use aws_lc_sys::*;
40
41    #[cfg(feature = "aws-lc-fips")]
42    pub use aws_lc_fips_sys::*;
43
44    #[cfg(not(any(feature = "aws-lc", feature = "aws-lc-fips")))]
45    include!(concat!(env!("OUT_DIR"), "/bindgen.rs"));
46
47    use libc::{c_char, c_long, c_void};
48
49    pub fn init() {
50        unsafe { CRYPTO_library_init() }
51    }
52
53    // BIO_get_mem_data is a C preprocessor macro by definition
54    #[allow(non_snake_case, clippy::not_unsafe_ptr_arg_deref)]
55    pub fn BIO_get_mem_data(b: *mut BIO, pp: *mut *mut c_char) -> c_long {
56        unsafe { BIO_ctrl(b, BIO_CTRL_INFO, 0, pp.cast::<c_void>()) }
57    }
58}
59#[cfg(awslc)]
60pub use aws_lc::*;
61
62#[cfg(openssl)]
63#[path = "."]
64mod openssl {
65    use libc::*;
66
67    #[cfg(feature = "bindgen")]
68    include!(concat!(env!("OUT_DIR"), "/bindgen.rs"));
69
70    pub use self::aes::*;
71    pub use self::asn1::*;
72    pub use self::bio::*;
73    pub use self::bn::*;
74    pub use self::cms::*;
75    #[cfg(ossl300)]
76    pub use self::core_dispatch::*;
77    pub use self::crypto::*;
78    pub use self::dh::*;
79    pub use self::dsa::*;
80    pub use self::dtls1::*;
81    pub use self::ec::*;
82    pub use self::err::*;
83    pub use self::evp::*;
84    #[cfg(not(feature = "bindgen"))]
85    pub use self::handwritten::*;
86    pub use self::obj_mac::*;
87    pub use self::ocsp::*;
88    pub use self::pem::*;
89    pub use self::pkcs7::*;
90    pub use self::rsa::*;
91    pub use self::sha::*;
92    pub use self::srtp::*;
93    pub use self::ssl::*;
94    pub use self::ssl3::*;
95    pub use self::tls1::*;
96    pub use self::types::*;
97    pub use self::x509::*;
98    pub use self::x509_vfy::*;
99    pub use self::x509v3::*;
100
101    #[macro_use]
102    mod macros;
103
104    mod aes;
105    mod asn1;
106    mod bio;
107    mod bn;
108    mod cms;
109    #[cfg(ossl300)]
110    mod core_dispatch;
111    mod crypto;
112    mod dh;
113    mod dsa;
114    mod dtls1;
115    mod ec;
116    mod err;
117    mod evp;
118    #[cfg(not(feature = "bindgen"))]
119    mod handwritten;
120    mod obj_mac;
121    mod ocsp;
122    mod pem;
123    mod pkcs7;
124    mod rsa;
125    mod sha;
126    mod srtp;
127    mod ssl;
128    mod ssl3;
129    mod tls1;
130    mod types;
131    mod x509;
132    mod x509_vfy;
133    mod x509v3;
134
135    use std::sync::Once;
136    // explicitly initialize to work around https://github.com/openssl/openssl/issues/3505
137    static INIT: Once = Once::new();
138
139    // FIXME remove
140    pub type PasswordCallback = unsafe extern "C" fn(
141        buf: *mut c_char,
142        size: c_int,
143        rwflag: c_int,
144        user_data: *mut c_void,
145    ) -> c_int;
146
147    #[cfg(ossl110)]
148    pub fn init() {
149        use std::ptr;
150
151        #[cfg(not(ossl111b))]
152        let init_options = OPENSSL_INIT_LOAD_SSL_STRINGS;
153        #[cfg(ossl111b)]
154        let init_options = OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_NO_ATEXIT;
155
156        INIT.call_once(|| unsafe {
157            OPENSSL_init_ssl(init_options, ptr::null_mut());
158        })
159    }
160
161    #[cfg(libressl)]
162    pub fn init() {}
163
164    #[cfg(not(any(ossl110, libressl)))]
165    pub fn init() {
166        use std::io::{self, Write};
167        use std::mem;
168        use std::process;
169        use std::sync::{Mutex, MutexGuard};
170
171        static mut MUTEXES: *mut Vec<Mutex<()>> = 0 as *mut Vec<Mutex<()>>;
172        static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> =
173            0 as *mut Vec<Option<MutexGuard<'static, ()>>>;
174
175        unsafe extern "C" fn locking_function(
176            mode: c_int,
177            n: c_int,
178            _file: *const c_char,
179            _line: c_int,
180        ) {
181            let mutex = &(&(*MUTEXES))[n as usize];
182
183            if mode & CRYPTO_LOCK != 0 {
184                (&mut (*GUARDS))[n as usize] = Some(mutex.lock().unwrap());
185            } else {
186                if let None = (&mut (*GUARDS))[n as usize].take() {
187                    let _ = writeln!(
188                        io::stderr(),
189                        "BUG: rust-openssl lock {} already unlocked, aborting",
190                        n
191                    );
192                    process::abort();
193                }
194            }
195        }
196
197        cfg_if! {
198            if #[cfg(unix)] {
199                fn set_id_callback() {
200                    unsafe extern "C" fn thread_id() -> c_ulong {
201                        ::libc::pthread_self() as c_ulong
202                    }
203
204                    unsafe {
205                        CRYPTO_set_id_callback__fixed_rust(Some(thread_id));
206                    }
207                }
208            } else {
209                fn set_id_callback() {}
210            }
211        }
212
213        INIT.call_once(|| unsafe {
214            SSL_library_init();
215            SSL_load_error_strings();
216            OPENSSL_add_all_algorithms_noconf();
217
218            let num_locks = CRYPTO_num_locks();
219            let mut mutexes = Box::new(Vec::new());
220            for _ in 0..num_locks {
221                mutexes.push(Mutex::new(()));
222            }
223            MUTEXES = mem::transmute(mutexes);
224            let guards: Box<Vec<Option<MutexGuard<()>>>> =
225                Box::new((0..num_locks).map(|_| None).collect());
226            GUARDS = mem::transmute(guards);
227
228            CRYPTO_set_locking_callback__fixed_rust(Some(locking_function));
229            set_id_callback();
230        })
231    }
232
233    /// Disable explicit initialization of the openssl libs.
234    ///
235    /// This is only appropriate to use if the openssl crate is being consumed by an application
236    /// that will be performing the initialization explicitly.
237    ///
238    /// # Safety
239    ///
240    /// In some versions of openssl, skipping initialization will fall back to the default procedure
241    /// while other will cause difficult to debug errors so care must be taken when calling this.
242    pub unsafe fn assume_init() {
243        INIT.call_once(|| {});
244    }
245}
246#[cfg(openssl)]
247pub use openssl::*;