Advertise ETM MAC names for AEAD-only clients (fixes #236)#243
Open
barnaby wants to merge 1 commit into
Open
Conversation
swift-nio-ssh only implements AEAD ciphers (AES-GCM, chacha20-poly1305), which report macName == nil and ignore MAC negotiation. But the KEXINIT still requires the MAC-name lists to intersect. The fallback advertised a single placeholder hmac-sha2-256, so hardened OpenSSH servers that offer ONLY encrypt-then-MAC names (e.g. NixOS-style configs) failed with keyExchangeNegotiationFailure. Advertise the plain + -etm variants of SHA-256/512 so negotiation intersects with both stock and hardened servers. The negotiated value remains unused for AEAD schemes. Adds negotiation tests: hardened-prod KEXINIT (captured vectors), ETM-only, rekey, both-directions consulted, asymmetric-rejected, and negative paths (no shared cipher/KEX/host-key). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
swift-nio-ssh only implements AEAD ciphers (AES-GCM, chacha20-poly1305), which report
macName == niland ignore MAC negotiation. But the KEXINIT still requires the MAC-name lists to intersect. The all-AEAD fallback insupportedMacAlgorithmsadvertises a single placeholderhmac-sha2-256, so a hardened OpenSSH server that offers only encrypt-then-MAC names (e.g. NixOS-style configs:hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com) has no intersection and the client fails withkeyExchangeNegotiationFailuremid-handshake.This is #236. Real-world impact: an iOS app using swift-nio-ssh as a direct SSH client cannot connect to hardened DigitalOcean/NixOS machines at all.
Change
When the scheme set yields no real MAC (all-AEAD), advertise the plain and
-etm@openssh.comvariants of SHA-256/512 instead of the single placeholder. The negotiated MAC value is still never used for AEAD schemes (integrity comes from the AEAD tag) — the list exists only so the KEXINIT MAC rows intersect with both stock and hardened servers.Tests
Adds negotiation coverage in
SSHKeyExchangeStateMachineTests: a captured hardened-prod KEXINIT (OpenSSH 10.2), ETM-only, rekey (same path re-run), both-directions-consulted, asymmetric-rejected (documents the symmetric-only constraint), and negative paths (no shared cipher / KEX / host-key).Verified end-to-end: the patched stack completes the full handshake against real hardened OpenSSH 10.2 production machines in ~1s, where upstream fails at ~0.4s.