diff --git a/knownhosts.go b/knownhosts.go index c2fb516..4dad777 100644 --- a/knownhosts.go +++ b/knownhosts.go @@ -76,13 +76,23 @@ func (hkcb HostKeyCallback) HostKeyAlgorithms(hostWithPort string) (algos []stri // example by https://github.com/golang/crypto/pull/254. hostKeys := hkcb.HostKeys(hostWithPort) seen := make(map[string]struct{}, len(hostKeys)) - for _, key := range hostKeys { - typ := key.Type() + addAlgo := func(typ string) { if _, already := seen[typ]; !already { algos = append(algos, typ) seen[typ] = struct{}{} } } + for _, key := range hostKeys { + typ := key.Type() + if typ == ssh.KeyAlgoRSA { + // KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms, + // not public key formats, so they can't appear as a PublicKey.Type. + // The corresponding PublicKey.Type is KeyAlgoRSA. See RFC 8332, Section 2. + addAlgo(ssh.KeyAlgoRSASHA512) + addAlgo(ssh.KeyAlgoRSASHA256) + } + addAlgo(typ) + } return algos } diff --git a/knownhosts_test.go b/knownhosts_test.go index 3a56510..8ace01b 100644 --- a/knownhosts_test.go +++ b/knownhosts_test.go @@ -42,10 +42,10 @@ func TestHostKeyAlgorithms(t *testing.T) { } expectedAlgorithms := map[string][]string{ - "only-rsa.example.test:22": {"ssh-rsa"}, + "only-rsa.example.test:22": {"rsa-sha2-512", "rsa-sha2-256", "ssh-rsa"}, "only-ecdsa.example.test:22": {"ecdsa-sha2-nistp256"}, "only-ed25519.example.test:22": {"ssh-ed25519"}, - "multi.example.test:2233": {"ssh-rsa", "ecdsa-sha2-nistp256", "ssh-ed25519"}, + "multi.example.test:2233": {"rsa-sha2-512", "rsa-sha2-256", "ssh-rsa", "ecdsa-sha2-nistp256", "ssh-ed25519"}, "192.168.1.102:2222": {"ecdsa-sha2-nistp256", "ssh-ed25519"}, "unknown-host.example.test": {}, // host not in file "multi.example.test:22": {}, // different port than entry in file