cmd: start linting fixes.

This commit is contained in:
2025-11-16 00:36:19 -08:00
parent a573f1cd20
commit f31d74243f
25 changed files with 662 additions and 599 deletions

View File

@@ -1,20 +1,20 @@
package main
import (
"crypto/tls"
"crypto/x509"
"flag"
"errors"
"fmt"
"io/ioutil"
"net"
"os"
"time"
"crypto/tls"
"crypto/x509"
"errors"
"flag"
"fmt"
"net"
"os"
"strings"
"time"
"git.wntrmute.dev/kyle/goutils/certlib"
hosts "git.wntrmute.dev/kyle/goutils/certlib/hosts"
"git.wntrmute.dev/kyle/goutils/certlib/revoke"
"git.wntrmute.dev/kyle/goutils/fileutil"
"git.wntrmute.dev/kyle/goutils/certlib"
hosts "git.wntrmute.dev/kyle/goutils/certlib/hosts"
"git.wntrmute.dev/kyle/goutils/certlib/revoke"
"git.wntrmute.dev/kyle/goutils/fileutil"
)
var (
@@ -23,6 +23,13 @@ var (
verbose bool
)
var (
strOK = "OK"
strExpired = "EXPIRED"
strRevoked = "REVOKED"
strUnknown = "UNKNOWN"
)
func main() {
flag.BoolVar(&hardfail, "hardfail", false, "treat revocation check failures as fatal")
flag.DurationVar(&timeout, "timeout", 10*time.Second, "network timeout for OCSP/CRL fetches and TLS site connects")
@@ -42,16 +49,16 @@ func main() {
for _, target := range flag.Args() {
status, err := processTarget(target)
switch status {
case "OK":
fmt.Printf("%s: OK\n", target)
case "EXPIRED":
fmt.Printf("%s: EXPIRED: %v\n", target, err)
case strOK:
fmt.Printf("%s: %s\n", target, strOK)
case strExpired:
fmt.Printf("%s: %s: %v\n", target, strExpired, err)
exitCode = 1
case "REVOKED":
fmt.Printf("%s: REVOKED\n", target)
case strRevoked:
fmt.Printf("%s: %s\n", target, strRevoked)
exitCode = 1
case "UNKNOWN":
fmt.Printf("%s: UNKNOWN: %v\n", target, err)
case strUnknown:
fmt.Printf("%s: %s: %v\n", target, strUnknown, err)
if hardfail {
// In hardfail, treat unknown as failure
exitCode = 1
@@ -67,74 +74,67 @@ func processTarget(target string) (string, error) {
return checkFile(target)
}
// Not a file; treat as site
return checkSite(target)
}
func checkFile(path string) (string, error) {
in, err := ioutil.ReadFile(path)
if err != nil {
return "UNKNOWN", err
}
// Prefer high-level helpers from certlib to load certificates from disk
if certs, err := certlib.LoadCertificates(path); err == nil && len(certs) > 0 {
// Evaluate the first certificate (leaf) by default
return evaluateCert(certs[0])
}
// Try PEM first; if that fails, try single DER cert
certs, err := certlib.ReadCertificates(in)
if err != nil || len(certs) == 0 {
cert, _, derr := certlib.ReadCertificate(in)
if derr != nil || cert == nil {
if err == nil {
err = derr
}
return "UNKNOWN", err
}
return evaluateCert(cert)
}
// Evaluate the first certificate (leaf) by default
return evaluateCert(certs[0])
cert, err := certlib.LoadCertificate(path)
if err != nil || cert == nil {
return strUnknown, err
}
return evaluateCert(cert)
}
func checkSite(hostport string) (string, error) {
// Use certlib/hosts to parse host/port (supports https URLs and host:port)
target, err := hosts.ParseHost(hostport)
if err != nil {
return "UNKNOWN", err
return strUnknown, err
}
d := &net.Dialer{Timeout: timeout}
conn, err := tls.DialWithDialer(d, "tcp", target.String(), &tls.Config{InsecureSkipVerify: true, ServerName: target.Host})
conn, err := tls.DialWithDialer(
d,
"tcp",
target.String(),
&tls.Config{InsecureSkipVerify: true, ServerName: target.Host}, // #nosec G402
)
if err != nil {
return "UNKNOWN", err
return strUnknown, err
}
defer conn.Close()
state := conn.ConnectionState()
if len(state.PeerCertificates) == 0 {
return "UNKNOWN", errors.New("no peer certificates presented")
return strUnknown, errors.New("no peer certificates presented")
}
return evaluateCert(state.PeerCertificates[0])
}
func evaluateCert(cert *x509.Certificate) (string, error) {
// Expiry check
now := time.Now()
if !now.Before(cert.NotAfter) {
return "EXPIRED", fmt.Errorf("expired at %s", cert.NotAfter)
}
if !now.After(cert.NotBefore) {
return "EXPIRED", fmt.Errorf("not valid until %s", cert.NotBefore)
}
// Delegate validity and revocation checks to certlib/revoke helper.
// It returns revoked=true for both revoked and expired/not-yet-valid.
// Map those cases back to our statuses using the returned error text.
revoked, ok, err := revoke.VerifyCertificateError(cert)
if revoked {
if err != nil {
msg := err.Error()
if strings.Contains(msg, "expired") || strings.Contains(msg, "isn't valid until") || strings.Contains(msg, "not valid until") {
return strExpired, err
}
}
return strRevoked, err
}
if !ok {
// Revocation status could not be determined
return strUnknown, err
}
// Revocation check using certlib/revoke
revoked, ok, err := revoke.VerifyCertificateError(cert)
if revoked {
// If revoked is true, ok will be true per implementation, err may describe why
return "REVOKED", err
}
if !ok {
// Revocation status could not be determined
return "UNKNOWN", err
}
return "OK", nil
return strOK, nil
}