security_framework/
policy.rs1use core_foundation::{declare_TCFType, impl_TCFType};
3use core_foundation::base::{CFOptionFlags, TCFType};
4use core_foundation::string::CFString;
5use security_framework_sys::base::{errSecParam, SecPolicyRef};
6use security_framework_sys::policy::*;
7use std::fmt;
8use std::ptr;
9
10use crate::secure_transport::SslProtocolSide;
11use crate::Error;
12
13declare_TCFType! {
14 SecPolicy, SecPolicyRef
16}
17impl_TCFType!(SecPolicy, SecPolicyRef, SecPolicyGetTypeID);
18
19unsafe impl Sync for SecPolicy {}
20unsafe impl Send for SecPolicy {}
21
22impl fmt::Debug for SecPolicy {
23 #[cold]
24 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
25 fmt.debug_struct("SecPolicy").finish()
26 }
27}
28
29bitflags::bitflags! {
30 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
32 pub struct RevocationPolicy: CFOptionFlags {
33 const OCSP_METHOD = kSecRevocationOCSPMethod;
35 const CRL_METHOD = kSecRevocationCRLMethod;
37 const PREFER_CRL = kSecRevocationPreferCRL;
39 const REQUIRE_POSITIVE_RESPONSE = kSecRevocationRequirePositiveResponse;
41 const NETWORK_ACCESS_DISABLED = kSecRevocationNetworkAccessDisabled;
43 const USE_ANY_METHOD_AVAILABLE = kSecRevocationUseAnyAvailableMethod;
45 }
46}
47
48impl SecPolicy {
49 pub fn create_ssl(protocol_side: SslProtocolSide, hostname: Option<&str>) -> Self {
54 let hostname = hostname.map(CFString::new);
55 let hostname = hostname
56 .as_ref()
57 .map(|s| s.as_concrete_TypeRef())
58 .unwrap_or(ptr::null_mut());
59 let is_server = protocol_side == SslProtocolSide::SERVER;
60 unsafe {
61 let policy = SecPolicyCreateSSL(is_server.into(), hostname);
62 Self::wrap_under_create_rule(policy)
63 }
64 }
65
66 pub fn create_revocation(options: RevocationPolicy) -> crate::Result<Self> {
71 let policy = unsafe { SecPolicyCreateRevocation(options.bits()) };
72
73 if policy.is_null() {
74 Err(Error::from_code(errSecParam))
75 } else {
76 Ok(unsafe { Self::wrap_under_create_rule(policy) })
77 }
78 }
79
80 #[must_use]
82 pub fn create_x509() -> Self {
83 unsafe {
84 let policy = SecPolicyCreateBasicX509();
85 Self::wrap_under_create_rule(policy)
86 }
87 }
88}
89
90#[cfg(test)]
91mod test {
92 use crate::policy::SecPolicy;
93 use crate::secure_transport::SslProtocolSide;
94
95 #[test]
96 fn create_ssl() {
97 SecPolicy::create_ssl(SslProtocolSide::SERVER, Some("certifi.org"));
98 }
99}