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