package main import ( "crypto/x509" "encoding/pem" "fmt" "html/template" "io/ioutil" "os" ) func handleErr(err error, str string, a ...interface{}) { a = append([]interface{}{err}, a...) if err != nil { fmt.Fprintf(os.Stderr, str, a...) os.Exit(1) } } func handleBool(ok bool, str string, a ...interface{}) { if !ok { fmt.Fprintf(os.Stderr, str, a...) os.Exit(1) } } var tmpl = template.Must(template.New("2html").Parse(` {{range $cert := .certs}} {{end}}
--- tls.pem
+++ crtsh.pem
@@ -1,{{.nTLS}} +1,{{.nCrtSh}} @@
{{if eq $cert.Pfix " "}} {{else}}{{$cert.Pfix}}{{end}} {{$cert.X509.Subject.CommonName}} {{$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() { data, err := ioutil.ReadAll(os.Stdin) handleErr(err, "Error reading stdin: %v\n") 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"] handleBool(ok, "Did not get X-Crt-Sh-Url\n") cert.action, ok = certPem.Headers["X-Diff-Action"] handleBool(ok, "Did not get X-Diff-Action\n") switch cert.action { case "add": b++ case "del": a++ case "ctx": a++ b++ default: handleBool(false, "Unknown X-Diff-Action: %q\n", cert.action) } cert.X509, err = x509.ParseCertificate(certPem.Bytes) handleErr(err, "Error parsing cert: %v\n") certs = append(certs, cert) } handleErr(tmpl.Execute(os.Stdout, map[string]interface{}{ "certs":certs, "nTLS": a, "nCrtSh": b, }), "Could not execute template: %v\n") }