security/certificate/
mod.rs1use crate::error::{Result, SecurityError};
4use crate::ffi;
5use crate::private::{cf_data, cf_data_to_vec, cf_string_to_string, checked_cf, OwnedCf};
6
7pub struct PublicKey {
9 raw: ffi::SecKeyRef,
10}
11
12impl PublicKey {
13 #[must_use]
15 pub const fn as_raw(&self) -> ffi::SecKeyRef {
16 self.raw
17 }
18}
19
20impl Drop for PublicKey {
21 fn drop(&mut self) {
22 if !self.raw.is_null() {
23 unsafe { ffi::CFRelease(self.raw.cast()) };
24 }
25 }
26}
27
28impl core::fmt::Debug for PublicKey {
29 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
30 f.debug_struct("PublicKey").field("raw", &self.raw).finish()
31 }
32}
33
34pub struct Certificate {
36 raw: ffi::SecCertificateRef,
37}
38
39impl Certificate {
40 pub fn from_der(der: &[u8]) -> Result<Self> {
46 let der = cf_data(der)?;
47 let raw =
48 unsafe { ffi::SecCertificateCreateWithData(ffi::kCFAllocatorDefault, der.as_data()) };
49 if raw.is_null() {
50 return Err(SecurityError::InvalidArgument(
51 "invalid DER-encoded X.509 certificate".to_owned(),
52 ));
53 }
54 Ok(Self { raw })
55 }
56
57 #[must_use]
59 pub const fn as_raw(&self) -> ffi::SecCertificateRef {
60 self.raw
61 }
62
63 #[must_use]
65 pub fn subject_summary(&self) -> Option<String> {
66 let raw = unsafe { ffi::SecCertificateCopySubjectSummary(self.raw) };
67 if raw.is_null() {
68 return None;
69 }
70 let owned = OwnedCf::new(raw.cast());
71 cf_string_to_string(owned.as_string())
72 }
73
74 pub fn der_data(&self) -> Result<Vec<u8>> {
80 let raw = unsafe { ffi::SecCertificateCopyData(self.raw) };
81 let data = checked_cf(raw.cast(), "SecCertificateCopyData")?;
82 Ok(cf_data_to_vec(data.as_data()))
83 }
84
85 pub fn public_key(&self) -> Result<PublicKey> {
91 let raw = unsafe { ffi::SecCertificateCopyKey(self.raw) };
92 if raw.is_null() {
93 return Err(SecurityError::CoreFoundation(apple_cf::CFError::new(
94 "SecCertificateCopyKey",
95 )));
96 }
97 Ok(PublicKey { raw })
98 }
99}
100
101impl Drop for Certificate {
102 fn drop(&mut self) {
103 if !self.raw.is_null() {
104 unsafe { ffi::CFRelease(self.raw.cast()) };
105 }
106 }
107}
108
109impl core::fmt::Debug for Certificate {
110 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
111 f.debug_struct("Certificate")
112 .field("subject_summary", &self.subject_summary())
113 .finish()
114 }
115}