From e70b8fb7228f0b90c8c9a095af9b6a82c762eedf Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 10 Oct 2016 22:30:10 -0400 Subject: initial commit --- .gitignore | 3 ++ Makefile | 16 +++++++ domains.txt | 4 ++ getcerts | 28 ++++++++++++ pem2html.go | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 193 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 domains.txt create mode 100755 getcerts create mode 100644 pem2html.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98b607b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +certs.* +pem2html +NET-* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..432518b --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +all: certs.html + +pem2html: %: %.go + go build $< + +certs.pem: getcerts domains.txt NET-crt.sh + ./getcerts $$(cat domains.txt) > $@ + +certs.html: %.html: %.pem pem2html + ./pem2html < $< > $@ + +NET-%: + touch $@ + +.DELETE_ON_ERROR: +.SECONDARY: diff --git a/domains.txt b/domains.txt new file mode 100644 index 0000000..390a92e --- /dev/null +++ b/domains.txt @@ -0,0 +1,4 @@ +parabola.nu +parabolagnulinux.org +lukeshu.com +team4272.com diff --git a/getcerts b/getcerts new file mode 100755 index 0000000..0191e2e --- /dev/null +++ b/getcerts @@ -0,0 +1,28 @@ +#!/usr/bin/env ruby +require 'nokogiri' +require 'open-uri' + +certs = {} +ARGV.each do |domain| + [ domain, "%.#{domain}" ].each do |pattern| + Nokogiri::XML(open("https://crt.sh/atom?identity=#{pattern}&exclude=expired")).css('feed > entry').each do |entry| + url = entry.css('id').first.text.split("#").first + + updated = entry.css('updated').first.text + + html = Nokogiri::HTML(entry.css('summary').first.text) + html.css('br').each{|br| br.replace("\n")} + pem = html.css('div').first.text + + lines = pem.split("\n") + lines.insert(1, "X-Crt-Sh-Url: #{url}", "X-Crt-Sh-Updated: #{updated}") + pem = lines.join("\n")+"\n" + + certs[url] = pem + end + end +end + +certs.each do |url, pem| + print pem +end diff --git a/pem2html.go b/pem2html.go new file mode 100644 index 0000000..be0405d --- /dev/null +++ b/pem2html.go @@ -0,0 +1,142 @@ +package main + +import ( + "crypto/x509" + "encoding/pem" + "fmt" + "io/ioutil" + "os" + "time" + "html/template" + "sort" +) + +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").Parse(` + + + + CT log + + + + + + + + + + + +{{range $cert := .}} + + + + + + + +{{end}} +
LoggedNotBeforeNotAfterSubject.CNIssuer.O
{{$cert.Updated.Local.Format "2006-01-02 15:04:05"}}{{$cert.X509.NotBefore.Local.Format "2006-01-02"}}{{$cert.X509.NotAfter.Local.Format "2006-01-02"}}{{$cert.X509.Subject.CommonName}}{{$cert.X509.Issuer.Organization}}
+ +`)) + +type Cert struct { + Url string + Updated time.Time + 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].Updated.UTC().After(l[j].Updated.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.Url, ok = certPem.Headers["X-Crt-Sh-Url"] + handleBool(ok, "Did not get X-Crt-Sh-Url\n") + + str, ok := certPem.Headers["X-Crt-Sh-Updated"] + handleBool(ok, "Did not get X-Crt-Sh-Updated\n") + cert.Updated, err = time.Parse("2006-01-02T15:04:05Z", str) + handleErr(err, "Could not parse updated time") + + cert.X509, err = x509.ParseCertificate(certPem.Bytes) + handleErr(err, "Error parsing cert: %v\n") + + certs = append(certs, cert) + } + + sort.Sort(certs) + tmpl.Execute(os.Stdout, certs) +} -- cgit v1.1-4-g5e80