• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2018-2019, Cloudflare, Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright notice,
9 //       this list of conditions and the following disclaimer.
10 //
11 //     * Redistributions in binary form must reproduce the above copyright
12 //       notice, this list of conditions and the following disclaimer in the
13 //       documentation and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
19 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 use std::ffi;
28 use std::ptr;
29 use std::slice;
30 
31 use std::io::Write;
32 
33 use libc::c_char;
34 use libc::c_int;
35 use libc::c_long;
36 use libc::c_uint;
37 use libc::c_void;
38 
39 use crate::Error;
40 use crate::Result;
41 
42 use crate::Connection;
43 use crate::ConnectionError;
44 
45 use crate::crypto;
46 use crate::packet;
47 
48 const TLS1_3_VERSION: u16 = 0x0304;
49 const TLS_ALERT_ERROR: u64 = 0x100;
50 const INTERNAL_ERROR: u64 = 0x01;
51 
52 #[allow(non_camel_case_types)]
53 #[repr(transparent)]
54 struct SSL_METHOD(c_void);
55 
56 #[allow(non_camel_case_types)]
57 #[repr(transparent)]
58 struct SSL_CTX(c_void);
59 
60 #[allow(non_camel_case_types)]
61 #[repr(transparent)]
62 struct SSL(c_void);
63 
64 #[allow(non_camel_case_types)]
65 #[repr(transparent)]
66 struct SSL_CIPHER(c_void);
67 
68 #[allow(non_camel_case_types)]
69 #[repr(transparent)]
70 struct SSL_SESSION(c_void);
71 
72 #[allow(non_camel_case_types)]
73 #[repr(transparent)]
74 struct X509_VERIFY_PARAM(c_void);
75 
76 #[allow(non_camel_case_types)]
77 #[repr(transparent)]
78 #[cfg(windows)]
79 struct X509_STORE(c_void);
80 
81 #[allow(non_camel_case_types)]
82 #[repr(transparent)]
83 #[cfg(windows)]
84 struct X509(c_void);
85 
86 #[allow(non_camel_case_types)]
87 #[repr(transparent)]
88 struct STACK_OF(c_void);
89 
90 #[allow(non_camel_case_types)]
91 #[repr(transparent)]
92 struct CRYPTO_BUFFER(c_void);
93 
94 #[repr(C)]
95 #[allow(non_camel_case_types)]
96 struct SSL_QUIC_METHOD {
97     set_read_secret: extern fn(
98         ssl: *mut SSL,
99         level: crypto::Level,
100         cipher: *const SSL_CIPHER,
101         secret: *const u8,
102         secret_len: usize,
103     ) -> c_int,
104 
105     set_write_secret: extern fn(
106         ssl: *mut SSL,
107         level: crypto::Level,
108         cipher: *const SSL_CIPHER,
109         secret: *const u8,
110         secret_len: usize,
111     ) -> c_int,
112 
113     add_handshake_data: extern fn(
114         ssl: *mut SSL,
115         level: crypto::Level,
116         data: *const u8,
117         len: usize,
118     ) -> c_int,
119 
120     flush_flight: extern fn(ssl: *mut SSL) -> c_int,
121 
122     send_alert:
123         extern fn(ssl: *mut SSL, level: crypto::Level, alert: u8) -> c_int,
124 }
125 
126 #[cfg(test)]
127 #[repr(C)]
128 #[allow(non_camel_case_types)]
129 #[allow(dead_code)]
130 enum ssl_private_key_result_t {
131     ssl_private_key_success,
132     ssl_private_key_retry,
133     ssl_private_key_failure,
134 }
135 
136 #[cfg(test)]
137 #[repr(C)]
138 #[allow(non_camel_case_types)]
139 struct SSL_PRIVATE_KEY_METHOD {
140     sign: extern fn(
141         ssl: *mut SSL,
142         out: *mut u8,
143         out_len: *mut usize,
144         max_out: usize,
145         signature_algorithm: u16,
146         r#in: *const u8,
147         in_len: usize,
148     ) -> ssl_private_key_result_t,
149 
150     decrypt: extern fn(
151         ssl: *mut SSL,
152         out: *mut u8,
153         out_len: *mut usize,
154         max_out: usize,
155         r#in: *const u8,
156         in_len: usize,
157     ) -> ssl_private_key_result_t,
158 
159     complete: extern fn(
160         ssl: *mut SSL,
161         out: *mut u8,
162         out_len: *mut usize,
163         max_out: usize,
164     ) -> ssl_private_key_result_t,
165 }
166 
167 lazy_static::lazy_static! {
168     /// BoringSSL Extra Data Index for Quiche Connections
169     pub static ref QUICHE_EX_DATA_INDEX: c_int = unsafe {
170         SSL_get_ex_new_index(0, ptr::null(), ptr::null(), ptr::null(), ptr::null())
171     };
172 }
173 
174 static QUICHE_STREAM_METHOD: SSL_QUIC_METHOD = SSL_QUIC_METHOD {
175     set_read_secret,
176     set_write_secret,
177     add_handshake_data,
178     flush_flight,
179     send_alert,
180 };
181 
182 pub struct Context(*mut SSL_CTX);
183 
184 impl Context {
new() -> Result<Context>185     pub fn new() -> Result<Context> {
186         unsafe {
187             let ctx_raw = SSL_CTX_new(TLS_method());
188 
189             let mut ctx = Context(ctx_raw);
190 
191             ctx.set_session_callback();
192 
193             ctx.load_ca_certs()?;
194 
195             Ok(ctx)
196         }
197     }
198 
199     #[cfg(feature = "boringssl-boring-crate")]
from_boring(ssl_ctx: boring::ssl::SslContext) -> Context200     pub fn from_boring(ssl_ctx: boring::ssl::SslContext) -> Context {
201         use foreign_types_shared::ForeignType;
202 
203         let mut ctx = Context(ssl_ctx.into_ptr() as _);
204         ctx.set_session_callback();
205 
206         ctx
207     }
208 
new_handshake(&mut self) -> Result<Handshake>209     pub fn new_handshake(&mut self) -> Result<Handshake> {
210         unsafe {
211             let ssl = SSL_new(self.as_mut_ptr());
212             Ok(Handshake::new(ssl))
213         }
214     }
215 
load_verify_locations_from_file(&mut self, file: &str) -> Result<()>216     pub fn load_verify_locations_from_file(&mut self, file: &str) -> Result<()> {
217         let file = ffi::CString::new(file).map_err(|_| Error::TlsFail)?;
218         map_result(unsafe {
219             SSL_CTX_load_verify_locations(
220                 self.as_mut_ptr(),
221                 file.as_ptr(),
222                 std::ptr::null(),
223             )
224         })
225     }
226 
load_verify_locations_from_directory( &mut self, path: &str, ) -> Result<()>227     pub fn load_verify_locations_from_directory(
228         &mut self, path: &str,
229     ) -> Result<()> {
230         let path = ffi::CString::new(path).map_err(|_| Error::TlsFail)?;
231         map_result(unsafe {
232             SSL_CTX_load_verify_locations(
233                 self.as_mut_ptr(),
234                 std::ptr::null(),
235                 path.as_ptr(),
236             )
237         })
238     }
239 
use_certificate_chain_file(&mut self, file: &str) -> Result<()>240     pub fn use_certificate_chain_file(&mut self, file: &str) -> Result<()> {
241         let cstr = ffi::CString::new(file).map_err(|_| Error::TlsFail)?;
242         map_result(unsafe {
243             SSL_CTX_use_certificate_chain_file(self.as_mut_ptr(), cstr.as_ptr())
244         })
245     }
246 
use_privkey_file(&mut self, file: &str) -> Result<()>247     pub fn use_privkey_file(&mut self, file: &str) -> Result<()> {
248         let cstr = ffi::CString::new(file).map_err(|_| Error::TlsFail)?;
249         map_result(unsafe {
250             SSL_CTX_use_PrivateKey_file(self.as_mut_ptr(), cstr.as_ptr(), 1)
251         })
252     }
253 
254     #[cfg(not(windows))]
load_ca_certs(&mut self) -> Result<()>255     fn load_ca_certs(&mut self) -> Result<()> {
256         unsafe { map_result(SSL_CTX_set_default_verify_paths(self.as_mut_ptr())) }
257     }
258 
259     #[cfg(windows)]
load_ca_certs(&mut self) -> Result<()>260     fn load_ca_certs(&mut self) -> Result<()> {
261         unsafe {
262             let cstr = ffi::CString::new("Root").map_err(|_| Error::TlsFail)?;
263             let sys_store = winapi::um::wincrypt::CertOpenSystemStoreA(
264                 0,
265                 cstr.as_ptr() as winapi::um::winnt::LPCSTR,
266             );
267             if sys_store.is_null() {
268                 return Err(Error::TlsFail);
269             }
270 
271             let ctx_store = SSL_CTX_get_cert_store(self.as_mut_ptr());
272             if ctx_store.is_null() {
273                 return Err(Error::TlsFail);
274             }
275 
276             let mut ctx_p = winapi::um::wincrypt::CertEnumCertificatesInStore(
277                 sys_store,
278                 ptr::null(),
279             );
280 
281             while !ctx_p.is_null() {
282                 let in_p = (*ctx_p).pbCertEncoded as *const u8;
283 
284                 let cert = d2i_X509(
285                     ptr::null_mut(),
286                     &in_p,
287                     (*ctx_p).cbCertEncoded as i32,
288                 );
289                 if !cert.is_null() {
290                     X509_STORE_add_cert(ctx_store, cert);
291                 }
292 
293                 X509_free(cert);
294 
295                 ctx_p = winapi::um::wincrypt::CertEnumCertificatesInStore(
296                     sys_store, ctx_p,
297                 );
298             }
299 
300             // tidy up
301             winapi::um::wincrypt::CertFreeCertificateContext(ctx_p);
302             winapi::um::wincrypt::CertCloseStore(sys_store, 0);
303         }
304 
305         Ok(())
306     }
307 
set_session_callback(&mut self)308     fn set_session_callback(&mut self) {
309         unsafe {
310             // This is needed to enable the session callback on the client. On
311             // the server it doesn't do anything.
312             SSL_CTX_set_session_cache_mode(
313                 self.as_mut_ptr(),
314                 0x0001, // SSL_SESS_CACHE_CLIENT
315             );
316 
317             SSL_CTX_sess_set_new_cb(self.as_mut_ptr(), new_session);
318         };
319     }
320 
set_verify(&mut self, verify: bool)321     pub fn set_verify(&mut self, verify: bool) {
322         // true  -> 0x01 SSL_VERIFY_PEER
323         // false -> 0x00 SSL_VERIFY_NONE
324         let mode = i32::from(verify);
325 
326         unsafe {
327             SSL_CTX_set_verify(self.as_mut_ptr(), mode, ptr::null());
328         }
329     }
330 
enable_keylog(&mut self)331     pub fn enable_keylog(&mut self) {
332         unsafe {
333             SSL_CTX_set_keylog_callback(self.as_mut_ptr(), keylog);
334         }
335     }
336 
set_alpn(&mut self, v: &[&[u8]]) -> Result<()>337     pub fn set_alpn(&mut self, v: &[&[u8]]) -> Result<()> {
338         let mut protos: Vec<u8> = Vec::new();
339 
340         for proto in v {
341             protos.push(proto.len() as u8);
342             protos.extend_from_slice(proto);
343         }
344 
345         // Configure ALPN for servers.
346         unsafe {
347             SSL_CTX_set_alpn_select_cb(
348                 self.as_mut_ptr(),
349                 select_alpn,
350                 ptr::null_mut(),
351             );
352         }
353 
354         // Configure ALPN for clients.
355         map_result_zero_is_success(unsafe {
356             SSL_CTX_set_alpn_protos(
357                 self.as_mut_ptr(),
358                 protos.as_ptr(),
359                 protos.len(),
360             )
361         })
362     }
363 
set_ticket_key(&mut self, key: &[u8]) -> Result<()>364     pub fn set_ticket_key(&mut self, key: &[u8]) -> Result<()> {
365         map_result(unsafe {
366             SSL_CTX_set_tlsext_ticket_keys(
367                 self.as_mut_ptr(),
368                 key.as_ptr(),
369                 key.len(),
370             )
371         })
372     }
373 
set_early_data_enabled(&mut self, enabled: bool)374     pub fn set_early_data_enabled(&mut self, enabled: bool) {
375         let enabled = i32::from(enabled);
376 
377         unsafe {
378             SSL_CTX_set_early_data_enabled(self.as_mut_ptr(), enabled);
379         }
380     }
381 
as_mut_ptr(&mut self) -> *mut SSL_CTX382     fn as_mut_ptr(&mut self) -> *mut SSL_CTX {
383         self.0
384     }
385 }
386 
387 // NOTE: These traits are not automatically implemented for Context due to the
388 // raw pointer it wraps. However, the underlying data is not aliased (as Context
389 // should be its only owner), and there is no interior mutability, as the
390 // pointer is not accessed directly outside of this module, and the Context
391 // object API should preserve Rust's borrowing guarantees.
392 unsafe impl std::marker::Send for Context {}
393 unsafe impl std::marker::Sync for Context {}
394 
395 impl Drop for Context {
drop(&mut self)396     fn drop(&mut self) {
397         unsafe { SSL_CTX_free(self.as_mut_ptr()) }
398     }
399 }
400 
401 pub struct Handshake {
402     /// Raw pointer
403     ptr: *mut SSL,
404     /// SSL_process_quic_post_handshake should be called when whenever
405     /// SSL_provide_quic_data is called to process the provided data.
406     provided_data_outstanding: bool,
407 }
408 
409 impl Handshake {
410     #[cfg(feature = "ffi")]
from_ptr(ssl: *mut c_void) -> Handshake411     pub unsafe fn from_ptr(ssl: *mut c_void) -> Handshake {
412         Handshake::new(ssl as *mut SSL)
413     }
414 
new(ptr: *mut SSL) -> Handshake415     fn new(ptr: *mut SSL) -> Handshake {
416         Handshake {
417             ptr,
418             provided_data_outstanding: false,
419         }
420     }
421 
get_error(&self, ret_code: c_int) -> c_int422     pub fn get_error(&self, ret_code: c_int) -> c_int {
423         unsafe { SSL_get_error(self.as_ptr(), ret_code) }
424     }
425 
init(&mut self, is_server: bool) -> Result<()>426     pub fn init(&mut self, is_server: bool) -> Result<()> {
427         self.set_state(is_server);
428 
429         self.set_min_proto_version(TLS1_3_VERSION);
430         self.set_max_proto_version(TLS1_3_VERSION);
431 
432         self.set_quic_method()?;
433 
434         // TODO: the early data context should include transport parameters and
435         // HTTP/3 SETTINGS in wire format.
436         self.set_quic_early_data_context(b"quiche")?;
437 
438         self.set_quiet_shutdown(true);
439 
440         Ok(())
441     }
442 
use_legacy_codepoint(&mut self, use_legacy: bool)443     pub fn use_legacy_codepoint(&mut self, use_legacy: bool) {
444         unsafe {
445             SSL_set_quic_use_legacy_codepoint(
446                 self.as_mut_ptr(),
447                 use_legacy as c_int,
448             );
449         }
450     }
451 
set_state(&mut self, is_server: bool)452     pub fn set_state(&mut self, is_server: bool) {
453         unsafe {
454             if is_server {
455                 SSL_set_accept_state(self.as_mut_ptr());
456             } else {
457                 SSL_set_connect_state(self.as_mut_ptr());
458             }
459         }
460     }
461 
set_ex_data<T>(&mut self, idx: c_int, data: *const T) -> Result<()>462     pub fn set_ex_data<T>(&mut self, idx: c_int, data: *const T) -> Result<()> {
463         map_result(unsafe {
464             let ptr = data as *const c_void;
465             SSL_set_ex_data(self.as_mut_ptr(), idx, ptr)
466         })
467     }
468 
set_quic_method(&mut self) -> Result<()>469     pub fn set_quic_method(&mut self) -> Result<()> {
470         map_result(unsafe {
471             SSL_set_quic_method(self.as_mut_ptr(), &QUICHE_STREAM_METHOD)
472         })
473     }
474 
set_quic_early_data_context(&mut self, context: &[u8]) -> Result<()>475     pub fn set_quic_early_data_context(&mut self, context: &[u8]) -> Result<()> {
476         map_result(unsafe {
477             SSL_set_quic_early_data_context(
478                 self.as_mut_ptr(),
479                 context.as_ptr(),
480                 context.len(),
481             )
482         })
483     }
484 
set_min_proto_version(&mut self, version: u16)485     pub fn set_min_proto_version(&mut self, version: u16) {
486         unsafe { SSL_set_min_proto_version(self.as_mut_ptr(), version) }
487     }
488 
set_max_proto_version(&mut self, version: u16)489     pub fn set_max_proto_version(&mut self, version: u16) {
490         unsafe { SSL_set_max_proto_version(self.as_mut_ptr(), version) }
491     }
492 
set_quiet_shutdown(&mut self, mode: bool)493     pub fn set_quiet_shutdown(&mut self, mode: bool) {
494         unsafe { SSL_set_quiet_shutdown(self.as_mut_ptr(), i32::from(mode)) }
495     }
496 
set_host_name(&mut self, name: &str) -> Result<()>497     pub fn set_host_name(&mut self, name: &str) -> Result<()> {
498         let cstr = ffi::CString::new(name).map_err(|_| Error::TlsFail)?;
499         let rc =
500             unsafe { SSL_set_tlsext_host_name(self.as_mut_ptr(), cstr.as_ptr()) };
501         self.map_result_ssl(rc)?;
502 
503         let param = unsafe { SSL_get0_param(self.as_mut_ptr()) };
504 
505         map_result(unsafe {
506             X509_VERIFY_PARAM_set1_host(param, cstr.as_ptr(), name.len())
507         })
508     }
509 
set_quic_transport_params(&mut self, buf: &[u8]) -> Result<()>510     pub fn set_quic_transport_params(&mut self, buf: &[u8]) -> Result<()> {
511         let rc = unsafe {
512             SSL_set_quic_transport_params(
513                 self.as_mut_ptr(),
514                 buf.as_ptr(),
515                 buf.len(),
516             )
517         };
518         self.map_result_ssl(rc)
519     }
520 
quic_transport_params(&self) -> &[u8]521     pub fn quic_transport_params(&self) -> &[u8] {
522         let mut ptr: *const u8 = ptr::null();
523         let mut len: usize = 0;
524 
525         unsafe {
526             SSL_get_peer_quic_transport_params(self.as_ptr(), &mut ptr, &mut len);
527         }
528 
529         if len == 0 {
530             return &mut [];
531         }
532 
533         unsafe { slice::from_raw_parts(ptr, len) }
534     }
535 
alpn_protocol(&self) -> &[u8]536     pub fn alpn_protocol(&self) -> &[u8] {
537         let mut ptr: *const u8 = ptr::null();
538         let mut len: u32 = 0;
539 
540         unsafe {
541             SSL_get0_alpn_selected(self.as_ptr(), &mut ptr, &mut len);
542         }
543 
544         if len == 0 {
545             return &mut [];
546         }
547 
548         unsafe { slice::from_raw_parts(ptr, len as usize) }
549     }
550 
server_name(&self) -> Option<&str>551     pub fn server_name(&self) -> Option<&str> {
552         let s = unsafe {
553             let ptr = SSL_get_servername(
554                 self.as_ptr(),
555                 0, // TLSEXT_NAMETYPE_host_name
556             );
557 
558             if ptr.is_null() {
559                 return None;
560             }
561 
562             ffi::CStr::from_ptr(ptr)
563         };
564 
565         s.to_str().ok()
566     }
567 
set_session(&mut self, session: &[u8]) -> Result<()>568     pub fn set_session(&mut self, session: &[u8]) -> Result<()> {
569         unsafe {
570             let ctx = SSL_get_SSL_CTX(self.as_ptr());
571 
572             if ctx.is_null() {
573                 return Err(Error::TlsFail);
574             }
575 
576             let session =
577                 SSL_SESSION_from_bytes(session.as_ptr(), session.len(), ctx);
578 
579             if session.is_null() {
580                 return Err(Error::TlsFail);
581             }
582 
583             let rc = SSL_set_session(self.as_mut_ptr(), session);
584             SSL_SESSION_free(session);
585 
586             map_result(rc)
587         }
588     }
589 
provide_data( &mut self, level: crypto::Level, buf: &[u8], ) -> Result<()>590     pub fn provide_data(
591         &mut self, level: crypto::Level, buf: &[u8],
592     ) -> Result<()> {
593         self.provided_data_outstanding = true;
594         let rc = unsafe {
595             SSL_provide_quic_data(
596                 self.as_mut_ptr(),
597                 level,
598                 buf.as_ptr(),
599                 buf.len(),
600             )
601         };
602         self.map_result_ssl(rc)
603     }
604 
do_handshake(&mut self, ex_data: &mut ExData) -> Result<()>605     pub fn do_handshake(&mut self, ex_data: &mut ExData) -> Result<()> {
606         self.set_ex_data(*QUICHE_EX_DATA_INDEX, ex_data)?;
607         let rc = unsafe { SSL_do_handshake(self.as_mut_ptr()) };
608         self.set_ex_data::<Connection>(*QUICHE_EX_DATA_INDEX, std::ptr::null())?;
609 
610         self.set_transport_error(ex_data, rc);
611         self.map_result_ssl(rc)
612     }
613 
process_post_handshake(&mut self, ex_data: &mut ExData) -> Result<()>614     pub fn process_post_handshake(&mut self, ex_data: &mut ExData) -> Result<()> {
615         // If SSL_provide_quic_data hasn't been called since we last called
616         // SSL_process_quic_post_handshake, then there's nothing to do.
617         if !self.provided_data_outstanding {
618             return Ok(());
619         }
620         self.provided_data_outstanding = false;
621 
622         self.set_ex_data(*QUICHE_EX_DATA_INDEX, ex_data)?;
623         let rc = unsafe { SSL_process_quic_post_handshake(self.as_mut_ptr()) };
624         self.set_ex_data::<Connection>(*QUICHE_EX_DATA_INDEX, std::ptr::null())?;
625 
626         self.set_transport_error(ex_data, rc);
627         self.map_result_ssl(rc)
628     }
629 
reset_early_data_reject(&mut self)630     pub fn reset_early_data_reject(&mut self) {
631         unsafe { SSL_reset_early_data_reject(self.as_mut_ptr()) };
632     }
633 
write_level(&self) -> crypto::Level634     pub fn write_level(&self) -> crypto::Level {
635         unsafe { SSL_quic_write_level(self.as_ptr()) }
636     }
637 
cipher(&self) -> Option<crypto::Algorithm>638     pub fn cipher(&self) -> Option<crypto::Algorithm> {
639         let cipher =
640             map_result_ptr(unsafe { SSL_get_current_cipher(self.as_ptr()) });
641 
642         get_cipher_from_ptr(cipher.ok()?).ok()
643     }
644 
curve(&self) -> Option<String>645     pub fn curve(&self) -> Option<String> {
646         let curve = unsafe {
647             let curve_id = SSL_get_curve_id(self.as_ptr());
648             if curve_id == 0 {
649                 return None;
650             }
651 
652             let curve_name = SSL_get_curve_name(curve_id);
653             match ffi::CStr::from_ptr(curve_name).to_str() {
654                 Ok(v) => v,
655 
656                 Err(_) => return None,
657             }
658         };
659 
660         Some(curve.to_string())
661     }
662 
sigalg(&self) -> Option<String>663     pub fn sigalg(&self) -> Option<String> {
664         let sigalg = unsafe {
665             let sigalg_id = SSL_get_peer_signature_algorithm(self.as_ptr());
666             if sigalg_id == 0 {
667                 return None;
668             }
669 
670             let sigalg_name = SSL_get_signature_algorithm_name(sigalg_id, 1);
671             match ffi::CStr::from_ptr(sigalg_name).to_str() {
672                 Ok(v) => v,
673 
674                 Err(_) => return None,
675             }
676         };
677 
678         Some(sigalg.to_string())
679     }
680 
peer_cert_chain(&self) -> Option<Vec<&[u8]>>681     pub fn peer_cert_chain(&self) -> Option<Vec<&[u8]>> {
682         let cert_chain = unsafe {
683             let chain =
684                 map_result_ptr(SSL_get0_peer_certificates(self.as_ptr())).ok()?;
685 
686             let num = sk_num(chain);
687             if num <= 0 {
688                 return None;
689             }
690 
691             let mut cert_chain = vec![];
692             for i in 0..num {
693                 let buffer =
694                     map_result_ptr(sk_value(chain, i) as *const CRYPTO_BUFFER)
695                         .ok()?;
696 
697                 let out_len = CRYPTO_BUFFER_len(buffer);
698                 if out_len == 0 {
699                     return None;
700                 }
701 
702                 let out = CRYPTO_BUFFER_data(buffer);
703                 let slice = slice::from_raw_parts(out, out_len);
704 
705                 cert_chain.push(slice);
706             }
707 
708             cert_chain
709         };
710 
711         Some(cert_chain)
712     }
713 
peer_cert(&self) -> Option<&[u8]>714     pub fn peer_cert(&self) -> Option<&[u8]> {
715         let peer_cert = unsafe {
716             let chain =
717                 map_result_ptr(SSL_get0_peer_certificates(self.as_ptr())).ok()?;
718             if sk_num(chain) <= 0 {
719                 return None;
720             }
721 
722             let buffer =
723                 map_result_ptr(sk_value(chain, 0) as *const CRYPTO_BUFFER)
724                     .ok()?;
725 
726             let out_len = CRYPTO_BUFFER_len(buffer);
727             if out_len == 0 {
728                 return None;
729             }
730 
731             let out = CRYPTO_BUFFER_data(buffer);
732             slice::from_raw_parts(out, out_len)
733         };
734 
735         Some(peer_cert)
736     }
737 
738     #[cfg(test)]
set_options(&mut self, opts: u32)739     pub fn set_options(&mut self, opts: u32) {
740         unsafe {
741             SSL_set_options(self.as_mut_ptr(), opts);
742         }
743     }
744 
745     // Only used for testing handling of failure during key signing.
746     #[cfg(test)]
set_failing_private_key_method(&mut self)747     pub fn set_failing_private_key_method(&mut self) {
748         extern fn failing_sign(
749             _ssl: *mut SSL, _out: *mut u8, _out_len: *mut usize, _max_out: usize,
750             _signature_algorithm: u16, _in: *const u8, _in_len: usize,
751         ) -> ssl_private_key_result_t {
752             ssl_private_key_result_t::ssl_private_key_failure
753         }
754 
755         extern fn failing_decrypt(
756             _ssl: *mut SSL, _out: *mut u8, _out_len: *mut usize, _max_out: usize,
757             _in: *const u8, _in_len: usize,
758         ) -> ssl_private_key_result_t {
759             ssl_private_key_result_t::ssl_private_key_failure
760         }
761 
762         extern fn failing_complete(
763             _ssl: *mut SSL, _out: *mut u8, _out_len: *mut usize, _max_out: usize,
764         ) -> ssl_private_key_result_t {
765             ssl_private_key_result_t::ssl_private_key_failure
766         }
767 
768         static QUICHE_PRIVATE_KEY_METHOD: SSL_PRIVATE_KEY_METHOD =
769             SSL_PRIVATE_KEY_METHOD {
770                 decrypt: failing_decrypt,
771                 sign: failing_sign,
772                 complete: failing_complete,
773             };
774 
775         unsafe {
776             SSL_set_private_key_method(
777                 self.as_mut_ptr(),
778                 &QUICHE_PRIVATE_KEY_METHOD,
779             );
780         }
781     }
782 
is_completed(&self) -> bool783     pub fn is_completed(&self) -> bool {
784         unsafe { SSL_in_init(self.as_ptr()) == 0 }
785     }
786 
is_resumed(&self) -> bool787     pub fn is_resumed(&self) -> bool {
788         unsafe { SSL_session_reused(self.as_ptr()) == 1 }
789     }
790 
is_in_early_data(&self) -> bool791     pub fn is_in_early_data(&self) -> bool {
792         unsafe { SSL_in_early_data(self.as_ptr()) == 1 }
793     }
794 
clear(&mut self) -> Result<()>795     pub fn clear(&mut self) -> Result<()> {
796         let rc = unsafe { SSL_clear(self.as_mut_ptr()) };
797         self.map_result_ssl(rc)
798     }
799 
as_ptr(&self) -> *const SSL800     fn as_ptr(&self) -> *const SSL {
801         self.ptr
802     }
803 
as_mut_ptr(&mut self) -> *mut SSL804     fn as_mut_ptr(&mut self) -> *mut SSL {
805         self.ptr
806     }
807 
map_result_ssl(&mut self, bssl_result: c_int) -> Result<()>808     fn map_result_ssl(&mut self, bssl_result: c_int) -> Result<()> {
809         match bssl_result {
810             1 => Ok(()),
811 
812             _ => {
813                 let ssl_err = self.get_error(bssl_result);
814                 match ssl_err {
815                     // SSL_ERROR_SSL
816                     1 => {
817                         log_ssl_error();
818 
819                         Err(Error::TlsFail)
820                     },
821 
822                     // SSL_ERROR_WANT_READ
823                     2 => Err(Error::Done),
824 
825                     // SSL_ERROR_WANT_WRITE
826                     3 => Err(Error::Done),
827 
828                     // SSL_ERROR_WANT_X509_LOOKUP
829                     4 => Err(Error::Done),
830 
831                     // SSL_ERROR_SYSCALL
832                     5 => Err(Error::TlsFail),
833 
834                     // SSL_ERROR_PENDING_SESSION
835                     11 => Err(Error::Done),
836 
837                     // SSL_ERROR_PENDING_CERTIFICATE
838                     12 => Err(Error::Done),
839 
840                     // SSL_ERROR_WANT_PRIVATE_KEY_OPERATION
841                     13 => Err(Error::Done),
842 
843                     // SSL_ERROR_PENDING_TICKET
844                     14 => Err(Error::Done),
845 
846                     // SSL_ERROR_EARLY_DATA_REJECTED
847                     15 => {
848                         self.reset_early_data_reject();
849                         Err(Error::Done)
850                     },
851 
852                     // SSL_ERROR_WANT_CERTIFICATE_VERIFY
853                     16 => Err(Error::Done),
854 
855                     _ => Err(Error::TlsFail),
856                 }
857             },
858         }
859     }
860 
set_transport_error(&mut self, ex_data: &mut ExData, bssl_result: c_int)861     fn set_transport_error(&mut self, ex_data: &mut ExData, bssl_result: c_int) {
862         // SSL_ERROR_SSL
863         if self.get_error(bssl_result) == 1 {
864             // SSL_ERROR_SSL can't be recovered so ensure we set a
865             // local_error so the connection is closed.
866             // See https://www.openssl.org/docs/man1.1.1/man3/SSL_get_error.html
867             if ex_data.local_error.is_none() {
868                 *ex_data.local_error = Some(ConnectionError {
869                     is_app: false,
870                     error_code: INTERNAL_ERROR,
871                     reason: Vec::new(),
872                 })
873             }
874         }
875     }
876 }
877 
878 // NOTE: These traits are not automatically implemented for Handshake due to the
879 // raw pointer it wraps. However, the underlying data is not aliased (as
880 // Handshake should be its only owner), and there is no interior mutability, as
881 // the pointer is not accessed directly outside of this module, and the
882 // Handshake object API should preserve Rust's borrowing guarantees.
883 unsafe impl std::marker::Send for Handshake {}
884 unsafe impl std::marker::Sync for Handshake {}
885 
886 impl Drop for Handshake {
drop(&mut self)887     fn drop(&mut self) {
888         unsafe { SSL_free(self.as_mut_ptr()) }
889     }
890 }
891 
892 pub struct ExData<'a> {
893     pub application_protos: &'a Vec<Vec<u8>>,
894 
895     pub pkt_num_spaces: &'a mut [packet::PktNumSpace; packet::Epoch::count()],
896 
897     pub session: &'a mut Option<Vec<u8>>,
898 
899     pub local_error: &'a mut Option<super::ConnectionError>,
900 
901     pub keylog: Option<&'a mut Box<dyn std::io::Write + Send + Sync>>,
902 
903     pub trace_id: &'a str,
904 
905     pub is_server: bool,
906 }
907 
get_ex_data_from_ptr<'a, T>(ptr: *mut SSL, idx: c_int) -> Option<&'a mut T>908 fn get_ex_data_from_ptr<'a, T>(ptr: *mut SSL, idx: c_int) -> Option<&'a mut T> {
909     unsafe {
910         let data = SSL_get_ex_data(ptr, idx) as *mut T;
911         data.as_mut()
912     }
913 }
914 
get_cipher_from_ptr(cipher: *const SSL_CIPHER) -> Result<crypto::Algorithm>915 fn get_cipher_from_ptr(cipher: *const SSL_CIPHER) -> Result<crypto::Algorithm> {
916     let cipher_id = unsafe { SSL_CIPHER_get_id(cipher) };
917 
918     let alg = match cipher_id {
919         0x0300_1301 => crypto::Algorithm::AES128_GCM,
920         0x0300_1302 => crypto::Algorithm::AES256_GCM,
921         0x0300_1303 => crypto::Algorithm::ChaCha20_Poly1305,
922         _ => return Err(Error::TlsFail),
923     };
924 
925     Ok(alg)
926 }
927 
set_read_secret( ssl: *mut SSL, level: crypto::Level, cipher: *const SSL_CIPHER, secret: *const u8, secret_len: usize, ) -> c_int928 extern fn set_read_secret(
929     ssl: *mut SSL, level: crypto::Level, cipher: *const SSL_CIPHER,
930     secret: *const u8, secret_len: usize,
931 ) -> c_int {
932     let ex_data = match get_ex_data_from_ptr::<ExData>(ssl, *QUICHE_EX_DATA_INDEX)
933     {
934         Some(v) => v,
935 
936         None => return 0,
937     };
938 
939     trace!("{} set read secret lvl={:?}", ex_data.trace_id, level);
940 
941     let space = match level {
942         crypto::Level::Initial =>
943             &mut ex_data.pkt_num_spaces[packet::Epoch::Initial],
944         crypto::Level::ZeroRTT =>
945             &mut ex_data.pkt_num_spaces[packet::Epoch::Application],
946         crypto::Level::Handshake =>
947             &mut ex_data.pkt_num_spaces[packet::Epoch::Handshake],
948         crypto::Level::OneRTT =>
949             &mut ex_data.pkt_num_spaces[packet::Epoch::Application],
950     };
951 
952     let aead = match get_cipher_from_ptr(cipher) {
953         Ok(v) => v,
954 
955         Err(_) => return 0,
956     };
957 
958     // 0-RTT read secrets are present only on the server.
959     if level != crypto::Level::ZeroRTT || ex_data.is_server {
960         let secret = unsafe { slice::from_raw_parts(secret, secret_len) };
961 
962         let open = match crypto::Open::from_secret(aead, secret) {
963             Ok(v) => v,
964 
965             Err(_) => return 0,
966         };
967 
968         if level == crypto::Level::ZeroRTT {
969             space.crypto_0rtt_open = Some(open);
970             return 1;
971         }
972 
973         space.crypto_open = Some(open);
974     }
975 
976     1
977 }
978 
set_write_secret( ssl: *mut SSL, level: crypto::Level, cipher: *const SSL_CIPHER, secret: *const u8, secret_len: usize, ) -> c_int979 extern fn set_write_secret(
980     ssl: *mut SSL, level: crypto::Level, cipher: *const SSL_CIPHER,
981     secret: *const u8, secret_len: usize,
982 ) -> c_int {
983     let ex_data = match get_ex_data_from_ptr::<ExData>(ssl, *QUICHE_EX_DATA_INDEX)
984     {
985         Some(v) => v,
986 
987         None => return 0,
988     };
989 
990     trace!("{} set write secret lvl={:?}", ex_data.trace_id, level);
991 
992     let space = match level {
993         crypto::Level::Initial =>
994             &mut ex_data.pkt_num_spaces[packet::Epoch::Initial],
995         crypto::Level::ZeroRTT =>
996             &mut ex_data.pkt_num_spaces[packet::Epoch::Application],
997         crypto::Level::Handshake =>
998             &mut ex_data.pkt_num_spaces[packet::Epoch::Handshake],
999         crypto::Level::OneRTT =>
1000             &mut ex_data.pkt_num_spaces[packet::Epoch::Application],
1001     };
1002 
1003     let aead = match get_cipher_from_ptr(cipher) {
1004         Ok(v) => v,
1005 
1006         Err(_) => return 0,
1007     };
1008 
1009     // 0-RTT write secrets are present only on the client.
1010     if level != crypto::Level::ZeroRTT || !ex_data.is_server {
1011         let secret = unsafe { slice::from_raw_parts(secret, secret_len) };
1012 
1013         let seal = match crypto::Seal::from_secret(aead, secret) {
1014             Ok(v) => v,
1015 
1016             Err(_) => return 0,
1017         };
1018 
1019         space.crypto_seal = Some(seal);
1020     }
1021 
1022     1
1023 }
1024 
add_handshake_data( ssl: *mut SSL, level: crypto::Level, data: *const u8, len: usize, ) -> c_int1025 extern fn add_handshake_data(
1026     ssl: *mut SSL, level: crypto::Level, data: *const u8, len: usize,
1027 ) -> c_int {
1028     let ex_data = match get_ex_data_from_ptr::<ExData>(ssl, *QUICHE_EX_DATA_INDEX)
1029     {
1030         Some(v) => v,
1031 
1032         None => return 0,
1033     };
1034 
1035     trace!(
1036         "{} write message lvl={:?} len={}",
1037         ex_data.trace_id,
1038         level,
1039         len
1040     );
1041 
1042     let buf = unsafe { slice::from_raw_parts(data, len) };
1043 
1044     let space = match level {
1045         crypto::Level::Initial =>
1046             &mut ex_data.pkt_num_spaces[packet::Epoch::Initial],
1047         crypto::Level::ZeroRTT => unreachable!(),
1048         crypto::Level::Handshake =>
1049             &mut ex_data.pkt_num_spaces[packet::Epoch::Handshake],
1050         crypto::Level::OneRTT =>
1051             &mut ex_data.pkt_num_spaces[packet::Epoch::Application],
1052     };
1053 
1054     if space.crypto_stream.send.write(buf, false).is_err() {
1055         return 0;
1056     }
1057 
1058     1
1059 }
1060 
flush_flight(_ssl: *mut SSL) -> c_int1061 extern fn flush_flight(_ssl: *mut SSL) -> c_int {
1062     // We don't really need to anything here since the output packets are
1063     // generated separately, when conn.send() is called.
1064 
1065     1
1066 }
1067 
send_alert(ssl: *mut SSL, level: crypto::Level, alert: u8) -> c_int1068 extern fn send_alert(ssl: *mut SSL, level: crypto::Level, alert: u8) -> c_int {
1069     let ex_data = match get_ex_data_from_ptr::<ExData>(ssl, *QUICHE_EX_DATA_INDEX)
1070     {
1071         Some(v) => v,
1072 
1073         None => return 0,
1074     };
1075 
1076     trace!(
1077         "{} send alert lvl={:?} alert={:x}",
1078         ex_data.trace_id,
1079         level,
1080         alert
1081     );
1082 
1083     let error: u64 = TLS_ALERT_ERROR + u64::from(alert);
1084     *ex_data.local_error = Some(ConnectionError {
1085         is_app: false,
1086         error_code: error,
1087         reason: Vec::new(),
1088     });
1089 
1090     1
1091 }
1092 
keylog(ssl: *mut SSL, line: *const c_char)1093 extern fn keylog(ssl: *mut SSL, line: *const c_char) {
1094     let ex_data = match get_ex_data_from_ptr::<ExData>(ssl, *QUICHE_EX_DATA_INDEX)
1095     {
1096         Some(v) => v,
1097 
1098         None => return,
1099     };
1100 
1101     if let Some(keylog) = &mut ex_data.keylog {
1102         let data = unsafe { ffi::CStr::from_ptr(line).to_bytes() };
1103 
1104         let mut full_line = Vec::with_capacity(data.len() + 1);
1105         full_line.extend_from_slice(data);
1106         full_line.push(b'\n');
1107 
1108         keylog.write_all(&full_line[..]).ok();
1109     }
1110 }
1111 
select_alpn( ssl: *mut SSL, out: *mut *const u8, out_len: *mut u8, inp: *mut u8, in_len: c_uint, _arg: *mut c_void, ) -> c_int1112 extern fn select_alpn(
1113     ssl: *mut SSL, out: *mut *const u8, out_len: *mut u8, inp: *mut u8,
1114     in_len: c_uint, _arg: *mut c_void,
1115 ) -> c_int {
1116     let ex_data = match get_ex_data_from_ptr::<ExData>(ssl, *QUICHE_EX_DATA_INDEX)
1117     {
1118         Some(v) => v,
1119 
1120         None => return 3, // SSL_TLSEXT_ERR_NOACK
1121     };
1122 
1123     if ex_data.application_protos.is_empty() {
1124         return 3; // SSL_TLSEXT_ERR_NOACK
1125     }
1126 
1127     let mut protos = octets::Octets::with_slice(unsafe {
1128         slice::from_raw_parts(inp, in_len as usize)
1129     });
1130 
1131     while let Ok(proto) = protos.get_bytes_with_u8_length() {
1132         let found = ex_data.application_protos.iter().any(|expected| {
1133             trace!(
1134                 "checking peer ALPN {:?} against {:?}",
1135                 std::str::from_utf8(proto.as_ref()),
1136                 std::str::from_utf8(expected.as_slice())
1137             );
1138 
1139             if expected.len() == proto.len() &&
1140                 expected.as_slice() == proto.as_ref()
1141             {
1142                 unsafe {
1143                     *out = expected.as_slice().as_ptr();
1144                     *out_len = expected.len() as u8;
1145                 }
1146 
1147                 return true;
1148             }
1149 
1150             false
1151         });
1152 
1153         if found {
1154             return 0; // SSL_TLSEXT_ERR_OK
1155         }
1156     }
1157 
1158     3 // SSL_TLSEXT_ERR_NOACK
1159 }
1160 
new_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int1161 extern fn new_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int {
1162     let ex_data = match get_ex_data_from_ptr::<ExData>(ssl, *QUICHE_EX_DATA_INDEX)
1163     {
1164         Some(v) => v,
1165 
1166         None => return 0,
1167     };
1168 
1169     let handshake = Handshake::new(ssl);
1170     let peer_params = handshake.quic_transport_params();
1171 
1172     // Serialize session object into buffer.
1173     let session_bytes = unsafe {
1174         let mut out: *mut u8 = std::ptr::null_mut();
1175         let mut out_len: usize = 0;
1176 
1177         if SSL_SESSION_to_bytes(session, &mut out, &mut out_len) == 0 {
1178             return 0;
1179         }
1180 
1181         let session_bytes = std::slice::from_raw_parts(out, out_len).to_vec();
1182         OPENSSL_free(out as *mut c_void);
1183 
1184         session_bytes
1185     };
1186 
1187     let mut buffer =
1188         Vec::with_capacity(8 + peer_params.len() + 8 + session_bytes.len());
1189 
1190     let session_bytes_len = session_bytes.len() as u64;
1191 
1192     if buffer.write(&session_bytes_len.to_be_bytes()).is_err() {
1193         std::mem::forget(handshake);
1194         return 0;
1195     }
1196 
1197     if buffer.write(&session_bytes).is_err() {
1198         std::mem::forget(handshake);
1199         return 0;
1200     }
1201 
1202     let peer_params_len = peer_params.len() as u64;
1203 
1204     if buffer.write(&peer_params_len.to_be_bytes()).is_err() {
1205         std::mem::forget(handshake);
1206         return 0;
1207     }
1208 
1209     if buffer.write(peer_params).is_err() {
1210         std::mem::forget(handshake);
1211         return 0;
1212     }
1213 
1214     *ex_data.session = Some(buffer);
1215 
1216     // Prevent handshake from being freed, as we still need it.
1217     std::mem::forget(handshake);
1218 
1219     0
1220 }
1221 
map_result(bssl_result: c_int) -> Result<()>1222 fn map_result(bssl_result: c_int) -> Result<()> {
1223     match bssl_result {
1224         1 => Ok(()),
1225         _ => Err(Error::TlsFail),
1226     }
1227 }
1228 
map_result_zero_is_success(bssl_result: c_int) -> Result<()>1229 fn map_result_zero_is_success(bssl_result: c_int) -> Result<()> {
1230     match bssl_result {
1231         0 => Ok(()),
1232         _ => Err(Error::TlsFail),
1233     }
1234 }
1235 
map_result_ptr<'a, T>(bssl_result: *const T) -> Result<&'a T>1236 fn map_result_ptr<'a, T>(bssl_result: *const T) -> Result<&'a T> {
1237     match unsafe { bssl_result.as_ref() } {
1238         Some(v) => Ok(v),
1239         None => Err(Error::TlsFail),
1240     }
1241 }
1242 
log_ssl_error()1243 fn log_ssl_error() {
1244     let err = [0; 1024];
1245 
1246     unsafe {
1247         let e = ERR_peek_error();
1248         ERR_error_string_n(e, err.as_ptr(), err.len());
1249     }
1250 
1251     trace!("{}", std::str::from_utf8(&err).unwrap());
1252 }
1253 
1254 extern {
1255     // SSL_METHOD
TLS_method() -> *const SSL_METHOD1256     fn TLS_method() -> *const SSL_METHOD;
1257 
1258     // SSL_CTX
SSL_CTX_new(method: *const SSL_METHOD) -> *mut SSL_CTX1259     fn SSL_CTX_new(method: *const SSL_METHOD) -> *mut SSL_CTX;
SSL_CTX_free(ctx: *mut SSL_CTX)1260     fn SSL_CTX_free(ctx: *mut SSL_CTX);
1261 
SSL_CTX_use_certificate_chain_file( ctx: *mut SSL_CTX, file: *const c_char, ) -> c_int1262     fn SSL_CTX_use_certificate_chain_file(
1263         ctx: *mut SSL_CTX, file: *const c_char,
1264     ) -> c_int;
1265 
SSL_CTX_use_PrivateKey_file( ctx: *mut SSL_CTX, file: *const c_char, ty: c_int, ) -> c_int1266     fn SSL_CTX_use_PrivateKey_file(
1267         ctx: *mut SSL_CTX, file: *const c_char, ty: c_int,
1268     ) -> c_int;
1269 
SSL_CTX_load_verify_locations( ctx: *mut SSL_CTX, file: *const c_char, path: *const c_char, ) -> c_int1270     fn SSL_CTX_load_verify_locations(
1271         ctx: *mut SSL_CTX, file: *const c_char, path: *const c_char,
1272     ) -> c_int;
1273 
1274     #[cfg(not(windows))]
SSL_CTX_set_default_verify_paths(ctx: *mut SSL_CTX) -> c_int1275     fn SSL_CTX_set_default_verify_paths(ctx: *mut SSL_CTX) -> c_int;
1276 
1277     #[cfg(windows)]
SSL_CTX_get_cert_store(ctx: *mut SSL_CTX) -> *mut X509_STORE1278     fn SSL_CTX_get_cert_store(ctx: *mut SSL_CTX) -> *mut X509_STORE;
1279 
SSL_CTX_set_verify(ctx: *mut SSL_CTX, mode: c_int, cb: *const c_void)1280     fn SSL_CTX_set_verify(ctx: *mut SSL_CTX, mode: c_int, cb: *const c_void);
1281 
SSL_CTX_set_keylog_callback( ctx: *mut SSL_CTX, cb: extern fn(ssl: *mut SSL, line: *const c_char), )1282     fn SSL_CTX_set_keylog_callback(
1283         ctx: *mut SSL_CTX, cb: extern fn(ssl: *mut SSL, line: *const c_char),
1284     );
1285 
SSL_CTX_set_tlsext_ticket_keys( ctx: *mut SSL_CTX, key: *const u8, key_len: usize, ) -> c_int1286     fn SSL_CTX_set_tlsext_ticket_keys(
1287         ctx: *mut SSL_CTX, key: *const u8, key_len: usize,
1288     ) -> c_int;
1289 
SSL_CTX_set_alpn_protos( ctx: *mut SSL_CTX, protos: *const u8, protos_len: usize, ) -> c_int1290     fn SSL_CTX_set_alpn_protos(
1291         ctx: *mut SSL_CTX, protos: *const u8, protos_len: usize,
1292     ) -> c_int;
1293 
SSL_CTX_set_alpn_select_cb( ctx: *mut SSL_CTX, cb: extern fn( ssl: *mut SSL, out: *mut *const u8, out_len: *mut u8, inp: *mut u8, in_len: c_uint, arg: *mut c_void, ) -> c_int, arg: *mut c_void, )1294     fn SSL_CTX_set_alpn_select_cb(
1295         ctx: *mut SSL_CTX,
1296         cb: extern fn(
1297             ssl: *mut SSL,
1298             out: *mut *const u8,
1299             out_len: *mut u8,
1300             inp: *mut u8,
1301             in_len: c_uint,
1302             arg: *mut c_void,
1303         ) -> c_int,
1304         arg: *mut c_void,
1305     );
1306 
SSL_CTX_set_early_data_enabled(ctx: *mut SSL_CTX, enabled: i32)1307     fn SSL_CTX_set_early_data_enabled(ctx: *mut SSL_CTX, enabled: i32);
1308 
SSL_CTX_set_session_cache_mode(ctx: *mut SSL_CTX, mode: c_int) -> c_int1309     fn SSL_CTX_set_session_cache_mode(ctx: *mut SSL_CTX, mode: c_int) -> c_int;
1310 
SSL_CTX_sess_set_new_cb( ctx: *mut SSL_CTX, cb: extern fn(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int, )1311     fn SSL_CTX_sess_set_new_cb(
1312         ctx: *mut SSL_CTX,
1313         cb: extern fn(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int,
1314     );
1315 
1316     // SSL
SSL_get_ex_new_index( argl: c_long, argp: *const c_void, unused: *const c_void, dup_unused: *const c_void, free_func: *const c_void, ) -> c_int1317     fn SSL_get_ex_new_index(
1318         argl: c_long, argp: *const c_void, unused: *const c_void,
1319         dup_unused: *const c_void, free_func: *const c_void,
1320     ) -> c_int;
1321 
SSL_new(ctx: *mut SSL_CTX) -> *mut SSL1322     fn SSL_new(ctx: *mut SSL_CTX) -> *mut SSL;
1323 
SSL_get_error(ssl: *const SSL, ret_code: c_int) -> c_int1324     fn SSL_get_error(ssl: *const SSL, ret_code: c_int) -> c_int;
1325 
SSL_set_accept_state(ssl: *mut SSL)1326     fn SSL_set_accept_state(ssl: *mut SSL);
SSL_set_connect_state(ssl: *mut SSL)1327     fn SSL_set_connect_state(ssl: *mut SSL);
1328 
SSL_get0_param(ssl: *mut SSL) -> *mut X509_VERIFY_PARAM1329     fn SSL_get0_param(ssl: *mut SSL) -> *mut X509_VERIFY_PARAM;
1330 
SSL_set_ex_data(ssl: *mut SSL, idx: c_int, ptr: *const c_void) -> c_int1331     fn SSL_set_ex_data(ssl: *mut SSL, idx: c_int, ptr: *const c_void) -> c_int;
SSL_get_ex_data(ssl: *mut SSL, idx: c_int) -> *mut c_void1332     fn SSL_get_ex_data(ssl: *mut SSL, idx: c_int) -> *mut c_void;
1333 
SSL_get_current_cipher(ssl: *const SSL) -> *const SSL_CIPHER1334     fn SSL_get_current_cipher(ssl: *const SSL) -> *const SSL_CIPHER;
1335 
SSL_get_curve_id(ssl: *const SSL) -> u161336     fn SSL_get_curve_id(ssl: *const SSL) -> u16;
SSL_get_curve_name(curve: u16) -> *const c_char1337     fn SSL_get_curve_name(curve: u16) -> *const c_char;
1338 
SSL_get_peer_signature_algorithm(ssl: *const SSL) -> u161339     fn SSL_get_peer_signature_algorithm(ssl: *const SSL) -> u16;
SSL_get_signature_algorithm_name( sigalg: u16, include_curve: i32, ) -> *const c_char1340     fn SSL_get_signature_algorithm_name(
1341         sigalg: u16, include_curve: i32,
1342     ) -> *const c_char;
1343 
SSL_set_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int1344     fn SSL_set_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int;
1345 
SSL_get_SSL_CTX(ssl: *const SSL) -> *mut SSL_CTX1346     fn SSL_get_SSL_CTX(ssl: *const SSL) -> *mut SSL_CTX;
1347 
SSL_get0_peer_certificates(ssl: *const SSL) -> *const STACK_OF1348     fn SSL_get0_peer_certificates(ssl: *const SSL) -> *const STACK_OF;
1349 
SSL_set_min_proto_version(ssl: *mut SSL, version: u16)1350     fn SSL_set_min_proto_version(ssl: *mut SSL, version: u16);
SSL_set_max_proto_version(ssl: *mut SSL, version: u16)1351     fn SSL_set_max_proto_version(ssl: *mut SSL, version: u16);
1352 
SSL_set_quiet_shutdown(ssl: *mut SSL, mode: c_int)1353     fn SSL_set_quiet_shutdown(ssl: *mut SSL, mode: c_int);
1354 
SSL_set_tlsext_host_name(ssl: *mut SSL, name: *const c_char) -> c_int1355     fn SSL_set_tlsext_host_name(ssl: *mut SSL, name: *const c_char) -> c_int;
1356 
SSL_set_quic_transport_params( ssl: *mut SSL, params: *const u8, params_len: usize, ) -> c_int1357     fn SSL_set_quic_transport_params(
1358         ssl: *mut SSL, params: *const u8, params_len: usize,
1359     ) -> c_int;
1360 
SSL_set_quic_method( ssl: *mut SSL, quic_method: *const SSL_QUIC_METHOD, ) -> c_int1361     fn SSL_set_quic_method(
1362         ssl: *mut SSL, quic_method: *const SSL_QUIC_METHOD,
1363     ) -> c_int;
1364 
SSL_set_quic_use_legacy_codepoint(ssl: *mut SSL, use_legacy: c_int)1365     fn SSL_set_quic_use_legacy_codepoint(ssl: *mut SSL, use_legacy: c_int);
1366 
SSL_set_quic_early_data_context( ssl: *mut SSL, context: *const u8, context_len: usize, ) -> c_int1367     fn SSL_set_quic_early_data_context(
1368         ssl: *mut SSL, context: *const u8, context_len: usize,
1369     ) -> c_int;
1370 
1371     #[cfg(test)]
SSL_set_options(ssl: *mut SSL, opts: u32) -> u321372     fn SSL_set_options(ssl: *mut SSL, opts: u32) -> u32;
1373 
1374     #[cfg(test)]
SSL_set_private_key_method( ssl: *mut SSL, key_method: *const SSL_PRIVATE_KEY_METHOD, )1375     fn SSL_set_private_key_method(
1376         ssl: *mut SSL, key_method: *const SSL_PRIVATE_KEY_METHOD,
1377     );
1378 
SSL_get_peer_quic_transport_params( ssl: *const SSL, out_params: *mut *const u8, out_params_len: *mut usize, )1379     fn SSL_get_peer_quic_transport_params(
1380         ssl: *const SSL, out_params: *mut *const u8, out_params_len: *mut usize,
1381     );
1382 
SSL_get0_alpn_selected( ssl: *const SSL, out: *mut *const u8, out_len: *mut u32, )1383     fn SSL_get0_alpn_selected(
1384         ssl: *const SSL, out: *mut *const u8, out_len: *mut u32,
1385     );
1386 
SSL_get_servername(ssl: *const SSL, ty: c_int) -> *const c_char1387     fn SSL_get_servername(ssl: *const SSL, ty: c_int) -> *const c_char;
1388 
SSL_provide_quic_data( ssl: *mut SSL, level: crypto::Level, data: *const u8, len: usize, ) -> c_int1389     fn SSL_provide_quic_data(
1390         ssl: *mut SSL, level: crypto::Level, data: *const u8, len: usize,
1391     ) -> c_int;
1392 
SSL_process_quic_post_handshake(ssl: *mut SSL) -> c_int1393     fn SSL_process_quic_post_handshake(ssl: *mut SSL) -> c_int;
1394 
SSL_reset_early_data_reject(ssl: *mut SSL)1395     fn SSL_reset_early_data_reject(ssl: *mut SSL);
1396 
SSL_do_handshake(ssl: *mut SSL) -> c_int1397     fn SSL_do_handshake(ssl: *mut SSL) -> c_int;
1398 
SSL_quic_write_level(ssl: *const SSL) -> crypto::Level1399     fn SSL_quic_write_level(ssl: *const SSL) -> crypto::Level;
1400 
SSL_session_reused(ssl: *const SSL) -> c_int1401     fn SSL_session_reused(ssl: *const SSL) -> c_int;
1402 
SSL_in_init(ssl: *const SSL) -> c_int1403     fn SSL_in_init(ssl: *const SSL) -> c_int;
1404 
SSL_in_early_data(ssl: *const SSL) -> c_int1405     fn SSL_in_early_data(ssl: *const SSL) -> c_int;
1406 
SSL_clear(ssl: *mut SSL) -> c_int1407     fn SSL_clear(ssl: *mut SSL) -> c_int;
1408 
SSL_free(ssl: *mut SSL)1409     fn SSL_free(ssl: *mut SSL);
1410 
1411     // SSL_CIPHER
SSL_CIPHER_get_id(cipher: *const SSL_CIPHER) -> c_uint1412     fn SSL_CIPHER_get_id(cipher: *const SSL_CIPHER) -> c_uint;
1413 
1414     // SSL_SESSION
SSL_SESSION_to_bytes( session: *const SSL_SESSION, out: *mut *mut u8, out_len: *mut usize, ) -> c_int1415     fn SSL_SESSION_to_bytes(
1416         session: *const SSL_SESSION, out: *mut *mut u8, out_len: *mut usize,
1417     ) -> c_int;
1418 
SSL_SESSION_from_bytes( input: *const u8, input_len: usize, ctx: *const SSL_CTX, ) -> *mut SSL_SESSION1419     fn SSL_SESSION_from_bytes(
1420         input: *const u8, input_len: usize, ctx: *const SSL_CTX,
1421     ) -> *mut SSL_SESSION;
1422 
SSL_SESSION_free(session: *mut SSL_SESSION)1423     fn SSL_SESSION_free(session: *mut SSL_SESSION);
1424 
1425     // X509_VERIFY_PARAM
X509_VERIFY_PARAM_set1_host( param: *mut X509_VERIFY_PARAM, name: *const c_char, namelen: usize, ) -> c_int1426     fn X509_VERIFY_PARAM_set1_host(
1427         param: *mut X509_VERIFY_PARAM, name: *const c_char, namelen: usize,
1428     ) -> c_int;
1429 
1430     // X509_STORE
1431     #[cfg(windows)]
X509_STORE_add_cert(ctx: *mut X509_STORE, x: *mut X509) -> c_int1432     fn X509_STORE_add_cert(ctx: *mut X509_STORE, x: *mut X509) -> c_int;
1433 
1434     // X509
1435     #[cfg(windows)]
X509_free(x: *mut X509)1436     fn X509_free(x: *mut X509);
1437     #[cfg(windows)]
d2i_X509(px: *mut X509, input: *const *const u8, len: c_int) -> *mut X5091438     fn d2i_X509(px: *mut X509, input: *const *const u8, len: c_int) -> *mut X509;
1439 
1440     // STACK_OF
sk_num(stack: *const STACK_OF) -> c_int1441     fn sk_num(stack: *const STACK_OF) -> c_int;
sk_value(stack: *const STACK_OF, idx: c_int) -> *mut c_void1442     fn sk_value(stack: *const STACK_OF, idx: c_int) -> *mut c_void;
1443 
1444     // CRYPTO_BUFFER
CRYPTO_BUFFER_len(buffer: *const CRYPTO_BUFFER) -> usize1445     fn CRYPTO_BUFFER_len(buffer: *const CRYPTO_BUFFER) -> usize;
CRYPTO_BUFFER_data(buffer: *const CRYPTO_BUFFER) -> *const u81446     fn CRYPTO_BUFFER_data(buffer: *const CRYPTO_BUFFER) -> *const u8;
1447 
1448     // ERR
ERR_peek_error() -> c_uint1449     fn ERR_peek_error() -> c_uint;
1450 
ERR_error_string_n(err: c_uint, buf: *const u8, len: usize)1451     fn ERR_error_string_n(err: c_uint, buf: *const u8, len: usize);
1452 
1453     // OPENSSL
OPENSSL_free(ptr: *mut c_void)1454     fn OPENSSL_free(ptr: *mut c_void);
1455 }
1456