Größte offene Härtungslücke geschlossen: SSHTransport nutzte bisher
.acceptAnything() für Host-Key-Validierung, akzeptierte also jeden
Schlüssel ohne Prüfung -- ein Man-in-the-Middle im lokalen Netz wäre
unbemerkt geblieben. Jetzt Trust-on-first-use wie beim REST-Zertifikat:
- SSHHostKeyFingerprint: SHA256 über NIOSSHPublicKey.write(to:) (die
SSH-Wire-Format-Bytes des Schlüssels) -- exakt die Bytes, die auch
OpenSSH für seine SHA256:-Fingerabdrücke hasht. Per Unit-Test gegen
einen echten ssh-keygen-erzeugten Testschlüssel kreuzgeprüft
(SHA256:Hllxv6LLoHl2XTIXGGjUYJHbPFoH2F7iMrR74C5J95g), nicht geraten.
- SSHHostKeyTrustStore: UserDefaults-Persistenz pro Host, Pendant zu
CertificateTrustStore.
- SSHTransport conformt jetzt selbst zu NIOSSHClientServerAuthentication-
Delegate (wie RestTransport zu URLSessionDelegate) und übergibt sich
selbst als .custom(self) Host-Key-Validator.
- ConnectionService: neuer State .needsSSHHostKeyConfirmation, eigener
Bestätigungs-Retry-Pfad (trustCurrentSSHHostKeyAndRetry), analog zum
bestehenden Zertifikat-Flow.
- ConnectView: zweiter Bestätigungsdialog mit Warnhinweis, dass ein
geänderter Fingerabdruck bei zuvor schon verbundenen Routern auf ein
manipuliertes Netzwerk hindeuten könnte.
BackupService/FactoryResetService bekommen die TOFU-Prüfung automatisch
mit (SSHTransport-Default-Parameter, gleicher UserDefaults-Speicher),
ohne eigene Bestätigungs-UI -- in der Praxis unkritisch, da der
Verbinden-Tab das Vertrauen immer zuerst herstellt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HReLXMbmPvtQ23p1iWiJNW