Skip to main content

security/
secure_transport.rs

1use serde::Deserialize;
2
3use crate::bridge;
4use crate::error::Result;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7/// Mirrors Secure Transport protocol-version selectors.
8pub enum ProtocolVersion {
9    /// Mirrors a Secure Transport protocol-version constant.
10    Ssl2,
11    /// Mirrors a Secure Transport protocol-version constant.
12    Ssl3,
13    /// Mirrors a Secure Transport protocol-version constant.
14    Tls1_0,
15    /// Mirrors a Secure Transport protocol-version constant.
16    Tls1_1,
17    /// Mirrors a Secure Transport protocol-version constant.
18    Tls1_2,
19    /// Mirrors a Secure Transport protocol-version constant.
20    Dtls1_0,
21    /// Mirrors a Secure Transport protocol-version constant.
22    Tls1_3,
23}
24
25impl ProtocolVersion {
26    /// Mirrors the protocol name used by Secure Transport configuration helpers.
27    pub const fn as_str(self) -> &'static str {
28        match self {
29            Self::Ssl2 => "ssl2",
30            Self::Ssl3 => "ssl3",
31            Self::Tls1_0 => "tls1.0",
32            Self::Tls1_1 => "tls1.1",
33            Self::Tls1_2 => "tls1.2",
34            Self::Dtls1_0 => "dtls1.0",
35            Self::Tls1_3 => "tls1.3",
36        }
37    }
38}
39
40#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
41/// Mirrors state queried from a Secure Transport session.
42pub struct SecureTransportState {
43    /// Mirrors a field returned by Secure Transport session queries.
44    pub side: String,
45    #[serde(rename = "sessionState")]
46    /// Mirrors a field returned by Secure Transport session queries.
47    pub session_state: String,
48    #[serde(rename = "minimumProtocol")]
49    /// Mirrors a field returned by Secure Transport session queries.
50    pub minimum_protocol: String,
51    #[serde(rename = "maximumProtocol")]
52    /// Mirrors a field returned by Secure Transport session queries.
53    pub maximum_protocol: String,
54}
55
56#[derive(Debug)]
57/// Wraps a Secure Transport `SSLContextRef`.
58pub struct SecureTransportContext {
59    handle: bridge::Handle,
60}
61
62impl SecureTransportContext {
63    /// Wraps the corresponding Secure Transport `SSLContextRef` operation.
64    pub fn client() -> Result<Self> {
65        create_context(bridge::security_secure_transport_create_client)
66    }
67
68    /// Wraps the corresponding Secure Transport `SSLContextRef` operation.
69    pub fn server() -> Result<Self> {
70        create_context(bridge::security_secure_transport_create_server)
71    }
72
73    /// Wraps the corresponding Secure Transport `SSLContextRef` operation.
74    pub fn set_protocol_min(&mut self, protocol: ProtocolVersion) -> Result<()> {
75        let protocol = bridge::cstring(protocol.as_str())?;
76        let mut error = std::ptr::null_mut();
77        let status = unsafe {
78            bridge::security_secure_transport_set_protocol_min(
79                self.handle.as_ptr(),
80                protocol.as_ptr(),
81                &mut error,
82            )
83        };
84        bridge::status_result("security_secure_transport_set_protocol_min", status, error)
85    }
86
87    /// Wraps the corresponding Secure Transport `SSLContextRef` operation.
88    pub fn set_protocol_max(&mut self, protocol: ProtocolVersion) -> Result<()> {
89        let protocol = bridge::cstring(protocol.as_str())?;
90        let mut error = std::ptr::null_mut();
91        let status = unsafe {
92            bridge::security_secure_transport_set_protocol_max(
93                self.handle.as_ptr(),
94                protocol.as_ptr(),
95                &mut error,
96            )
97        };
98        bridge::status_result("security_secure_transport_set_protocol_max", status, error)
99    }
100
101    /// Wraps the corresponding Secure Transport `SSLContextRef` operation.
102    pub fn state(&self) -> Result<SecureTransportState> {
103        let mut status = 0;
104        let mut error = std::ptr::null_mut();
105        let raw = unsafe {
106            bridge::security_secure_transport_copy_state(
107                self.handle.as_ptr(),
108                &mut status,
109                &mut error,
110            )
111        };
112        bridge::required_json("security_secure_transport_copy_state", raw, status, error)
113    }
114}
115
116fn create_context(
117    create: unsafe extern "C" fn(*mut i32, *mut *mut std::ffi::c_void) -> *mut std::ffi::c_void,
118) -> Result<SecureTransportContext> {
119    let mut status = 0;
120    let mut error = std::ptr::null_mut();
121    let raw = unsafe { create(&mut status, &mut error) };
122    bridge::required_handle("security_secure_transport_create", raw, status, error)
123        .map(|handle| SecureTransportContext { handle })
124}