Add certexpiry.
This commit is contained in:
parent
858c9cb4e8
commit
9b18cc18d3
|
@ -11,6 +11,9 @@ Contents:
|
||||||
certchain/ Display the certificate chain from a
|
certchain/ Display the certificate chain from a
|
||||||
TLS connection.
|
TLS connection.
|
||||||
certdump/ Dump certificate information.
|
certdump/ Dump certificate information.
|
||||||
|
certexpiry/ Print a list of certificate subjects and expiry times
|
||||||
|
or warn about certificates expiring within a certain
|
||||||
|
window.
|
||||||
certverify/ Verify a TLS X.509 certificate, optionally printing
|
certverify/ Verify a TLS X.509 certificate, optionally printing
|
||||||
the time to expiry and checking for revocations.
|
the time to expiry and checking for revocations.
|
||||||
clustersh/ Run commands or transfer files across multiple
|
clustersh/ Run commands or transfer files across multiple
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
certexpiry
|
||||||
|
|
||||||
|
Print a list of certificates and their expiry, or only warn about
|
||||||
|
upcoming expiries.
|
||||||
|
|
||||||
|
It takes a list of PEM-encoded certificates, and compares the NotAfter
|
||||||
|
value to the window given by the -t flag (which defaults to 2160 hours,
|
||||||
|
or 90 days). Alternatively, given the -q flag, it will only warn about
|
||||||
|
certificates expiring in the window.
|
||||||
|
|
||||||
|
Example, run on the cfssl-trust[1] CA bundle:
|
||||||
|
|
||||||
|
$ certexpiry -q ca-bundle.crt
|
||||||
|
/GPKIRootCA/C=KR/O=Government of Korea/OU=GPKI/SN=93008982654396041992798201139454296355 expires on 2017-03-15 06:00:04 +0000 UTC (in 1633h0m44.686144136s)
|
||||||
|
/CA DATEV BT 01/C=DE/O=DATEV eG/SN=139288328771231810070797444106717912243 expires on 2017-01-09 13:42:30 +0000 UTC (in 80h43m10.685385355s)
|
||||||
|
/CA DATEV STD 01/C=DE/O=DATEV eG/SN=142389455970744957119921172249094394891 expires on 2017-01-09 13:42:30 +0000 UTC (in 80h43m10.685236793s)
|
||||||
|
/CA DATEV INT 01/C=DE/O=DATEV eG/SN=169035066479776292612803392462688126470 expires on 2017-01-09 13:42:30 +0000 UTC (in 80h43m10.685208087s)
|
||||||
|
$ certexpiry ca-bundle.crt | head -5
|
||||||
|
/http://www.valicert.com//O=ValiCert, Inc./OU=ValiCert Class 3 Policy Validation Authority/L=ValiCert Validation Network/SN=1 expires on 2019-06-26 00:22:33 +0000 UTC (in 21619h22m44.060898709s)
|
||||||
|
/QuoVadis Root CA 2/C=BM/O=QuoVadis Limited/SN=1289 expires on 2031-11-24 18:23:33 +0000 UTC (in 130453h23m44.060878817s)
|
||||||
|
/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority/SN=149843929435818692848040365716851702463 expires on 2028-08-01 23:59:59 +0000 UTC (in 101419h0m10.06087362s)
|
||||||
|
/Equifax Secure Global eBusiness CA-1/C=US/O=Equifax Secure Inc./SN=1 expires on 2020-06-21 04:00:00 +0000 UTC (in 30287h0m11.060869101s)
|
||||||
|
/thawte Primary Root CA/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/SN=69529181992039203566298953787712940909 expires on 2036-07-16 23:59:59 +0000 UTC (in 171163h0m10.060864304s)
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/cloudflare/cfssl/helpers"
|
||||||
|
"github.com/kisom/goutils/die"
|
||||||
|
"github.com/kisom/goutils/lib"
|
||||||
|
)
|
||||||
|
|
||||||
|
var warnOnly bool
|
||||||
|
var leeway = 2160 * time.Hour // three months
|
||||||
|
|
||||||
|
func displayName(name pkix.Name) string {
|
||||||
|
var ns []string
|
||||||
|
|
||||||
|
if name.CommonName != "" {
|
||||||
|
ns = append(ns, name.CommonName)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range name.Country {
|
||||||
|
ns = append(ns, fmt.Sprintf("C=%s", name.Country[i]))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range name.Organization {
|
||||||
|
ns = append(ns, fmt.Sprintf("O=%s", name.Organization[i]))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range name.OrganizationalUnit {
|
||||||
|
ns = append(ns, fmt.Sprintf("OU=%s", name.OrganizationalUnit[i]))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range name.Locality {
|
||||||
|
ns = append(ns, fmt.Sprintf("L=%s", name.Locality[i]))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range name.Province {
|
||||||
|
ns = append(ns, fmt.Sprintf("ST=%s", name.Province[i]))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ns) > 0 {
|
||||||
|
return "/" + strings.Join(ns, "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
die.With("no subject information in root")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func expires(cert *x509.Certificate) time.Duration {
|
||||||
|
return cert.NotAfter.Sub(time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
|
func inDanger(cert *x509.Certificate) bool {
|
||||||
|
return expires(cert) < leeway
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkCert(cert *x509.Certificate) {
|
||||||
|
warn := inDanger(cert)
|
||||||
|
name := displayName(cert.Subject)
|
||||||
|
name = fmt.Sprintf("%s/SN=%s", name, cert.SerialNumber)
|
||||||
|
expiry := expires(cert)
|
||||||
|
if warnOnly {
|
||||||
|
if warn {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s expires on %s (in %s)\n", name, cert.NotAfter, expiry)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s expires on %s (in %s)\n", name, cert.NotAfter, expiry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.BoolVar(&warnOnly, "q", false, "only warn about expiring certs")
|
||||||
|
flag.DurationVar(&leeway, "t", leeway, "warn if certificates are closer than this to expiring")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
for _, file := range flag.Args() {
|
||||||
|
in, err := ioutil.ReadFile(file)
|
||||||
|
if err != nil {
|
||||||
|
lib.Warn(err, "failed to read file")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
certs, err := helpers.ParseCertificatesPEM(in)
|
||||||
|
if err != nil {
|
||||||
|
lib.Warn(err, "while parsing certificates")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cert := range certs {
|
||||||
|
checkCert(cert)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue