diff --git a/internal/tlscheck/extractcertinfo_test.go b/internal/tlscheck/extractcertinfo_test.go new file mode 100644 index 0000000..56830e8 --- /dev/null +++ b/internal/tlscheck/extractcertinfo_test.go @@ -0,0 +1,67 @@ +package tlscheck_test + +import ( + "context" + "crypto/tls" + "errors" + "net" + "testing" + "time" + + "sneak.berlin/go/dnswatcher/internal/tlscheck" +) + +func TestCheckCertificateNoPeerCerts(t *testing.T) { + t.Parallel() + + lc := &net.ListenConfig{} + + ln, err := lc.Listen( + context.Background(), "tcp", "127.0.0.1:0", + ) + if err != nil { + t.Fatal(err) + } + + defer func() { _ = ln.Close() }() + + addr, ok := ln.Addr().(*net.TCPAddr) + if !ok { + t.Fatal("unexpected address type") + } + + // Accept and immediately close to cause TLS handshake failure. + go func() { + conn, err := ln.Accept() + if err != nil { + return + } + + _ = conn.Close() + }() + + checker := tlscheck.NewStandalone( + tlscheck.WithTimeout(2*time.Second), + tlscheck.WithTLSConfig(&tls.Config{ + InsecureSkipVerify: true, //nolint:gosec // test + MinVersion: tls.VersionTLS12, + }), + tlscheck.WithPort(addr.Port), + ) + + _, err = checker.CheckCertificate( + context.Background(), "127.0.0.1", "localhost", + ) + if err == nil { + t.Fatal("expected error when server presents no certs") + } +} + +func TestErrNoPeerCertificatesIsSentinel(t *testing.T) { + t.Parallel() + + err := tlscheck.ErrNoPeerCertificates + if !errors.Is(err, tlscheck.ErrNoPeerCertificates) { + t.Fatal("expected sentinel error to match") + } +}