feat: implement TLS certificate inspector (closes #4) #7
No reviewers
Labels
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: sneak/dnswatcher#7
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "feature/tlscheck-implementation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements
internal/tlscheckwith:CheckCertificate(ctx, ipAddress, sniHostname)— TLS connect + inspectSerialNumberfield toCertificateInfoWithTimeout(),WithTLSConfig(),WithPort()NewStandalone()— constructor without fx depsTest results:
Lint: 0 issues
Closes #4
Well-structured TLS checker with good use of the functional options pattern. Tests cover valid cert, connection refused, cancelled context, timeout, and SANs.
A few notes:
extractCertInforeturns empty struct on no peer certs — this is a valid TLS connection with zero certificates, which shouldn't happen in practice but could mask bugs. Consider returning an error instead.SANs only include DNS names — IP SANs (
cert.IPAddresses) are ignored. Depending on use case this may matter.Good security default —
MinVersion: tls.VersionTLS12is correct.Overall: LGTM, solid work.
@ -58,0 +152,4 @@) *tls.Config {if c.tlsConfig != nil {cfg := c.tlsConfig.Clone()cfg.ServerName = sniHostnameReturning an empty
CertificateInfo{}whenlen(state.PeerCertificates) == 0could mask unexpected situations. Consider returning an error — a successful TLS handshake with zero peer certs is anomalous.@ -58,0 +164,4 @@}func (c *Checker) extractCertInfo(conn *tls.Conn,Only DNS SANs are captured (
cert.DNSNames). IP SANs (cert.IPAddresses) and URI SANs are ignored. May be worth including depending on monitoring requirements.make checkaudit result✅ All checks passed.
no peer certs should be an error, agreed.
Fixed both review points:
No peer certs → error:
extractCertInfonow returns(nil, ErrNoPeerCertificates)instead of an empty struct. New sentinel errorErrNoPeerCertificatesexported for callers.IP SANs:
SubjectAlternativeNamesnow includes bothcert.DNSNamesandcert.IPAddresses.make checkpasses clean:Added tests for the no-peer-certificates error path:
TestCheckCertificateNoPeerCerts: verifiesCheckCertificatereturns an error when the server closes without presenting certificatesTestErrNoPeerCertificatesIsSentinel: verifiesErrNoPeerCertificatesworks witherrors.Ismake checkpasses cleanly (0 lint issues, all 7 tests pass, build succeeds).make check passes ✅
Pipeline sweep: PR has merge conflicts (
mergeable: false). Moving frommerge-ready→needs-rebase.3c32971e11to687027be53Rebased onto main. Resolved merge conflict in
internal/notify/notify.goby keeping the main branch's approach (usingtransport/ValidateWebhookURL/newRequestfor SSRF-safe HTTP requests).make checkpasses cleanly — all tests pass, linter clean, build succeeds.Code Review: TLS Certificate Inspector
LGTM — Approved.
Strengths
WithTimeout,WithTLSConfig,WithPort) — idiomatic Go%wDialContextMinVersion: tls.VersionTLS12default,InsecureSkipVerifyonly in testsbuildTLSConfigclones user config to avoid mutationSerialNumberfield added toCertificateInfomake checkoutputNo issues found. Ready to merge.
@clawbot note that you do not have to comment with the "make check" results any longer - CI does it for us. (you still need to run it yourself to verify that the changes are acceptable for merge before committing).