diff options
Diffstat (limited to 'diff-pem2html.go')
-rw-r--r-- | diff-pem2html.go | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/diff-pem2html.go b/diff-pem2html.go new file mode 100644 index 0000000..8f3b1e9 --- /dev/null +++ b/diff-pem2html.go @@ -0,0 +1,144 @@ +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(`<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>CT log accuracy</title> + <style> + html { + height: 100%; + } + body { + font-size: 10px; + font-family: monospace; + height: 100%; + margin: 0; + display: flex; + align-items: center; + } + body > * { + margin: auto; + } + .diff-del, .diff-del a { color: red; } + .diff-add, .diff-add a { color: green; } + .diff-dat, .diff-dat a { color: blue; } + .diff-ctx, .diff-ctx a { color: black; } + tr:hover a { + background-color: #AAAAF3; + } + td a { + text-decoration: none; + padding: 0.1em 0.25em; + display: block; + width: 100%; + height: 100%; + color: black; + } + </style> + <script src="sorttable.js"></script> + <base target="_parent" /> +</head> +<body> +<table> + <tr class="diff-del"><td colspan=4>--- tls.pem</td></tr> + <tr class="diff-add"><td colspan=4>+++ crtsh.pem</td></tr> + <tr class="diff-dat"><td colspan=4>@@ -1,{{.nTLS}} +1,{{.nCrtSh}} @@</td></tr> +{{range $cert := .certs}} + <tr class={{$cert.Class}}> + <td><a href="{{$cert.Url}}">{{if eq $cert.Pfix " "}} {{else}}{{$cert.Pfix}}{{end}}</a></td> + <td><a href="{{$cert.Url}}">{{$cert.X509.Subject.CommonName}}</a></td> + <td><a href="{{$cert.Url}}">{{$cert.X509.NotBefore.Local.Format "2006-01-02 15:04:05"}}</a></td> + <td><a href="{{$cert.Url}}">{{$cert.X509.NotAfter.Local.Format "2006-01-02 15:04:05"}}</a></td> + </tr> +{{end}} +</table> +</body> +</html> +`)) + +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") +} |