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