//! RPC handlers for the FIPS mesh transport subsystem. //! //! Surface is deliberately thin: a read-only `fips.status`, a user-gated //! `fips.check-update`, a stubbed `fips.apply-update`, and a //! `fips.install` that (re-)materialises the daemon config + key and //! activates the service. All writes go through `sudo` helpers in //! `crate::fips`. use super::RpcHandler; use crate::fips; use anyhow::Result; impl RpcHandler { pub(super) async fn handle_fips_status(&self) -> Result { let identity_dir = fips::identity_dir_from(&self.config.data_dir); let status = fips::FipsStatus::query(&identity_dir).await; Ok(serde_json::to_value(status)?) } pub(super) async fn handle_fips_check_update(&self) -> Result { let check = fips::update::check().await?; Ok(serde_json::to_value(check)?) } pub(super) async fn handle_fips_apply_update(&self) -> Result { fips::update::apply().await?; Ok(serde_json::json!({ "applied": true })) } /// Install config + key into /etc/fips and activate the service. /// Intended to be called: /// - once by the seed-onboarding flow, right after the FIPS key /// is written to /data/identity/fips_key, and /// - on user demand from the dashboard if something drifted. pub(super) async fn handle_fips_install(&self) -> Result { let identity_dir = fips::identity_dir_from(&self.config.data_dir); fips::config::install(&identity_dir).await?; fips::service::activate(fips::SERVICE_UNIT).await?; let status = fips::FipsStatus::query(&identity_dir).await; Ok(serde_json::to_value(status)?) } pub(super) async fn handle_fips_restart(&self) -> Result { fips::service::restart(fips::SERVICE_UNIT).await?; Ok(serde_json::json!({ "restarted": true })) } }