diff --git a/ssh/knownhosts/knownhosts.go b/ssh/knownhosts/knownhosts.go index 1ef1c35..c7eda05 100644 --- a/ssh/knownhosts/knownhosts.go +++ b/ssh/knownhosts/knownhosts.go @@ -192,8 +192,7 @@ func parseLine(line []byte) (marker, host string, key ssh.PublicKey, err error) return "", "", nil, errors.New("knownhosts: missing host pattern") } - // ignore the keytype as it's in the key blob anyway. - _, line = nextWord(line) + wantType, line := nextWord(line) if len(line) == 0 { return "", "", nil, errors.New("knownhosts: missing key type pattern") } @@ -209,6 +208,10 @@ func parseLine(line []byte) (marker, host string, key ssh.PublicKey, err error) return "", "", nil, err } + if key.Type() != wantType { + return "", "", nil, fmt.Errorf("knownhosts: key type mismatch: found %q, want %q", key.Type(), wantType) + } + return marker, host, key, nil } diff --git a/ssh/knownhosts/knownhosts_test.go b/ssh/knownhosts/knownhosts_test.go index 8e1fba2..f3af2da 100644 --- a/ssh/knownhosts/knownhosts_test.go +++ b/ssh/knownhosts/knownhosts_test.go @@ -12,6 +12,7 @@ import ( "fmt" "net" "reflect" + "strings" "testing" "golang.org/x/crypto/ssh" @@ -446,3 +447,18 @@ func TestUnicodeSpaceTrimming(t *testing.T) { t.Errorf("Did not match dirty host, implying parsing issue") } } + +func TestKeyTypeMismatch(t *testing.T) { + line := fmt.Sprintf("server.org ssh-rsa %s", base64.StdEncoding.EncodeToString(edKey.Marshal())) + + db := newHostKeyDB() + err := db.Read(bytes.NewBufferString(line), "testdb") + if err == nil { + t.Fatal("Read succeeded on line with key type mismatch, expected error") + } + + expectedErr := `knownhosts: key type mismatch: found "ssh-ed25519", want "ssh-rsa"` + if !strings.Contains(err.Error(), expectedErr) { + t.Fatalf("got error %q, want to contain %q", err.Error(), expectedErr) + } +}