Certificate check from Go
As the web moves more and more to HTTPS and ehanced security (such as HSTS) keeping your certificates updated and valid becomes more and more important.
I’m toying with an idea of building a small webapp to monitor my small portfolio of certificates and warn me if a certificate is due to expire. As part of this, I’m slowly patching pieces together in Go and one of the small useful outcomes is a small (compilable to bin) script which prints the basic certificate details of a given domain.
package main
import (
"bytes"
"crypto/tls"
"crypto/x509" // https://golang.org/pkg/crypto/x509/
"encoding/pem"
"fmt"
"os"
)
func GetCertificatesPEM(address string) (string, error) {
conn, err := tls.Dial("tcp", address, &tls.Config{
InsecureSkipVerify: true,
})
if err != nil {
return "", err
}
defer conn.Close()
var b bytes.Buffer
for _, cert := range conn.ConnectionState().PeerCertificates {
err := pem.Encode(&b, &pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
})
if err != nil {
return "", err
}
}
return b.String(), nil
}
func main() {
domainArg := os.Args[1]
certs, err := GetCertificatesPEM(domainArg + ":443")
if err != nil {
fmt.Print("err %v\n", err.Error())
}
block, _ := pem.Decode([]byte(certs))
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
panic("failed to parse certificate: " + err.Error())
}
//fmt.Printf("len %v : %v\n", len(certs), certs)
fmt.Println(cert.Subject)
fmt.Println(cert.Issuer)
fmt.Println(cert.NotAfter)
Script Output
Once run the output could look something like this:
$ go run checkCertificate.go netfactory.dk
CN=netfactory.dk
CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US
2020-08-12 04:47:13 +0000 UTC
You can (also) find the above source code in my GoLang snippets Library on Github.