Search code examples
macosrustsecurity-framework

Using `SecTrustSettingsSetTrustSettings` binding in Rust cause `errSecInternalComponent`


I'm writing an update to Security framework crate that is a bindings to apple Security.framework.

I added some functionalities as SecCertificateAddToKeychain without any problem but with SecTrustSettingsSetTrustSettings the result is always -2070 errSecInternalComponent .

This is the full implementation:

use crate::base::SecCertificateRef;
use core_foundation_sys::array::CFArrayRef;
use core_foundation_sys::base::CFTypeRef;
use core_foundation_sys::base::OSStatus;

pub type SecTrustSettingsDomain = u32;

pub const kSecTrustSettingsDomainUser: SecTrustSettingsDomain = 0;
pub const kSecTrustSettingsDomainAdmin: SecTrustSettingsDomain = 1;
pub const kSecTrustSettingsDomainSystem: SecTrustSettingsDomain = 2;

pub type SecTrustSettingsResult = u32;

pub const kSecTrustSettingsResultInvalid: SecTrustSettingsResult = 0;
pub const kSecTrustSettingsResultTrustRoot: SecTrustSettingsResult = 1;
pub const kSecTrustSettingsResultTrustAsRoot: SecTrustSettingsResult = 2;
pub const kSecTrustSettingsResultDeny: SecTrustSettingsResult = 3;
pub const kSecTrustSettingsResultUnspecified: SecTrustSettingsResult = 4;

extern "C" {
    pub fn SecTrustSettingsCopyCertificates(
        domain: SecTrustSettingsDomain,
        certsOut: *mut CFArrayRef,
    ) -> OSStatus;
    pub fn SecTrustSettingsCopyTrustSettings(
        certificateRef: SecCertificateRef,
        domain: SecTrustSettingsDomain,
        trustSettings: *mut CFArrayRef,
    ) -> OSStatus;
    pub fn SecTrustSettingsSetTrustSettings(
        certificateRef: SecCertificateRef,
        domain: SecTrustSettingsDomain,
        trustSettingsDictOrArray: CFTypeRef,
    ) -> OSStatus;
}

And this is the way I call the function:

pub fn set_trust_settings(cert: &SecCertificate) -> Result<()>{
    let domain = kSecTrustSettingsDomainAdmin;
    let trust_settings: CFTypeRef = ptr::null_mut();
        cvt(unsafe {
            SecTrustSettingsSetTrustSettings(
                cert.as_CFTypeRef() as *mut _,
                domain,
                trust_settings,
            )
    })
}

Notes

  • sudo security add-trusted-certs [..] works without any problem
  • I want to add this function to allow users to add my app certificate programmatically without to add it each time manually, I want to implement the remove certificate too, to remove them after the session
  • I'm on macos 13 with M2
  • sudo security authorizationdb write com.apple.trust-settings.admin allow doesn't work

Solution

  • In the official documentation, there is a line that specifies that this function only works when called in a GUI environment.

    My solution was that to create a minimal macos bundle app to be called when needed with:

    tokio::process::Command::new("open").arg("./path/app_name.app")