use std::path::PathBuf;
use std::time::Duration;
use crate::internal::app_storage::StorageConfig;
pub use crate::internal::app_storage::WindowsSoftwareFallback;
use crate::types::AccessPolicy;
#[derive(Debug, Clone, Default)]
pub enum PlatformConfig {
#[default]
Default,
MacOs(MacOsConfig),
Windows(WindowsConfig),
Linux(LinuxConfig),
}
#[derive(Debug, Clone)]
pub struct MacOsConfig {
pub wrapping_key_user_presence: bool,
pub wrapping_key_cache_ttl: Duration,
pub keychain_access_group: Option<String>,
pub extra_bridge_paths: Vec<String>,
}
impl Default for MacOsConfig {
fn default() -> Self {
Self {
wrapping_key_user_presence: false,
wrapping_key_cache_ttl: Duration::ZERO,
keychain_access_group: None,
extra_bridge_paths: Vec::new(),
}
}
}
#[derive(Debug, Clone)]
pub struct WindowsConfig {
pub prefer_windows_hello_ux: bool,
pub software_fallback: WindowsSoftwareFallback,
pub dpapi_app_key: Option<[u8; 32]>,
}
impl Default for WindowsConfig {
fn default() -> Self {
Self {
prefer_windows_hello_ux: false,
software_fallback: WindowsSoftwareFallback::Disabled,
dpapi_app_key: None,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct LinuxConfig {
pub force_keyring: bool,
pub extra_bridge_paths: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct EnclaveConfig {
pub app_name: String,
pub default_key_label: String,
pub access_policy: Option<AccessPolicy>,
pub keys_dir: Option<PathBuf>,
pub platform: PlatformConfig,
}
impl EnclaveConfig {
pub fn new(app_name: impl Into<String>, default_key_label: impl Into<String>) -> Self {
Self {
app_name: app_name.into(),
default_key_label: default_key_label.into(),
access_policy: None,
keys_dir: None,
platform: PlatformConfig::Default,
}
}
pub fn effective_app_name(&self) -> String {
crate::internal::core::signing::ensure_safe_app_name(&self.app_name)
}
pub fn resolved_access_policy(&self) -> AccessPolicy {
self.access_policy.unwrap_or_else(|| {
if crate::internal::core::signing::is_binary_signed() {
AccessPolicy::None
} else {
AccessPolicy::Any
}
})
}
pub(crate) fn to_storage_config(&self) -> StorageConfig {
let (
wrapping_key_user_presence,
wrapping_key_cache_ttl,
keychain_access_group,
extra_bridge_paths,
force_keyring,
prefer_windows_hello_ux,
windows_software_fallback,
dpapi_app_key,
) = match &self.platform {
PlatformConfig::MacOs(m) => (
m.wrapping_key_user_presence,
m.wrapping_key_cache_ttl,
m.keychain_access_group.clone(),
m.extra_bridge_paths.clone(),
false,
false,
WindowsSoftwareFallback::Disabled,
None,
),
PlatformConfig::Windows(w) => (
false,
Duration::ZERO,
None,
Vec::new(),
false,
w.prefer_windows_hello_ux,
w.software_fallback,
w.dpapi_app_key,
),
PlatformConfig::Linux(l) => (
false,
Duration::ZERO,
None,
l.extra_bridge_paths.clone(),
l.force_keyring,
false,
WindowsSoftwareFallback::Disabled,
None,
),
PlatformConfig::Default => (
false,
Duration::ZERO,
None,
Vec::new(),
false,
false,
WindowsSoftwareFallback::Disabled,
None,
),
};
StorageConfig {
app_name: self.effective_app_name(),
key_label: self.default_key_label.clone(),
access_policy: self.resolved_access_policy(),
extra_bridge_paths,
keys_dir: self.keys_dir.clone(),
force_keyring,
wrapping_key_user_presence,
wrapping_key_cache_ttl,
keychain_access_group,
prefer_windows_hello_ux,
windows_software_fallback,
dpapi_app_key,
}
}
}