Skip to content

Commit

Permalink
Add SecTrustSettingsSetTrustSettings and SecCertificateAddToKeychain (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
emanuele-em authored May 20, 2023
1 parent 5f0231f commit 2b2f63e
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
1 change: 1 addition & 0 deletions security-framework-sys/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pub const errSecInvalidExtendedKeyUsage: OSStatus = -67609;
pub const errSecTrustSettingDeny: OSStatus = -67654;
pub const errSecCertificateRevoked: OSStatus = -67820;
pub const errSecNotTrusted: OSStatus = -67843;
pub const errSecInternalComponent: OSStatus = -2070;

extern "C" {
// this is available on iOS 11.3+, MacOS 10.3+
Expand Down
14 changes: 14 additions & 0 deletions security-framework/src/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use crate::base::{Error, Result};
use crate::cvt;
#[cfg(any(feature = "OSX_10_12", target_os = "ios"))]
use crate::key;
#[cfg(target_os = "macos")]
use crate::os::macos::keychain::SecKeychain;
#[cfg(any(feature = "OSX_10_12", target_os = "ios"))]
use core_foundation::base::FromVoid;
#[cfg(any(feature = "OSX_10_13", target_os = "ios"))]
Expand Down Expand Up @@ -72,6 +74,18 @@ impl SecCertificate {
}
}

/// Adds a certificate to a keychain.
#[cfg(target_os="macos")]
pub fn add_to_keychain(&self, keychain: Option<SecKeychain>) -> Result<()> {
let kch = match keychain {
Some(kch) => kch,
_ => SecKeychain::default()?,
};
cvt(unsafe {
SecCertificateAddToKeychain(self.as_CFTypeRef() as *mut _, kch.as_CFTypeRef() as *mut _)
})
}

/// Returns a human readable summary of this certificate.
#[must_use]
pub fn subject_summary(&self) -> String {
Expand Down
28 changes: 28 additions & 0 deletions security-framework/src/trust_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use core_foundation::dictionary::CFDictionary;
use core_foundation::number::CFNumber;
use core_foundation::string::CFString;

use core_foundation_sys::base::CFTypeRef;
use security_framework_sys::base::errSecNoTrustSettings;
use security_framework_sys::base::errSecSuccess;
use security_framework_sys::trust_settings::*;
Expand Down Expand Up @@ -113,6 +114,32 @@ impl TrustSettings {
Ok(TrustSettingsIter { index: 0, array })
}

///set trust settings to ""always trust this root certificate regardless of use.".
/// Sets the trust settings for the provided certificate to "always trust this root certificate
/// regardless of use."
///
/// This method configures the trust settings for the specified certificate, indicating that it should
/// always be trusted as a TLS root certificate, regardless of its usage.
///
/// If successful, the trust settings are updated for the certificate in the given domain. If the
/// certificate had no previous trust settings in the domain, new trust settings are created. If the
/// certificate had existing trust settings, they are replaced with the new settings.
///
/// It is not possible to modify per-user trust settings when not running in a GUI
/// environment, if you try it will return error `2070: errSecInternalComponent`
#[cfg(target_os="macos")]
pub fn set_trust_settings_always(&self, cert: &SecCertificate) -> Result<()> {
let domain = self.domain;
let trust_settings: CFTypeRef = ptr::null_mut();
cvt(unsafe {
SecTrustSettingsSetTrustSettings(
cert.as_CFTypeRef() as *mut _,
domain.into(),
trust_settings,
)
})
}

/// Returns the aggregate trust setting for the given certificate.
///
/// This tells you whether the certificate should be trusted as a TLS
Expand Down Expand Up @@ -275,3 +302,4 @@ mod test {
Some("The specified item could not be found in the keychain.".into()));
}
}

0 comments on commit 2b2f63e

Please sign in to comment.