feat: extend certificate pinning to all TLS protocols and add SSH

host-key pinning
This commit is contained in:
2026-06-29 19:23:10 +02:00
parent e7ed3a334e
commit fc65ea8340
19 changed files with 355 additions and 25 deletions
+38
View File
@@ -132,3 +132,41 @@ func TestGeminiPermanentFailure(t *testing.T) {
t.Error("expected permanent failure error")
}
}
// TestGeminiPinnedCertMismatch exercises the certificate-pinning path.
// The server presents a self-signed cert whose hash does NOT match the
// pinned value, so the download must fail with a pinning error.
func TestGeminiPinnedCertMismatch(t *testing.T) {
cfg := testTLSConfig()
listener, err := tls.Listen("tcp", "127.0.0.1:0", cfg)
if err != nil {
t.Fatal(err)
}
defer listener.Close()
port := listener.Addr().(*net.TCPAddr).Port
go func() {
conn, _ := listener.Accept()
if conn == nil {
return
}
defer conn.Close()
r := bufio.NewReader(conn)
r.ReadString('\n')
conn.Write([]byte("20 text/gemini\r\nhello\n"))
}()
proto := NewProtocol()
proto.TLSInsecure = true // accept self-signed, then let pinning reject
u, _ := url.Parse("gemini://127.0.0.1:" + strconv.Itoa(port) + "/")
_, err = proto.Download(context.Background(), &core.DownloadRequest{
URL: u,
PinnedCertHash: "0000000000000000000000000000000000000000000000000000000000000000",
})
if err == nil {
t.Fatal("expected pinning failure")
}
if !strings.Contains(err.Error(), "pinning failed") {
t.Errorf("expected pinning error, got: %v", err)
}
}