summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--diff.go121
2 files changed, 109 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index 6315ace..dda3709 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@ tls.pem: tls-getcerts config-sockets.txt NET-tls
tls.html: %.html: %.pem tls-pem2html
./tls-pem2html < $< > $@
-diff.txt: diff tls.pem crtsh.pem
+diff.html: diff tls.pem crtsh.pem
./diff tls.pem crtsh.pem > $@
NET-%:
diff --git a/diff.go b/diff.go
index 59e7625..25dee8b 100644
--- a/diff.go
+++ b/diff.go
@@ -5,6 +5,7 @@ import (
"encoding/pem"
"fmt"
"io/ioutil"
+ "html/template"
"os"
"sort"
)
@@ -87,6 +88,99 @@ func fmtCert(cert *x509.Certificate) string {
cert.NotAfter.Format("2006-01-02 15:04:05 MST(-07)"))
}
+var tmpl = template.Must(template.New("2html").
+ Funcs(template.FuncMap{
+ "class": class,
+ "link": link,
+ "join": join,
+ "isNil": isNil,
+ }).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 td {
+ background-color: #AAAAF3;
+ }
+ a { text-decoration: none; }
+ </style>
+ <script src="sorttable.js"></script>
+ <base target="_parent" />
+</head>
+<body>
+<table>
+ <tr class="diff-del"><td colspan=4>--- {{.fileTLS}}</td></tr>
+ <tr class="diff-add"><td colspan=4>+++ {{.fileCrtSh}}</td></tr>
+ <tr class="diff-dat"><td colspan=4>@@ -1,{{len .certsTLS}} +1,{{len .certsCrtSh}} @@</td></tr>
+{{define "Row"}}
+ <tr class={{.pfix | class}}>
+ <td><a href="{{.cert | link}}">{{.pfix}}</a></td>
+ <td><a href="{{.cert | link}}">{{.cert.Subject.CommonName}}</a></td>
+ <td><a href="{{.cert | link}}">{{.cert.NotBefore.Local.Format "2006-01-02 15:04:05"}}</a></td>
+ <td><a href="{{.cert | link}}">{{.cert.NotAfter.Local.Format "2006-01-02 15:04:05"}}</a></td>
+ </tr>
+{{end}}
+{{range $cert := .certs}}
+{{if isNil $cert.CrtSh}}
+{{template "Row" join "-" $cert.TLS}}
+{{else if $cert.TLS.Equal $cert.CrtSh | not}}
+{{template "Row" join "-" $cert.TLS}}
+{{template "Row" join "+" $cert.CrtSh}}
+{{else}}
+{{template "Row" join " " $cert.TLS}}
+{{end}}
+{{end}}
+</table>
+</body>
+</html>
+`))
+
+type Cert struct {
+ TLS, CrtSh *x509.Certificate
+}
+
+func link(cert *x509.Certificate) string {
+ return fmt.Sprintf("https://crt.sh/?serial=%036x", cert.SerialNumber)
+}
+
+func isNil(cert *x509.Certificate) bool {
+ return cert == nil
+}
+
+func class(pfix string) string {
+ return map[string]string {
+ "+": "diff-add",
+ "-": "diff-del",
+ " ": "diff-ctx",
+ }[pfix]
+}
+
+func join(pfix string, cert *x509.Certificate) map[string]interface{} {
+ return map[string]interface{} {
+ "pfix": pfix,
+ "cert": cert,
+ }
+}
+
func main() {
if len(os.Args) != 3 {
fmt.Fprintf(os.Stderr, "Usage: %s TLS-file crt.sh-file\n", os.Args[0])
@@ -97,19 +191,20 @@ func main() {
certsCrtSh, err := readCrtSh(os.Args[2], hostsTLS)
handleErr(err, "Could load crt.sh file: %v\n")
- fmt.Printf("--- %s\n", os.Args[1])
- fmt.Printf("+++ %s\n", os.Args[2])
- fmt.Printf("@@ -1,%d +1,%d @@\n", len(hostsTLS), len(hostsTLS))
+ certs := make([]Cert, len(certsTLS))
+ i := 0
for _, host := range hostsTLS {
- certTLS := certsTLS[host]
- certCrtSh, okCrtSh := certsCrtSh[host]
- if !okCrtSh {
- fmt.Printf("-%s\t%s\n", host, fmtCert(certTLS))
- } else if !certTLS.Equal(certCrtSh) {
- fmt.Printf("-%s\t%s\n", host, fmtCert(certTLS))
- fmt.Printf("+%s\t%s\n", host, fmtCert(certCrtSh))
- } else {
- fmt.Printf(" %s\t%s\n", host, fmtCert(certTLS))
- }
+ var cert Cert
+ cert.TLS = certsTLS[host]
+ cert.CrtSh = certsCrtSh[host]
+ certs[i] = cert
+ i++
}
+ handleErr(tmpl.Execute(os.Stdout, map[string]interface{}{
+ "certs": certs,
+ "certsTLS": certsTLS,
+ "certsCrtSh": certsCrtSh,
+ "fileTLS": os.Args[1],
+ "fileCrtSh": os.Args[2],
+ }), "Could not execute template: %v\n")
}