ssl-certs-checker/utils.go

127 lines
2.3 KiB
Go
Raw Normal View History

2020-02-22 15:39:16 +00:00
package main
import (
"crypto/tls"
"crypto/x509"
2020-03-15 14:07:50 +00:00
"fmt"
2020-04-02 19:41:41 +01:00
"io/ioutil"
2020-02-22 15:39:16 +00:00
"net"
"os"
"strconv"
"strings"
2020-05-10 09:39:43 +01:00
"sync"
"time"
2020-02-22 15:39:16 +00:00
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
2020-04-02 19:41:41 +01:00
"gopkg.in/yaml.v2"
2020-02-22 15:39:16 +00:00
)
2020-04-02 19:41:41 +01:00
type Config struct {
Hosts []string `yaml:"hosts"`
}
func readConfig(config string) Config {
c := Config{}
y, err := ioutil.ReadFile(config)
if err != nil {
fmt.Printf("fatal: %s\n", err)
os.Exit(1)
}
err = yaml.Unmarshal(y, &c)
if err != nil {
fmt.Printf("fatal: %s\n", err)
os.Exit(1)
}
return c
}
func getPeerCertificates(h string, port int, timeout int) ([]*x509.Certificate, error) {
2020-02-22 15:39:16 +00:00
conn, err := tls.DialWithDialer(
&net.Dialer{
Timeout: time.Duration(timeout) * time.Second,
2020-02-22 15:39:16 +00:00
},
protocol,
h+":"+strconv.Itoa(port),
&tls.Config{
ServerName: h,
})
if err != nil {
return nil, err
}
defer conn.Close()
if err := conn.Handshake(); err != nil {
return nil, err
}
return conn.ConnectionState().PeerCertificates, nil
}
func getCells(t table.Writer, host string, port, timeout int, wg *sync.WaitGroup) {
2020-05-10 09:39:43 +01:00
defer wg.Done()
certs, err := getPeerCertificates(host, port, timeout)
2020-02-22 15:39:16 +00:00
if err != nil {
2020-03-15 14:07:50 +00:00
fmt.Printf("err: %s\n", err)
2020-02-22 15:39:16 +00:00
return // skip if target host invalid
}
for _, c := range certs {
if c.IsCA {
continue
}
2020-03-15 14:07:50 +00:00
t.AppendRows([]table.Row{{
host + ":" + strconv.Itoa(port),
(*c).Subject.CommonName,
strings.Join((*c).DNSNames, "\n"),
(*c).NotBefore,
(*c).NotAfter,
(*c).PublicKeyAlgorithm.String(),
2020-03-15 14:07:50 +00:00
(*c).Issuer.CommonName,
}})
2020-02-22 15:39:16 +00:00
}
}
func prettyPrintCertsInfo(config string, timeout int) {
2020-04-02 19:41:41 +01:00
rc := readConfig(config)
if len(rc.Hosts) <= 0 {
fmt.Printf("key not found, or empty input\n")
return
}
2020-02-22 15:39:16 +00:00
t := table.NewWriter()
t.SetOutputMirror(os.Stdout)
t.AppendHeader(table.Row{
"Host",
"Common Name",
2020-03-04 02:32:34 +00:00
"DNS Names",
2020-02-22 15:39:16 +00:00
"Not Before",
"Not After",
"PublicKeyAlgorithm",
2020-02-22 15:39:16 +00:00
"Issuer",
})
2020-05-10 09:39:43 +01:00
var wg sync.WaitGroup
2020-04-02 19:41:41 +01:00
for _, target := range rc.Hosts {
2020-03-15 14:07:50 +00:00
p := defaultPort
ts := strings.Split(target, ":")
if len(ts) == 2 {
tp, err := strconv.Atoi(ts[1])
if err != nil {
2020-04-02 19:41:41 +01:00
fmt.Errorf("err: invalid port [%s], assume target port is 443\n", target)
2020-03-15 14:07:50 +00:00
} else {
p = tp
}
}
2020-05-10 09:39:43 +01:00
wg.Add(1)
2020-03-15 14:07:50 +00:00
go getCells(t, ts[0], p, timeout, &wg)
2020-02-22 15:39:16 +00:00
}
2020-05-10 09:39:43 +01:00
wg.Wait()
2020-02-22 15:39:16 +00:00
t.Style().Format.Header = text.FormatDefault
t.Render()
}