1use std::os::fd::AsRawFd;
2
3use foreign_types_shared::ForeignType;
4
5use crate::ffi::BIO_NOCLOSE;
6
7pub struct SslStream {
8 _tcp: std::net::TcpStream,
9 ssl: openssl::ssl::Ssl,
10}
11impl SslStream {
12 pub fn new(tcp: std::net::TcpStream, ssl: openssl::ssl::Ssl) -> Self {
14 let sock_bio = unsafe { openssl_sys::BIO_new_socket(tcp.as_raw_fd(), BIO_NOCLOSE) };
15 assert!(!sock_bio.is_null(), "Failed to create socket BIO");
16 unsafe {
17 openssl_sys::SSL_set_bio(ssl.as_ptr(), sock_bio, sock_bio);
18 }
19 SslStream { _tcp: tcp, ssl }
20 }
21
22 pub fn connect(&self) -> Result<(), crate::error::Error> {
24 let result = unsafe { openssl_sys::SSL_connect(self.ssl.as_ptr()) };
25 if result <= 0 {
26 Err(crate::error::Error::make(result, self.ssl()))
27 } else {
28 Ok(())
29 }
30 }
31
32 pub fn accept(&self) -> Result<(), crate::error::Error> {
33 let result = unsafe { openssl_sys::SSL_accept(self.ssl.as_ptr()) };
34 if result <= 0 {
35 Err(crate::error::Error::make(result, self.ssl()))
36 } else {
37 Ok(())
38 }
39 }
40
41 pub fn ssl(&self) -> &openssl::ssl::Ssl {
42 &self.ssl
43 }
44
45 pub fn shutdown(&self) -> Result<openssl::ssl::ShutdownResult, crate::error::Error> {
46 let result = unsafe { openssl_sys::SSL_shutdown(self.ssl.as_ptr()) };
47 match result {
48 1 => {
49 Ok(openssl::ssl::ShutdownResult::Received)
51 }
52 0 => {
53 Ok(openssl::ssl::ShutdownResult::Sent)
56 }
57 i => Err(crate::error::Error::make(i, self.ssl())),
58 }
59 }
60
61 pub fn ktls_send_enabled(&self) -> bool {
62 unsafe {
63 let wbio = openssl_sys::SSL_get_wbio(self.ssl.as_ptr());
64 crate::ffi::BIO_get_ktls_send(wbio) != 0
65 }
66 }
67
68 pub fn ktls_recv_enabled(&self) -> bool {
69 unsafe {
70 let rbio = openssl_sys::SSL_get_rbio(self.ssl.as_ptr());
71 crate::ffi::BIO_get_ktls_recv(rbio) != 0
72 }
73 }
74}
75
76impl std::io::Read for SslStream {
77 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
78 let mut bytes_read = 0;
79 unsafe {
80 let ret = openssl_sys::SSL_read_ex(
81 self.ssl.as_ptr(),
82 buf.as_mut_ptr() as *mut _,
83 buf.len(),
84 &mut bytes_read,
85 );
86 if ret < 0 {
87 Err(std::io::Error::other(crate::error::Error::make(
88 ret,
89 self.ssl(),
90 )))
91 } else {
92 Ok(bytes_read)
93 }
94 }
95 }
96}
97
98impl std::io::Write for SslStream {
99 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
100 if buf.is_empty() {
101 return Ok(0);
102 }
103
104 unsafe {
105 let len = openssl_sys::SSL_write(
106 self.ssl.as_ptr(),
107 buf.as_ptr() as *const _,
108 buf.len().try_into().unwrap(),
109 );
110 if len < 0 {
111 Err(std::io::Error::other(crate::error::Error::make(
112 len,
113 self.ssl(),
114 )))
115 } else {
116 Ok(len as usize)
117 }
118 }
119 }
120
121 fn flush(&mut self) -> std::io::Result<()> {
122 Ok(())
123 }
124}
125
126impl Drop for SslStream {
127 fn drop(&mut self) {
128 }
135}