/rust/git/checkouts/nss-rs-71e20fe79ef91440/9b94ca3/src/ssl.rs
Line | Count | Source |
1 | | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
2 | | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
3 | | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
4 | | // option. This file may not be copied, modified, or distributed |
5 | | // except according to those terms. |
6 | | |
7 | | use std::os::raw::{c_uint, c_void}; |
8 | | |
9 | | use crate::{ |
10 | | Epoch, |
11 | | err::{Res, secstatus_to_res}, |
12 | | nss_prelude::SECStatus, |
13 | | prio::PRFileDesc, |
14 | | }; |
15 | | |
16 | | mod nss_ssl { |
17 | | #![allow( |
18 | | dead_code, |
19 | | non_upper_case_globals, |
20 | | non_snake_case, |
21 | | nonstandard_style, |
22 | | unsafe_op_in_unsafe_fn, |
23 | | unused_qualifications, |
24 | | clippy::all, |
25 | | clippy::nursery, |
26 | | clippy::pedantic, |
27 | | clippy::restriction, |
28 | | reason = "For included bindgen code." |
29 | | )] |
30 | | use crate::{ |
31 | | err::PRErrorCode, |
32 | | nss_prelude::*, |
33 | | p11::{CERTCertificateStr, HpkeAeadId, HpkeKdfId, PK11SymKeyStr, SECKEYPrivateKeyStr}, |
34 | | prio::{PRFileDesc, PRFileInfo, PRFileInfo64, PRIOVec}, |
35 | | time::PRTime, |
36 | | }; |
37 | | |
38 | | include!(concat!(env!("OUT_DIR"), "/nss_ssl.rs")); |
39 | | } |
40 | | pub use nss_ssl::*; |
41 | | |
42 | | #[expect(non_snake_case, unused, reason = "OK here.")] |
43 | | mod SSLOption { |
44 | | include!(concat!(env!("OUT_DIR"), "/nss_sslopt.rs")); |
45 | | } |
46 | | |
47 | | // Remap some constants. |
48 | | #[expect(non_upper_case_globals, reason = "OK here.")] |
49 | | pub const SECSuccess: SECStatus = _SECStatus_SECSuccess; |
50 | | #[expect(non_upper_case_globals, reason = "OK here.")] |
51 | | pub const SECFailure: SECStatus = _SECStatus_SECFailure; |
52 | | |
53 | | #[derive(Debug, Copy, Clone)] |
54 | | #[repr(u32)] |
55 | | pub enum Opt { |
56 | | Locking = SSLOption::SSL_NO_LOCKS, |
57 | | Tickets = SSLOption::SSL_ENABLE_SESSION_TICKETS, |
58 | | OcspStapling = SSLOption::SSL_ENABLE_OCSP_STAPLING, |
59 | | Alpn = SSLOption::SSL_ENABLE_ALPN, |
60 | | ExtendedMasterSecret = SSLOption::SSL_ENABLE_EXTENDED_MASTER_SECRET, |
61 | | SignedCertificateTimestamps = SSLOption::SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, |
62 | | EarlyData = SSLOption::SSL_ENABLE_0RTT_DATA, |
63 | | RecordSizeLimit = SSLOption::SSL_RECORD_SIZE_LIMIT, |
64 | | Tls13CompatMode = SSLOption::SSL_ENABLE_TLS13_COMPAT_MODE, |
65 | | HelloDowngradeCheck = SSLOption::SSL_ENABLE_HELLO_DOWNGRADE_CHECK, |
66 | | SuppressEndOfEarlyData = SSLOption::SSL_SUPPRESS_END_OF_EARLY_DATA, |
67 | | Grease = SSLOption::SSL_ENABLE_GREASE, |
68 | | EnableChExtensionPermutation = SSLOption::SSL_ENABLE_CH_EXTENSION_PERMUTATION, |
69 | | } |
70 | | |
71 | | impl Opt { |
72 | | #[must_use] |
73 | 18.0k | pub const fn as_int(self) -> PRInt32 { |
74 | 18.0k | self as PRInt32 |
75 | 18.0k | } |
76 | | |
77 | | // Some options are backwards, like SSL_NO_LOCKS, so use this to manage that. |
78 | 18.0k | fn map_enabled(self, enabled: bool) -> PRIntn { |
79 | 18.0k | let v = match self { |
80 | 2.57k | Self::Locking => !enabled, |
81 | 15.4k | _ => enabled, |
82 | | }; |
83 | 18.0k | PRIntn::from(v) |
84 | 18.0k | } |
85 | | |
86 | 18.0k | pub(crate) fn set(self, fd: *mut PRFileDesc, value: bool) -> Res<()> { |
87 | 18.0k | secstatus_to_res(unsafe { SSL_OptionSet(fd, self.as_int(), self.map_enabled(value)) }) |
88 | 18.0k | } |
89 | | } |
90 | | |
91 | | experimental_api!(SSL_HelloRetryRequestCallback( |
92 | | fd: *mut PRFileDesc, |
93 | | cb: SSLHelloRetryRequestCallback, |
94 | | arg: *mut c_void, |
95 | | )); |
96 | | experimental_api!(SSL_RecordLayerWriteCallback( |
97 | | fd: *mut PRFileDesc, |
98 | | cb: SSLRecordWriteCallback, |
99 | | arg: *mut c_void, |
100 | | )); |
101 | | experimental_api!(SSL_RecordLayerData( |
102 | | fd: *mut PRFileDesc, |
103 | | epoch: Epoch, |
104 | | ct: SSLContentType::Type, |
105 | | data: *const u8, |
106 | | len: c_uint, |
107 | | )); |
108 | | experimental_api!(SSL_SendSessionTicket( |
109 | | fd: *mut PRFileDesc, |
110 | | extra: *const u8, |
111 | | len: c_uint, |
112 | | )); |
113 | | experimental_api!(SSL_SetMaxEarlyDataSize(fd: *mut PRFileDesc, size: u32)); |
114 | | experimental_api!(SSL_SetResumptionToken( |
115 | | fd: *mut PRFileDesc, |
116 | | token: *const u8, |
117 | | len: c_uint, |
118 | | )); |
119 | | experimental_api!(SSL_SetResumptionTokenCallback( |
120 | | fd: *mut PRFileDesc, |
121 | | cb: SSLResumptionTokenCallback, |
122 | | arg: *mut c_void, |
123 | | )); |
124 | | |
125 | | experimental_api!(SSL_GetResumptionTokenInfo( |
126 | | token: *const u8, |
127 | | token_len: c_uint, |
128 | | info: *mut SSLResumptionTokenInfo, |
129 | | len: c_uint, |
130 | | )); |
131 | | |
132 | | experimental_api!(SSL_DestroyResumptionTokenInfo( |
133 | | info: *mut SSLResumptionTokenInfo, |
134 | | )); |
135 | | |
136 | | experimental_api!(SSL_SetCertificateCompressionAlgorithm( |
137 | | fd: *mut PRFileDesc, |
138 | | t: SSLCertificateCompressionAlgorithm, |
139 | | )); |
140 | | |
141 | | #[cfg(test)] |
142 | | #[cfg_attr(coverage_nightly, coverage(off))] |
143 | | mod tests { |
144 | | use super::{SSL_GetNumImplementedCiphers, SSL_NumImplementedCiphers}; |
145 | | |
146 | | #[test] |
147 | | fn num_ciphers() { |
148 | | assert!(unsafe { SSL_NumImplementedCiphers } > 0); |
149 | | assert!(unsafe { SSL_GetNumImplementedCiphers() } > 0); |
150 | | assert_eq!(unsafe { SSL_NumImplementedCiphers }, unsafe { |
151 | | SSL_GetNumImplementedCiphers() |
152 | | }); |
153 | | } |
154 | | } |