1 //! Security Policies support.
2 use core_foundation::base::TCFType;
3 use core_foundation::string::CFString;
4 use security_framework_sys::base::SecPolicyRef;
5 use security_framework_sys::policy::*;
6 use std::fmt;
7 use std::ptr;
8 
9 use crate::secure_transport::SslProtocolSide;
10 
11 declare_TCFType! {
12     /// A type representing a certificate validation policy.
13     SecPolicy, SecPolicyRef
14 }
15 impl_TCFType!(SecPolicy, SecPolicyRef, SecPolicyGetTypeID);
16 
17 unsafe impl Sync for SecPolicy {}
18 unsafe impl Send for SecPolicy {}
19 
20 impl fmt::Debug for SecPolicy {
21     #[cold]
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result22     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
23         fmt.debug_struct("SecPolicy").finish()
24     }
25 }
26 
27 impl SecPolicy {
28     /// Creates a `SecPolicy` for evaluating SSL certificate chains.
29     ///
30     /// The side which you are evaluating should be provided (i.e. pass `SslSslProtocolSide::SERVER` if
31     /// you are a client looking to validate a server's certificate chain).
create_ssl(protocol_side: SslProtocolSide, hostname: Option<&str>) -> Self32     pub fn create_ssl(protocol_side: SslProtocolSide, hostname: Option<&str>) -> Self {
33         let hostname = hostname.map(CFString::new);
34         let hostname = hostname
35             .as_ref()
36             .map(|s| s.as_concrete_TypeRef())
37             .unwrap_or(ptr::null_mut());
38         let is_server = protocol_side == SslProtocolSide::SERVER;
39         unsafe {
40             let policy = SecPolicyCreateSSL(is_server as _, hostname);
41             Self::wrap_under_create_rule(policy)
42         }
43     }
44 
45     /// Returns a policy object for the default X.509 policy.
create_x509() -> Self46     pub fn create_x509() -> Self {
47         unsafe {
48             let policy = SecPolicyCreateBasicX509();
49             Self::wrap_under_create_rule(policy)
50         }
51     }
52 }
53 
54 #[cfg(test)]
55 mod test {
56     use crate::policy::SecPolicy;
57     use crate::secure_transport::SslProtocolSide;
58 
59     #[test]
create_ssl()60     fn create_ssl() {
61         SecPolicy::create_ssl(SslProtocolSide::SERVER, Some("certifi.org"));
62     }
63 }
64