summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tls-getcerts.go22
-rw-r--r--tls-pem2html.go36
2 files changed, 47 insertions, 11 deletions
diff --git a/tls-getcerts.go b/tls-getcerts.go
index ba951c9..49e15a2 100644
--- a/tls-getcerts.go
+++ b/tls-getcerts.go
@@ -5,16 +5,33 @@ import (
"crypto/x509"
"encoding/pem"
"fmt"
+ "net"
"os"
)
func getcert(socket string) (*x509.Certificate, error){
+ host, _, err := net.SplitHostPort(socket)
+ if err != nil {
+ return nil, err
+ }
conn, err := tls.Dial("tcp", socket, &tls.Config{InsecureSkipVerify: true})
if err != nil {
return nil, err
}
defer conn.Close()
- return conn.ConnectionState().PeerCertificates[0], nil
+ cstate := conn.ConnectionState()
+
+ opts := x509.VerifyOptions{
+ DNSName: host,
+ Intermediates: x509.NewCertPool(),
+ }
+ for _, cert := range cstate.PeerCertificates[1:] {
+ opts.Intermediates.AddCert(cert)
+ }
+
+ cert := cstate.PeerCertificates[0]
+ _, err = cert.Verify(opts)
+ return cert, err
}
func main() {
@@ -29,6 +46,9 @@ func main() {
Headers: map[string]string{"X-Socket": socket},
Bytes: cert.Raw,
}
+ if err != nil {
+ block.Headers["X-Error"] = err.Error()
+ }
pem.Encode(os.Stdout, &block)
}
}
diff --git a/tls-pem2html.go b/tls-pem2html.go
index efefd68..a68a58a 100644
--- a/tls-pem2html.go
+++ b/tls-pem2html.go
@@ -33,7 +33,7 @@ var tmpl = template.Must(template.New("pem2html").
<html lang="en">
<head>
<meta charset="utf-8">
- <title>CT log</title>
+ <title>Live Certs</title>
<style>
html {
height: 100%;
@@ -63,7 +63,10 @@ var tmpl = template.Must(template.New("pem2html").
td {
background-color: #F3F3F3;
}
- tr:hover td {
+ tr.invalid td {
+ background-color: #F30000 !important;
+ }
+ tr:hover td, tr.invalid:hover td {
background-color: #AAAAF3 !important;
}
td a {
@@ -73,9 +76,6 @@ var tmpl = template.Must(template.New("pem2html").
height: 100%;
color: black;
}
- tr.expired td {
- background-color: #F30000;
- }
</style>
<script src="sorttable.js"></script>
</head>
@@ -91,11 +91,11 @@ var tmpl = template.Must(template.New("pem2html").
<th>Socket</th>
</tr>
{{range $cert := .certs}}
- <tr>
- <td style="background-color: ${$cert.X509.NotBefore | green}}">{{$cert.X509.NotBefore.Local.Format "2006-01-02"}}</td>
- <td style="background-color: {{$cert.X509.NotAfter | red}}" >{{$cert.X509.NotAfter.Local.Format "2006-01-02"}}</td>
- <td>{{$cert.X509.Subject.CommonName | html}}</td>
- <td>{{$cert.Socket | html}}</td>
+ <tr class="{{$cert.Class}}">
+ <td style="background-color: {{$cert.X509.NotBefore | green}}"><a href="{{$cert.Link}}" title="{{$cert.Error}}">{{$cert.X509.NotBefore.Local.Format "2006-01-02"}}</a></td>
+ <td style="background-color: {{$cert.X509.NotAfter | red }}"><a href="{{$cert.Link}}" title="{{$cert.Error}}">{{$cert.X509.NotAfter.Local.Format "2006-01-02"}}</a></td>
+ <td><a href="{{$cert.Link}}" title="{{$cert.Error}}">{{$cert.X509.Subject.CommonName | html}}</a></td>
+ <td><a href="{{$cert.Link}}" title="{{$cert.Error}}">{{$cert.Socket | html}}</a></td>
</tr>
{{end}}
</table>
@@ -153,9 +153,23 @@ func red(t time.Time) string {
type Cert struct {
Socket string
+ Error string
X509 *x509.Certificate
}
+func (cert Cert) Link() string {
+ return fmt.Sprintf("https://crt.sh/?serial=%036x", cert.X509.SerialNumber)
+}
+
+func (cert Cert) Class() string {
+ if cert.Error == "" {
+ return ""
+ } else {
+ return "invalid"
+ }
+}
+
+
type Certs []Cert
// Len is the number of elements in the collection.
@@ -191,6 +205,8 @@ func main() {
cert.Socket, ok = certPem.Headers["X-Socket"]
handleBool(ok, "Did not get X-Socket\n")
+ cert.Error, ok = certPem.Headers["X-Error"]
+
cert.X509, err = x509.ParseCertificate(certPem.Bytes)
handleErr(err, "Error parsing cert: %v\n")