diff --git a/keep-desktop/src/nostrconnect.rs b/keep-desktop/src/nostrconnect.rs index 18924de8..ca3fe995 100644 --- a/keep-desktop/src/nostrconnect.rs +++ b/keep-desktop/src/nostrconnect.rs @@ -87,9 +87,28 @@ impl App { let setup_arc = Arc::new(Mutex::new(None)); self.bunker_pending_setup = Some(setup_arc.clone()); let proxy = self.proxy_addr(); + let cert_pins = self.certificate_pins.clone(); + let keep_path = self.keep_path.clone(); + let require_pinned = self.settings.strict_cert_pinning; Task::perform( async move { + // Enforce/establish SPKI pins before starting the bunker against + // these relays. The relay list comes from the (attacker-influenceable) + // nostrconnect request, so this fails closed on a corrupt pin store + // or a pin mismatch, and records TOFU pins otherwise, mirroring the + // interactive bunker-start path in bunker_service.rs. + // Propagate the `ConnectionError` unchanged (via `?`) so a + // `PinMismatch` keeps its structured variant and reaches the + // dedicated cert-failure UI, matching the interactive path. + crate::frost::verify_relay_certificates( + &valid_relays, + &cert_pins, + &keep_path, + require_pinned, + ) + .await?; + let keyring = tokio::task::spawn_blocking(move || extract_keyring(&keep_arc)) .await .map_err(|_| "Background task failed".to_string())??;