1use super::*;
2
3use libc::c_long;
4use libc::c_uchar;
5
6#[allow(non_camel_case_types)]
7#[repr(transparent)]
8struct OPENSSL_STACK {
9 _unused: c_void,
10}
11
12#[allow(non_camel_case_types)]
13#[repr(transparent)]
14struct X509 {
15 _unused: c_void,
16}
17
18#[repr(C)]
19#[allow(non_camel_case_types)]
20pub(super) struct SSL_QUIC_METHOD {
21 set_encryption_secrets: Option<
22 extern "C" fn(
23 ssl: *mut SSL,
24 level: crypto::Level,
25 read_secret: *const u8,
26 write_secret: *const u8,
27 secret_len: usize,
28 ) -> c_int,
29 >,
30
31 add_handshake_data: Option<
32 unsafe extern "C" fn(
33 ssl: *mut SSL,
34 level: crypto::Level,
35 data: *const u8,
36 len: usize,
37 ) -> c_int,
38 >,
39
40 flush_flight: Option<extern "C" fn(ssl: *mut SSL) -> c_int>,
41
42 send_alert: Option<
43 extern "C" fn(ssl: *mut SSL, level: crypto::Level, alert: u8) -> c_int,
44 >,
45}
46
47pub(super) static QUICHE_STREAM_METHOD: SSL_QUIC_METHOD = SSL_QUIC_METHOD {
48 set_encryption_secrets: Some(set_encryption_secrets),
49 add_handshake_data: Some(add_handshake_data),
50 flush_flight: Some(flush_flight),
51 send_alert: Some(send_alert),
52};
53
54impl Context {
55 pub fn set_early_data_enabled(&mut self, _enabled: bool) {
56 }
58}
59
60impl Handshake {
61 pub fn set_quic_early_data_context(&mut self, _context: &[u8]) -> Result<()> {
62 map_result(1)
64 }
65
66 pub fn curve(&self) -> Option<String> {
67 let curve = unsafe {
68 let curve_id = SSL_get_negotiated_group(self.as_ptr());
69 if curve_id == 0 {
70 return None;
71 }
72
73 let curve_name = SSL_group_to_name(self.as_ptr(), curve_id);
74
75 match ffi::CStr::from_ptr(curve_name).to_str() {
76 Ok(v) => v,
77
78 Err(_) => return None,
79 }
80 };
81
82 Some(curve.to_string())
83 }
84
85 pub fn peer_cert_chain(&self) -> Option<Vec<&[u8]>> {
86 let cert_chain = unsafe {
89 let chain =
90 map_result_ptr(SSL_get_peer_cert_chain(self.as_ptr())).ok()?;
91
92 let num = sk_X509_num(chain);
93 if num == 0 {
94 return None;
95 }
96
97 let mut cert_chain = vec![];
98 for i in 0..num {
99 let cert =
100 map_result_ptr(sk_X509_value(chain, i) as *mut X509).ok()?;
101
102 let mut out: *mut u8 = ptr::null_mut();
103 let len = i2d_X509(cert, &mut out);
104 if len < 0 {
105 return None;
106 }
107 cert_chain.push(slice::from_raw_parts(out, len as usize));
108 }
109
110 cert_chain
111 };
112
113 Some(cert_chain)
114 }
115
116 pub fn peer_cert(&self) -> Option<&[u8]> {
117 let peer_cert = unsafe {
118 let cert =
125 map_result_ptr(SSL_get0_peer_certificate(self.as_ptr())).ok()?;
126 let mut out: *mut u8 = ptr::null_mut();
127 let len = i2d_X509(cert, &mut out);
128 if len < 0 {
129 return None;
130 }
131 slice::from_raw_parts(out, len as usize)
132 };
133 Some(peer_cert)
134 }
135
136 #[cfg(test)]
137 #[allow(dead_code)] pub fn set_failing_private_key_method(&mut self) {}
139
140 pub fn is_in_early_data(&self) -> bool {
141 false
142 }
143
144 pub fn early_data_reason(&self) -> u32 {
145 0
146 }
147
148 pub fn set_session(&mut self, session: &[u8]) -> Result<()> {
149 unsafe {
150 let ctx = SSL_get_SSL_CTX(self.as_ptr());
151
152 if ctx.is_null() {
153 return Err(Error::TlsFail);
154 }
155
156 let session = d2i_SSL_SESSION(
157 ptr::null_mut(),
158 &mut session.as_ptr(),
159 session.len() as c_long,
160 );
161
162 if session.is_null() {
163 return Err(Error::TlsFail);
164 }
165
166 let rc = SSL_set_session(self.as_mut_ptr(), session);
167 SSL_SESSION_free(session);
168
169 map_result(rc)
170 }
171 }
172
173 pub fn reset_early_data_reject(&mut self) {
174 }
176
177 pub fn sigalg(&self) -> Option<String> {
178 let sigalg = "";
179
180 Some(sigalg.to_string())
181 }
182}
183
184extern "C" fn set_encryption_secrets(
185 ssl: *mut SSL, level: crypto::Level, read_secret: *const u8,
186 write_secret: *const u8, secret_len: usize,
187) -> c_int {
188 let cipher = map_result_ptr(unsafe { SSL_get_current_cipher(ssl) });
189 let _write_ret =
190 set_write_secret(ssl, level, cipher.unwrap(), write_secret, secret_len);
191 let _read_ret =
192 set_read_secret(ssl, level, cipher.unwrap(), read_secret, secret_len);
193
194 1
195}
196
197#[allow(non_snake_case)]
203unsafe fn sk_X509_num(stack: *const STACK_OF) -> usize {
204 OPENSSL_sk_num(stack as *const OPENSSL_STACK)
205}
206
207#[allow(non_snake_case)]
208unsafe fn sk_X509_value(stack: *const STACK_OF, idx: usize) -> *mut c_void {
209 OPENSSL_sk_value(stack as *const OPENSSL_STACK, idx)
210}
211
212#[allow(non_snake_case)]
213pub(super) unsafe fn SSL_CTX_set_session_cache_mode(
214 ctx: *mut SSL_CTX, mode: c_int,
215) -> c_int {
216 const SSL_CTRL_SET_SESS_CACHE_MODE: c_int = 44;
217
218 SSL_CTX_ctrl(
219 ctx,
220 SSL_CTRL_SET_SESS_CACHE_MODE,
221 mode as c_long,
222 ptr::null_mut(),
223 ) as c_int
224}
225
226#[allow(non_snake_case)]
227pub(super) unsafe fn SSL_CTX_set_tlsext_ticket_keys(
228 ctx: *mut SSL_CTX, key: *const u8, key_len: usize,
229) -> c_int {
230 const SSL_CTRL_SET_TLSEXT_TICKET_KEYS: c_int = 59;
231
232 SSL_CTX_ctrl(
233 ctx,
234 SSL_CTRL_SET_TLSEXT_TICKET_KEYS,
235 key_len as c_long,
236 key as *mut c_void,
237 ) as c_int
238}
239
240#[allow(non_snake_case)]
241pub(super) unsafe fn SSL_set_min_proto_version(
242 s: *mut SSL, version: u16,
243) -> c_int {
244 const SSL_CTRL_SET_MIN_PROTO_VERSION: c_int = 123;
245
246 SSL_ctrl(
247 s,
248 SSL_CTRL_SET_MIN_PROTO_VERSION,
249 version as c_long,
250 ptr::null_mut(),
251 ) as c_int
252}
253
254#[allow(non_snake_case)]
255pub(super) unsafe fn SSL_set_max_proto_version(
256 s: *mut SSL, version: u16,
257) -> c_int {
258 const SSL_CTRL_SET_MAX_PROTO_VERSION: c_int = 124;
259
260 SSL_ctrl(
261 s,
262 SSL_CTRL_SET_MAX_PROTO_VERSION,
263 version as c_long,
264 ptr::null_mut(),
265 ) as c_int
266}
267
268#[allow(non_snake_case)]
269pub(super) unsafe fn SSL_set_tlsext_host_name(
270 s: *mut SSL, name: *const c_char,
271) -> c_int {
272 const SSL_CTRL_SET_TLSEXT_HOSTNAME: c_int = 55;
273
274 #[allow(non_upper_case_globals)]
275 const TLSEXT_NAMETYPE_host_name: c_long = 0;
276
277 SSL_ctrl(
278 s,
279 SSL_CTRL_SET_TLSEXT_HOSTNAME,
280 TLSEXT_NAMETYPE_host_name,
281 name as *mut c_void,
282 ) as c_int
283}
284
285#[allow(non_snake_case)]
286pub(super) unsafe fn SSL_get_ex_new_index(
287 argl: c_long, argp: *const c_void, newf: *const c_void, dupf: *const c_void,
288 freef: *const c_void,
289) -> c_int {
290 const CRYPTO_EX_INDEX_SSL: c_int = 0;
291
292 CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, newf, dupf, freef)
293}
294
295#[allow(non_snake_case)]
296unsafe fn SSL_get_negotiated_group(ssl: *const SSL) -> c_int {
297 const SSL_CTRL_GET_NEGOTIATED_GROUP: c_int = 134;
298 SSL_ctrl(
299 ssl,
300 SSL_CTRL_GET_NEGOTIATED_GROUP,
301 0 as c_long,
302 ptr::null_mut(),
303 ) as c_int
304}
305
306pub(super) fn get_session_bytes(session: *mut SSL_SESSION) -> Result<Vec<u8>> {
307 let session_bytes = unsafe {
308 let out_len = i2d_SSL_SESSION(session, ptr::null_mut());
310 if out_len == 0 {
311 return Err(Error::TlsFail);
312 }
313 let mut out: Vec<c_uchar> = Vec::with_capacity(out_len as usize);
314
315 let out_len = i2d_SSL_SESSION(session, &mut out.as_mut_ptr());
316 let session_bytes =
317 slice::from_raw_parts(out.as_mut_ptr(), out_len as usize).to_vec();
318 session_bytes
319 };
320
321 Ok(session_bytes)
322}
323pub(super) const TLS_ERROR: c_int = 2;
324
325extern "C" {
326
327 fn SSL_CTX_ctrl(
328 ctx: *mut SSL_CTX, cmd: c_int, larg: c_long, parg: *mut c_void,
329 ) -> c_long;
330
331 fn SSL_get_peer_cert_chain(ssl: *const SSL) -> *mut STACK_OF;
332
333 fn SSL_get0_peer_certificate(ssl: *const SSL) -> *mut X509;
334
335 fn SSL_ctrl(
336 ssl: *const SSL, cmd: c_int, larg: c_long, parg: *mut c_void,
337 ) -> c_long;
338
339 fn i2d_X509(px: *const X509, out: *mut *mut c_uchar) -> c_int;
340
341 fn OPENSSL_sk_num(stack: *const OPENSSL_STACK) -> usize;
342
343 fn OPENSSL_sk_value(stack: *const OPENSSL_STACK, idx: usize) -> *mut c_void;
344
345 fn CRYPTO_get_ex_new_index(
348 class_index: c_int, argl: c_long, argp: *const c_void,
349 new_func: *const c_void, dup_func: *const c_void,
350 free_func: *const c_void,
351 ) -> c_int;
352
353 fn d2i_SSL_SESSION(
354 a: *mut *mut SSL_SESSION, pp: *mut *const c_uchar, len: c_long,
355 ) -> *mut SSL_SESSION;
356
357 pub(super) fn i2d_SSL_SESSION(
358 in_: *mut SSL_SESSION, pp: *mut *mut c_uchar,
359 ) -> c_int;
360
361 fn SSL_group_to_name(ssl: *const SSL, id: c_int) -> *const c_char;
362}