135 lines
2.5 KiB
Go
135 lines
2.5 KiB
Go
|
|
package main
|
|
|
|
import (
|
|
"os"
|
|
"log"
|
|
"flag"
|
|
"time"
|
|
"math"
|
|
"strings"
|
|
"crypto/tls"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
)
|
|
|
|
type zzz struct{
|
|
Data map[string]any
|
|
}
|
|
|
|
func pp(out *zzz, n string, v any) {
|
|
b, ok := v.([]byte)
|
|
if ok {
|
|
out.Data[n] = hex.EncodeToString(b)
|
|
} else {
|
|
out.Data[n] = v
|
|
}
|
|
|
|
if false {
|
|
log.Println(n, ":", out.Data[n])
|
|
}
|
|
}
|
|
|
|
func Proc(ipport string, arg... int) ([]map[string]interface{}, error) {
|
|
var err error
|
|
now := time.Now()
|
|
ret := make([]map[string]interface{}, 0)
|
|
|
|
conf := &tls.Config{
|
|
InsecureSkipVerify: true,
|
|
}
|
|
|
|
var ccnt int = 5
|
|
if len(arg) > 0 && arg[0] > 0 {
|
|
ccnt = arg[0]
|
|
}
|
|
|
|
// log.Println("Connect", ipport, "max-count", ccnt)
|
|
conn, err := tls.Dial("tcp", ipport, conf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
cstat := conn.ConnectionState()
|
|
certs := cstat.PeerCertificates
|
|
|
|
for i, cert := range certs {
|
|
if i >= ccnt {
|
|
break
|
|
}
|
|
|
|
var out zzz = zzz{
|
|
Data: make(map[string]any),
|
|
}
|
|
|
|
DnsList := make([]string, 0)
|
|
|
|
for _, dns := range cert.DNSNames {
|
|
DnsList = append(DnsList, dns)
|
|
}
|
|
|
|
pp(&out, "Subject" , cert.Subject.String() )
|
|
pp(&out, "SerialNumber" , cert.SerialNumber.Bytes() )
|
|
pp(&out, "AuthorityKeyId" , cert.AuthorityKeyId )
|
|
pp(&out, "IssuerName" , cert.Issuer.String() )
|
|
pp(&out, "IssuerCommonName" , cert.Issuer.CommonName )
|
|
pp(&out, "ExpiryDateTime" , cert.NotAfter.Format(time.DateTime) )
|
|
pp(&out, "ExpiryDeltaDay" , math.Floor(cert.NotAfter.Sub( now ).Hours()/24) )
|
|
pp(&out, "DnsList" , DnsList )
|
|
// log.Println(out)
|
|
|
|
ret = append(ret, out.Data)
|
|
|
|
// log.Println("End")
|
|
}
|
|
|
|
return ret, nil
|
|
}
|
|
|
|
func main() {
|
|
addr := flag.String("a", "google.com:443", "Checked host")
|
|
ccnt := flag.Int("c", 1, "Max count certificates chain")
|
|
mday := flag.Float64("m", 50, "Min day's cert valid, or return 2")
|
|
|
|
flag.Parse()
|
|
|
|
tail := flag.Args()
|
|
|
|
for {
|
|
if len(tail) == 0 {
|
|
break
|
|
}
|
|
|
|
if len(tail) == 1 {
|
|
addr = &tail[0]
|
|
break
|
|
}
|
|
|
|
flag.PrintDefaults()
|
|
os.Exit(1)
|
|
}
|
|
|
|
var ipport string = *addr
|
|
aipp := strings.Split(*addr, ":")
|
|
if len(aipp) < 2 {
|
|
ipport = aipp[0] + ":443"
|
|
}
|
|
|
|
list, err := Proc(ipport, *ccnt)
|
|
if err != nil {
|
|
log.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
jsonResp, _ := json.MarshalIndent(list, "", "\t")
|
|
log.Println(string(jsonResp))
|
|
|
|
if list[0]["ExpiryDeltaDay"].(float64) < *mday {
|
|
os.Exit(2)
|
|
}
|
|
|
|
os.Exit(0)
|
|
}
|