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