From 89fa60bdf5ed6bd729f4d7931c9603e896d38665 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 18 Nov 2016 03:23:25 -0500 Subject: more --- tls-pem2html.go | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 tls-pem2html.go (limited to 'tls-pem2html.go') diff --git a/tls-pem2html.go b/tls-pem2html.go new file mode 100644 index 0000000..efefd68 --- /dev/null +++ b/tls-pem2html.go @@ -0,0 +1,202 @@ +package main + +import ( + "crypto/x509" + "encoding/pem" + "fmt" + "html/template" + "io/ioutil" + "os" + "sort" + "time" +) + +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...) + } +} + +var tmpl = template.Must(template.New("pem2html"). + Funcs(template.FuncMap{ + "red": red, + "green": green, + }).Parse(` + + + + CT log + + + + + + + + + + + + +{{range $cert := .certs}} + + + + + + +{{end}} +
+

Updated {{.now.Local.Format "2006-01-02 15:04:05"}}

+
NotBeforeNotAfterSubject.CNSocket
{{$cert.X509.NotBefore.Local.Format "2006-01-02"}}{{$cert.X509.NotAfter.Local.Format "2006-01-02"}}{{$cert.X509.Subject.CommonName | html}}{{$cert.Socket | html}}
+ + +`)) + +var now = time.Now() + +type interpolation struct { + ta, tb time.Time + ba, bb byte +} + +func (i interpolation) interpolate(tc time.Time) byte { + db := i.tb.Sub(i.ta) + dc := tc.Sub(i.ta) + + pct := float64(dc) / float64(db) + if pct < 0 { + pct = 0 + } else if pct > 1 { + pct = 1 + } + + sb := int16(i.bb) - int16(i.ba) + sc := int16(pct * float64(sb)) + + return byte(int16(i.ba) + sc) +} + +var daysago = interpolation{ + ta: now.AddDate(0, 0, -30), + tb: now, + ba: 0xF3, + bb: 0x00, +} + +var daysuntil = interpolation{ + ta: now, + tb: now.AddDate(0, 0, 30), + ba: 0x00, + bb: 0xF3, +} + +func green(t time.Time) string { + b := daysago.interpolate(t) + return fmt.Sprintf("#%02X%02X%02X", b, 0xF3, b) +} + +func red(t time.Time) string { + b := daysuntil.interpolate(t) + return fmt.Sprintf("#%02X%02X%02X", 0xF3, b, b) +} + +type Cert struct { + Socket string + X509 *x509.Certificate +} + +type Certs []Cert + +// Len is the number of elements in the collection. +func (l Certs) Len() int { + return len(l) +} + +// Less reports whether the element with +// index i should sort before the element with index j. +func (l Certs) Less(i, j int) bool { + return l[i].X509.NotAfter.UTC().After(l[j].X509.NotAfter.UTC()) +} + +// Swap swaps the elements with indexes i and j. +func (l Certs) Swap(i, j int) { + tmp := l[i] + l[i] = l[j] + l[j] = tmp +} + +func main() { + data, err := ioutil.ReadAll(os.Stdin) + handleErr(err, "Error reading stdin: %v\n") + + var certs Certs + for len(data) > 0 { + var certPem *pem.Block + certPem, data = pem.Decode(data) + + var ok bool + var cert Cert + + cert.Socket, ok = certPem.Headers["X-Socket"] + handleBool(ok, "Did not get X-Socket\n") + + cert.X509, err = x509.ParseCertificate(certPem.Bytes) + handleErr(err, "Error parsing cert: %v\n") + + certs = append(certs, cert) + } + + sort.Sort(certs) + handleErr(tmpl.Execute(os.Stdout, map[string]interface{}{"certs":certs, "now": now}), "Could not execute template: %v\n") +} -- cgit v1.2.3-54-g00ecf