diff --git a/lib/src/algorithm/ssh_kex_type.dart b/lib/src/algorithm/ssh_kex_type.dart index 2866319..420a749 100644 --- a/lib/src/algorithm/ssh_kex_type.dart +++ b/lib/src/algorithm/ssh_kex_type.dart @@ -7,6 +7,15 @@ class SSHKexType extends SSHAlgorithm { digestFactory: digestSha256, ); + /// RFC 8731 name for the same algorithm as [x25519]. Servers hardened to a + /// single kex commonly offer only this spelling, and OpenSSH matches names + /// literally — without it the handshake dies with "no matching key exchange + /// method found". + static const x25519Rfc = SSHKexType._( + name: 'curve25519-sha256', + digestFactory: digestSha256, + ); + static const nistp256 = SSHKexType._( name: 'ecdh-sha2-nistp256', digestFactory: digestSha256, diff --git a/lib/src/ssh_algorithm.dart b/lib/src/ssh_algorithm.dart index fc57995..1107647 100644 --- a/lib/src/ssh_algorithm.dart +++ b/lib/src/ssh_algorithm.dart @@ -46,6 +46,7 @@ class SSHAlgorithms { const SSHAlgorithms({ this.kex = const [ SSHKexType.x25519, + SSHKexType.x25519Rfc, SSHKexType.nistp521, SSHKexType.nistp384, SSHKexType.nistp256, diff --git a/lib/src/ssh_transport.dart b/lib/src/ssh_transport.dart index ff46a42..c61ce10 100644 --- a/lib/src/ssh_transport.dart +++ b/lib/src/ssh_transport.dart @@ -1196,6 +1196,7 @@ class SSHTransport { switch (_kexType) { case SSHKexType.x25519: + case SSHKexType.x25519Rfc: _kex = await SSHKexX25519.createAsync(); break; case SSHKexType.nistp256: diff --git a/test/src/algorithm/ssh_cipher_type_test.dart b/test/src/algorithm/ssh_cipher_type_test.dart index 132b226..a13b575 100644 --- a/test/src/algorithm/ssh_cipher_type_test.dart +++ b/test/src/algorithm/ssh_cipher_type_test.dart @@ -106,6 +106,7 @@ void main() { algorithms.kex, equals([ SSHKexType.x25519, + SSHKexType.x25519Rfc, SSHKexType.nistp521, SSHKexType.nistp384, SSHKexType.nistp256,