82 lines
2.2 KiB
Go
82 lines
2.2 KiB
Go
//go:build linux || freebsd
|
|
// +build linux freebsd
|
|
|
|
package sftp
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"golang.org/x/crypto/ssh"
|
|
)
|
|
|
|
func TestHostKeyCallbackInsecure(t *testing.T) {
|
|
cb, err := hostKeyCallback("", true, "")
|
|
if err != nil {
|
|
t.Fatalf("hostKeyCallback: %v", err)
|
|
}
|
|
if cb == nil {
|
|
t.Fatal("expected callback")
|
|
}
|
|
}
|
|
|
|
func TestHostKeyCallbackMissingFile(t *testing.T) {
|
|
_, err := hostKeyCallback("/nonexistent/known_hosts", false, "")
|
|
if err == nil {
|
|
t.Fatal("expected error for missing known_hosts")
|
|
}
|
|
}
|
|
|
|
func TestHostKeyCallbackPinned(t *testing.T) {
|
|
// Pinning takes precedence over insecure and known_hosts: the
|
|
// callback is returned without touching the filesystem.
|
|
cb, err := hostKeyCallback("/nonexistent/known_hosts", false, "SHA256:abcdefghijklmnopqrstuvwxyz0123456789+/=")
|
|
if err != nil {
|
|
t.Fatalf("hostKeyCallback with pin: %v", err)
|
|
}
|
|
if cb == nil {
|
|
t.Fatal("expected callback for pinned host key")
|
|
}
|
|
}
|
|
|
|
func TestNormalizePinnedHostKey(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
in string
|
|
want string
|
|
}{
|
|
{"empty", "", ""},
|
|
{"whitespace only", " ", ""},
|
|
{"openssh form preserved", "SHA256:abc123", "SHA256:abc123"},
|
|
{"hex converted to base64", "00", "SHA256:AA=="},
|
|
{"invalid hex falls through", "nothex", "nothex"},
|
|
}
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
if got := normalizePinnedHostKey(c.in); got != c.want {
|
|
t.Errorf("normalizePinnedHostKey(%q) = %q, want %q", c.in, got, c.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSSHFingerprintSHA256(t *testing.T) {
|
|
// Use a fixed test key so the fingerprint is deterministic.
|
|
// Generated with ssh-keygen -t ed25519 -f /tmp/test_key -N ""
|
|
// and parsed here. We use ssh.ParseAuthorizedKey on a known-good
|
|
// public key line.
|
|
pubLine := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE+HHi0MtRj4VPl8mdP8gniGZDRb0SZTdI2TPxRyCm1H test@example.com"
|
|
key, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pubLine))
|
|
if err != nil {
|
|
t.Fatalf("ParseAuthorizedKey: %v", err)
|
|
}
|
|
fp := sshFingerprintSHA256(key)
|
|
if !strings.HasPrefix(fp, "SHA256:") {
|
|
t.Errorf("fingerprint should start with SHA256:, got %q", fp)
|
|
}
|
|
// The fingerprint must be deterministic for the same key.
|
|
if fp != sshFingerprintSHA256(key) {
|
|
t.Error("fingerprint should be deterministic")
|
|
}
|
|
}
|