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