package main import ( "crypto/x509" "encoding/pem" "fmt" "io/ioutil" "os" "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 readTLS(filename string) (map[string]*x509.Certificate, error) { file, err := os.Open(filename) if err != nil { return nil, err } data, err := ioutil.ReadAll(file) if err != nil { return nil, err } ret := make(map[string]*x509.Certificate) for len(data) > 0 { var certPem *pem.Block certPem, data = pem.Decode(data) certX509, err := x509.ParseCertificate(certPem.Bytes) if err != nil { return nil, err } ret[certX509.Subject.CommonName] = certX509 } return ret, nil } func readCrtSh(filename string, hosts []string) (map[string]*x509.Certificate, error) { file, err := os.Open(filename) if err != nil { return nil, err } data, err := ioutil.ReadAll(file) if err != nil { return nil, err } ret := make(map[string]*x509.Certificate) for len(data) > 0 { var certPem *pem.Block certPem, data = pem.Decode(data) certX509, err := x509.ParseCertificate(certPem.Bytes) if err != nil { return nil, err } for _, host := range hosts { if certX509.VerifyHostname(host) == nil { if old, haveold := ret[host]; !haveold || certX509.NotBefore.After(old.NotBefore) { ret[host] = certX509 } } } } return ret, nil } func keys(m map[string]*x509.Certificate) []string { ret := make([]string, len(m)) i := 0 for k := range m { ret[i] = k i++ } sort.Strings(ret) return ret } func main() { if len(os.Args) != 3 { fmt.Fprintf(os.Stderr, "Usage: %s TLS-file crt.sh-file\n", os.Args[0]) } certsTLS, err := readTLS(os.Args[1]) handleErr(err, "Could load TLS file: %v\n") hostsTLS := keys(certsTLS) 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)) for _, host := range hostsTLS { certTLS := certsTLS[host] certCrtSh, okCrtSh := certsCrtSh[host] if !okCrtSh { fmt.Printf("-%s %s\n", host, certTLS.NotBefore.Format("2006-01-02 15:04:05 MST(-07)")) } else if !certTLS.Equal(certCrtSh) { fmt.Printf("-%s %s\n", host, certTLS.NotBefore.Format("2006-01-02 15:04:05 MST(-07)")) fmt.Printf("+%s %s\n", host, certCrtSh.NotBefore.Format("2006-01-02 15:04:05 MST(-07)")) } else { fmt.Printf(" %s %s\n", host, certTLS.NotBefore.Format("2006-01-02 15:04:05 MST(-07)")) } } }