feat(apple): adapt the macOS client to ABI v2 — client identity + SPAKE2 PIN pairing
ci / rust (push) Has been cancelled
ci / rust (push) Has been cancelled
The pairing/renegotiation batch bumped the punktfunk/1 ABI to v2 and the host now hard-rejects v1 Hellos (m3.rs), so streaming from the Mac was dead until the bundled PunktfunkCore.xcframework is rebuilt — it is gitignored, so that is a per-checkout step: bash scripts/build-xcframework.sh. The Swift wrapper itself was already adapted upstream; this lands the app on top of it. - ClientIdentityStore: persistent client identity in the login Keychain, presented on every connect so paired hosts recognize this Mac. Keychain access failure throws instead of regenerating (a fresh identity would silently un-pair this Mac from every --require-pairing host); a lost first-run race resolves toward the stored identity; pairing uses the strict loadForPairing() so a memory-only identity can't strand a ceremony. - PairSheet: the SPAKE2 PIN ceremony, reachable from a host card's context menu and from the trust prompt's "Pair with PIN instead…" (which drops the live session first — the host's accept loop is sequential). Success pins the verified fingerprint and connects; an in-flight ceremony self-discards when the sheet is dismissed, so a late success can't pin + auto-connect behind the user's back. Wrong PIN and Keychain failures get distinct, actionable error text. - Tests: identity unit tests; the full pairing ceremony + --require-pairing gate on loopback (test-loopback.sh arms a second host, parses its PIN from the log, and gives both hosts throwaway config homes — no more writes to the real ~/.config/punktfunk); remote pairing + pinned stream over the LAN (PUNKTFUNK_REMOTE_PIN, _PORT). Validated live against the box: SPAKE2 ceremony with the host's arming PIN → verified fingerprint → pinned + identified 720p60 session (host persisted the client identity); first light 60/60 AUs decoded to pixels; vkcube on glass through the app. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
// Saved hosts + their pinned identities, persisted as JSON in UserDefaults.
|
||||
//
|
||||
// Trust model (client side of punktfunk/1): the host serves a persistent certificate and
|
||||
// logs its SHA-256 fingerprint at startup. First connect is trust-on-first-use — the user
|
||||
// explicitly confirms the observed fingerprint against the host's log, and we pin it here.
|
||||
// Every later connect passes the pin into punktfunk-core, which refuses a host whose
|
||||
// identity changed. (Host→client authorization — a pairing PIN — is a roadmap item; today
|
||||
// the host accepts any client that can reach its port.)
|
||||
// logs its SHA-256 fingerprint at startup. The pin lands here one of two ways — the
|
||||
// trust-on-first-use prompt (user compares the observed fingerprint against the host's
|
||||
// log) or the SPAKE2 PIN pairing ceremony (PairSheet; mutually verified, and the host
|
||||
// stores our identity from ClientIdentityStore in return). Every later connect passes
|
||||
// the pin into punktfunk-core, which refuses a host whose identity changed. Hosts running
|
||||
// --require-pairing only admit paired clients, so for them pairing is the only way in.
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
Reference in New Issue
Block a user