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