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(libressl)]
154    pub fn init() {}
155
156    #[cfg(not(any(ossl110, libressl)))]
157    pub fn init() {
158        use std::io::{self, Write};
159        use std::mem;
160        use std::process;
161        use std::sync::{Mutex, MutexGuard};
162
163        static mut MUTEXES: *mut Vec<Mutex<()>> = 0 as *mut Vec<Mutex<()>>;
164        static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> =
165            0 as *mut Vec<Option<MutexGuard<'static, ()>>>;
166
167        unsafe extern "C" fn locking_function(
168            mode: c_int,
169            n: c_int,
170            _file: *const c_char,
171            _line: c_int,
172        ) {
173            let mutex = &(&(*MUTEXES))[n as usize];
174
175            if mode & CRYPTO_LOCK != 0 {
176                (&mut (*GUARDS))[n as usize] = Some(mutex.lock().unwrap());
177            } else {
178                if let None = (&mut (*GUARDS))[n as usize].take() {
179                    let _ = writeln!(
180                        io::stderr(),
181                        "BUG: rust-openssl lock {} already unlocked, aborting",
182                        n
183                    );
184                    process::abort();
185                }
186            }
187        }
188
189        cfg_if! {
190            if #[cfg(unix)] {
191                fn set_id_callback() {
192                    unsafe extern "C" fn thread_id() -> c_ulong {
193                        ::libc::pthread_self() as c_ulong
194                    }
195
196                    unsafe {
197                        CRYPTO_set_id_callback(Some(thread_id));
198                    }
199                }
200            } else {
201                fn set_id_callback() {}
202            }
203        }
204
205        INIT.call_once(|| unsafe {
206            SSL_library_init();
207            SSL_load_error_strings();
208            OPENSSL_add_all_algorithms_noconf();
209
210            let num_locks = CRYPTO_num_locks();
211            let mut mutexes = Box::new(Vec::new());
212            for _ in 0..num_locks {
213                mutexes.push(Mutex::new(()));
214            }
215            MUTEXES = mem::transmute(mutexes);
216            let guards: Box<Vec<Option<MutexGuard<()>>>> =
217                Box::new((0..num_locks).map(|_| None).collect());
218            GUARDS = mem::transmute(guards);
219
220            CRYPTO_set_locking_callback(Some(locking_function));
221            set_id_callback();
222        })
223    }
224
225    /// Disable explicit initialization of the openssl libs.
226    ///
227    /// This is only appropriate to use if the openssl crate is being consumed by an application
228    /// that will be performing the initialization explicitly.
229    ///
230    /// # Safety
231    ///
232    /// In some versions of openssl, skipping initialization will fall back to the default procedure
233    /// while other will cause difficult to debug errors so care must be taken when calling this.
234    pub unsafe fn assume_init() {
235        INIT.call_once(|| {});
236    }
237}
238#[cfg(openssl)]
239pub use openssl::*;