Skip to content

Instantly share code, notes, and snippets.

@predakanga
Created September 10, 2015 13:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save predakanga/0df36267ab4e56fe88c5 to your computer and use it in GitHub Desktop.
Save predakanga/0df36267ab4e56fe88c5 to your computer and use it in GitHub Desktop.
package main
import (
"crypto/x509"
"crypto/tls"
"encoding/pem"
"os"
"io/ioutil"
"github.com/jessevdk/go-flags"
"time"
"fmt"
)
type Options struct {
InputFile string `short:"i" description:"File to process (PEM)" value-name:"cert.pem"`
Args struct {
Address string `positional-arg-name:"address" description:"Address of server to process"`
} `positional-args:"yes"`
}
func main() {
var opts Options
parser := flags.NewParser(&opts, flags.Default)
ret, err := parser.Parse()
if err != nil {
typ := err.(*flags.Error).Type
if typ != flags.ErrHelp {
fmt.Fprintln(os.Stderr, "Failed to parse arguments:", err)
os.Exit(1)
}
os.Exit(0)
}
if len(ret) != 0 || (opts.InputFile == "" && opts.Args.Address == "") || (opts.InputFile != "" && opts.Args.Address != "") {
parser.WriteHelp(os.Stdout)
os.Exit(1)
}
var result int
if opts.InputFile != "" {
result = verify_file(opts.InputFile)
} else {
result = verify_host(opts.Args.Address)
}
os.Exit(result)
}
func verify_cert(cert *(x509.Certificate)) int {
fmt.Println("Checking certificate for", cert.Subject.CommonName)
if cert.NotAfter.Before(time.Now()) {
fmt.Println("Certificate expired on", cert.NotAfter.Format("Jan 2 2006"))
return 2
}
if cert.NotAfter.Before(time.Now().AddDate(0, 0, 7)) {
fmt.Println("Certificate will expire on", cert.NotAfter.Format("Jan 2 2006"))
return 1
}
fmt.Println("Certificate looks good, will expire on", cert.NotAfter.Format("Jan 2 2006"))
return 0
}
func verify_file(file string) int {
pem_bytes, err := ioutil.ReadFile(file)
if err != nil {
fmt.Fprintln(os.Stderr, "Failed to read file:", err)
return 1
}
first_block, _ := pem.Decode(pem_bytes)
if first_block == nil {
fmt.Fprintln(os.Stderr, "PEM encoded certificate expected, was not found")
return 1
}
cert, err := x509.ParseCertificate(first_block.Bytes)
if err != nil {
fmt.Fprintln(os.Stderr, "Parsing certificated failed:", err)
return 1
}
return verify_cert(cert)
}
func verify_host(addr string) int {
opts := tls.Config{ InsecureSkipVerify: true }
conn, err := tls.Dial("tcp", addr, &opts)
if err != nil {
fmt.Fprintln(os.Stderr, "Connection failed:", err)
return 1
}
defer conn.Close()
state := conn.ConnectionState()
if len(state.PeerCertificates) < 1 {
fmt.Fprintln(os.Stderr, "No peer certificate was received")
return 1
}
return verify_cert(state.PeerCertificates[0])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment