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 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result21     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
22         fmt.debug_struct("SecPolicy").finish()
23     }
24 }
25 
26 impl SecPolicy {
27     /// Creates a `SecPolicy` for evaluating SSL certificate chains.
28     ///
29     /// The side which you are evaluating should be provided (i.e. pass `SslSslProtocolSide::SERVER` if
30     /// you are a client looking to validate a server's certificate chain).
create_ssl(protocol_side: SslProtocolSide, hostname: Option<&str>) -> Self31     pub fn create_ssl(protocol_side: SslProtocolSide, hostname: Option<&str>) -> Self {
32         let hostname = hostname.map(CFString::new);
33         let hostname = hostname
34             .as_ref()
35             .map(|s| s.as_concrete_TypeRef())
36             .unwrap_or(ptr::null_mut());
37         let is_server = protocol_side == SslProtocolSide::SERVER;
38         unsafe {
39             let policy = SecPolicyCreateSSL(is_server as _, hostname);
40             Self::wrap_under_create_rule(policy)
41         }
42     }
43 
44     /// Returns a policy object for the default X.509 policy.
create_x509() -> Self45     pub fn create_x509() -> Self {
46         unsafe {
47             let policy = SecPolicyCreateBasicX509();
48             Self::wrap_under_create_rule(policy)
49         }
50     }
51 }
52 
53 #[cfg(test)]
54 mod test {
55     use crate::policy::SecPolicy;
56     use crate::secure_transport::SslProtocolSide;
57 
58     #[test]
create_ssl()59     fn create_ssl() {
60         SecPolicy::create_ssl(SslProtocolSide::SERVER, Some("certifi.org"));
61     }
62 }
63