use std::path::Path;
use std::process::Command;
use crate::error::ProxyError;
#[cfg(target_os = "macos")]
pub(super) fn add_trusted_cert(cert_path: &Path) -> Result<(), ProxyError> {
let cert_str = cert_path
.to_str()
.ok_or_else(|| ProxyError::Keychain("cert path is not valid UTF-8".into()))?;
let output = Command::new("security")
.args([
"add-trusted-cert",
"-d",
"-r",
"trustRoot",
"-k",
"/Library/Keychains/System.keychain",
cert_str,
])
.output()
.map_err(|e| ProxyError::Keychain(format!("failed to run security CLI: {e}")))?;
if output.status.success() {
Ok(())
} else {
Err(ProxyError::Keychain(
String::from_utf8_lossy(&output.stderr).trim().to_string(),
))
}
}
#[cfg(target_os = "macos")]
pub(super) fn remove_trusted_cert(cert_path: &Path) -> Result<(), ProxyError> {
let cert_str = cert_path
.to_str()
.ok_or_else(|| ProxyError::Keychain("cert path is not valid UTF-8".into()))?;
let output = Command::new("security")
.args(["remove-trusted-cert", "-d", cert_str])
.output()
.map_err(|e| ProxyError::Keychain(format!("failed to run security CLI: {e}")))?;
if output.status.success() {
Ok(())
} else {
Err(ProxyError::Keychain(
String::from_utf8_lossy(&output.stderr).trim().to_string(),
))
}
}
#[cfg(target_os = "macos")]
pub(super) fn is_cert_trusted(subject: &str) -> Result<bool, ProxyError> {
let output = Command::new("security")
.args([
"find-certificate",
"-c",
subject,
"-a",
"/Library/Keychains/System.keychain",
])
.output()
.map_err(|e| ProxyError::Keychain(format!("failed to run security CLI: {e}")))?;
Ok(output.status.success())
}