1#[cfg(any(feature = "OSX_10_9", target_os = "ios"))]
3use core_foundation::base::CFOptionFlags;
4use core_foundation::base::TCFType;
5use core_foundation::string::CFString;
6#[cfg(any(feature = "OSX_10_9", target_os = "ios"))]
7use apple_security_sys::base::errSecParam;
8use apple_security_sys::base::SecPolicyRef;
9use apple_security_sys::policy::*;
10use std::fmt;
11use std::ptr;
12
13use crate::secure_transport::SslProtocolSide;
14#[cfg(any(feature = "OSX_10_9", target_os = "ios"))]
15use crate::Error;
16
17declare_TCFType! {
18 SecPolicy, SecPolicyRef
20}
21impl_TCFType!(SecPolicy, SecPolicyRef, SecPolicyGetTypeID);
22
23unsafe impl Sync for SecPolicy {}
24unsafe impl Send for SecPolicy {}
25
26impl fmt::Debug for SecPolicy {
27 #[cold]
28 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
29 fmt.debug_struct("SecPolicy").finish()
30 }
31}
32
33#[cfg(any(feature = "OSX_10_9", target_os = "ios"))]
34bitflags::bitflags! {
35 pub struct RevocationPolicy: CFOptionFlags {
37 const OCSP_METHOD = kSecRevocationOCSPMethod;
39 const CRL_METHOD = kSecRevocationCRLMethod;
41 const PREFER_CRL = kSecRevocationPreferCRL;
43 const REQUIRE_POSITIVE_RESPONSE = kSecRevocationRequirePositiveResponse;
45 const NETWORK_ACCESS_DISABLED = kSecRevocationNetworkAccessDisabled;
47 const USE_ANY_METHOD_AVAILABLE = kSecRevocationUseAnyAvailableMethod;
49 }
50}
51
52impl SecPolicy {
53 pub fn create_ssl(protocol_side: SslProtocolSide, hostname: Option<&str>) -> Self {
58 let hostname = hostname.map(CFString::new);
59 let hostname = hostname
60 .as_ref()
61 .map(|s| s.as_concrete_TypeRef())
62 .unwrap_or(ptr::null_mut());
63 let is_server = protocol_side == SslProtocolSide::SERVER;
64 unsafe {
65 let policy = SecPolicyCreateSSL(is_server as _, hostname);
66 Self::wrap_under_create_rule(policy)
67 }
68 }
69
70 #[cfg(any(feature = "OSX_10_9", target_os = "ios"))]
71 pub fn create_revocation(options: RevocationPolicy) -> crate::Result<Self> {
76 let policy = unsafe { SecPolicyCreateRevocation(options.bits()) };
77
78 if policy.is_null() {
79 Err(Error::from_code(errSecParam))
80 } else {
81 Ok(unsafe { Self::wrap_under_create_rule(policy) })
82 }
83 }
84
85 #[must_use]
87 pub fn create_x509() -> Self {
88 unsafe {
89 let policy = SecPolicyCreateBasicX509();
90 Self::wrap_under_create_rule(policy)
91 }
92 }
93}
94
95#[cfg(test)]
96mod test {
97 use crate::policy::SecPolicy;
98 use crate::secure_transport::SslProtocolSide;
99
100 #[test]
101 fn create_ssl() {
102 SecPolicy::create_ssl(SslProtocolSide::SERVER, Some("certifi.org"));
103 }
104}