//go:build standalone package main import ( "crypto/x509" "encoding/pem" "errors" "fmt" "html/template" "io" "os" "git.lukeshu.com/dashboard/bin-src/util" ) //nolint:gochecknoglobals // would be const var tmpl = template.Must(template.New("pem2html"). Funcs(template.FuncMap{ "htmlcell": util.HTMLCellEscapeString, }).Parse(` {{range $cert := .certs}} {{end}}
--- tls.pem
+++ crtsh.pem
@@ -1,{{.nTLS}} +1,{{.nCrtSh}} @@
{{$cert.Pfix | htmlcell}} {{$cert.X509.Subject.CommonName | htmlcell}} {{$cert.X509.NotBefore.Local.Format "2006-01-02 15:04:05"}} {{$cert.X509.NotAfter.Local.Format "2006-01-02 15:04:05"}}
`)) type Cert struct { Url string action string X509 *x509.Certificate } func (cert Cert) Pfix() string { return map[string]string{ "add": "+", "del": "-", "ctx": " ", }[cert.action] } func (cert Cert) Class() string { return "diff-" + cert.action } func main() { if err := mainWithError(); err != nil { _, _ = fmt.Fprintf(os.Stderr, "%s: error: %v", os.Args[0], err) os.Exit(1) } } func mainWithError() error { data, err := io.ReadAll(os.Stdin) if err != nil { return fmt.Errorf("reading stdin: %w", err) } var certs []Cert a := 0 b := 0 for len(data) > 0 { var certPem *pem.Block certPem, data = pem.Decode(data) var ok bool var cert Cert cert.Url, ok = certPem.Headers["X-Crt-Sh-Url"] if !ok { return errors.New("did not get X-Crt-Sh-Url") } cert.action, ok = certPem.Headers["X-Diff-Action"] if !ok { return errors.New("did not get X-Diff-Action") } switch cert.action { case "add": b++ case "del": a++ case "ctx": a++ b++ default: return fmt.Errorf("unknown X-Diff-Action: %q", cert.action) } cert.X509, err = x509.ParseCertificate(certPem.Bytes) if err != nil { cert.X509 = new(x509.Certificate) } certs = append(certs, cert) } if err := tmpl.Execute(os.Stdout, map[string]any{ "certs": certs, "nTLS": a, "nCrtSh": b, }); err != nil { return fmt.Errorf("could not execute template: %w", err) } return nil }