diff options
Diffstat (limited to '')
-rw-r--r-- | cmd/x509info/main.go | 150 |
1 files changed, 0 insertions, 150 deletions
diff --git a/cmd/x509info/main.go b/cmd/x509info/main.go deleted file mode 100644 index c425c45..0000000 --- a/cmd/x509info/main.go +++ /dev/null @@ -1,150 +0,0 @@ -package main - -import ( - "crypto/tls" - "crypto/x509" - "flag" - "fmt" - "html/template" - "os" - "time" - - "github.com/fcuny/world/internal/version" -) - -const usage = `Usage: - x509-info [DOMAIN] - x509-info (-f long) [DOMAIN] - -Options: - -f, --format Format the result. Valid values: short, long. Default: short - -i, --insecure Skip the TLS validation. Default: false - -p, --port Specify the port. Default: 443 - -v, --version Print version information - -h, --help Print this message -` - -func main() { - flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s\n", usage) } - - var ( - portFlag int - outputFormatFlag string - insecureFlag bool - versionFlag bool - ) - - flag.IntVar(&portFlag, "port", 443, "Port to check") - flag.IntVar(&portFlag, "p", 443, "Port to check") - flag.StringVar(&outputFormatFlag, "format", "short", "Format the output") - flag.StringVar(&outputFormatFlag, "f", "short", "Format the output") - flag.BoolVar(&insecureFlag, "insecure", false, "Whether to bypass secure flag checks") - flag.BoolVar(&insecureFlag, "i", false, "Whether to bypass secure flag checks") - flag.BoolVar(&versionFlag, "version", false, "Print version information") - flag.BoolVar(&versionFlag, "v", false, "Print version information") - - flag.Parse() - - if versionFlag { - information := version.VersionAndBuildInfo() - fmt.Println(information) - return - } - - if flag.NArg() != 1 { - fmt.Fprintf(os.Stderr, "too many arguments: got %d, expected 1\n", flag.NArg()) - flag.Usage() - os.Exit(1) - } - - domain := flag.Arg(0) - - certs, err := getCertificates(domain, portFlag, insecureFlag) - if err != nil { - fmt.Fprintf(os.Stderr, "error: %v\n", err) - os.Exit(1) - } - - switch outputFormatFlag { - case "long": - printLong(certs) - default: - printShort(certs) - } -} - -func getCertificates(domain string, port int, insecureSkipVerify bool) ([]*x509.Certificate, error) { - conf := &tls.Config{ - InsecureSkipVerify: insecureSkipVerify, - } - - remote := fmt.Sprintf("%s:%d", domain, port) - - conn, err := tls.Dial("tcp", remote, conf) - if err != nil { - return nil, fmt.Errorf("failed to get the certificate for %s: %v", remote, err) - } - - defer conn.Close() - - certs := conn.ConnectionState().PeerCertificates - return certs, nil -} - -func printShort(certs []*x509.Certificate) { - cert := certs[0] - - now := time.Now() - remainingDays := cert.NotAfter.Sub(now) - - if remainingDays > 0 { - fmt.Printf("%s, valid until %s (%d days left)\n", cert.Subject.CommonName, cert.NotAfter.Format(time.RFC1123), int(remainingDays.Hours()/24)) - } else { - fmt.Printf("%s, not valid since %s (expired %d days ago)\n", cert.Subject.CommonName, cert.NotAfter.Format(time.RFC1123), int(remainingDays.Abs().Hours()/24)) - } -} - -const tmplLong = `certificate - version: {{ .Version }} - serial: {{ .SerialNumber }} - subject: {{ .Subject.CommonName }} - issuer: {{ .Issuer.CommonName }} - -validity: - not before: {{ rfc1123 .NotBefore }} - not after: {{ rfc1123 .NotAfter }} - validity days: {{ validFor .NotBefore .NotAfter }} - remaining days: {{ remainingDays .NotAfter }} - -SANs: -{{- range $i, $name := .DNSNames }} - • {{ $name }} -{{- end }} -` - -func printLong(certs []*x509.Certificate) { - funcMap := template.FuncMap{ - "validFor": func(before, after time.Time) int { - validForDays := after.Sub(before) - return int(validForDays.Hours() / 24) - }, - "remainingDays": func(notAfter time.Time) int { - now := time.Now() - remainingDays := notAfter.Sub(now) - return int(remainingDays.Hours() / 24) - }, - "rfc1123": func(date time.Time) string { - return date.Format(time.RFC1123) - }, - } - - tmpl, err := template.New("tmpl").Funcs(funcMap).Parse(tmplLong) - if err != nil { - panic(err) - } - - err = tmpl.Execute(os.Stdout, certs[0]) - if err != nil { - panic(err) - } -} |