Ad expiry/revocation checking to certverify.

This commit is contained in:
Kyle Isom 2016-01-14 23:08:12 -08:00
parent 0851b241cd
commit 7944be7139
4 changed files with 81 additions and 18 deletions

View File

@ -11,7 +11,8 @@ Contents:
certchain/ Display the certificate chain from a
TLS connection.
certdump/ Dump certificate information.
certverify/ Verify a TLS X.509 certificate.
certverify/ Verify a TLS X.509 certificate, optionally printing
the time to expiry and checking for revocations.
clustersh/ Run commands or transfer files across multiple
servers via SSH.
csrpubdump/ Dump the public key from an X.509

View File

@ -6,7 +6,7 @@ It does not check for revocations (though this is a planned feature),
and it does not check the hostname (it deals only in certificate files).
[ Usage ]
certverify [-ca bundle] [-f] [-i bundle] [-v] certificate
certverify [-ca bundle] [-f] [-i bundle] [-r] [-v] certificate
[ Flags ]
-ca bundle Specify the path to the CA certificate bundle
@ -15,6 +15,7 @@ and it does not check the hostname (it deals only in certificate files).
any intermediates bundled with the certificate.
-i bundle Specify the path to the intermediate certificate
bundle to use.
-r Print revocation and expiry information.
-v Print extra information during the program's run.
If the certificate validates, also prints 'OK'.
@ -34,3 +35,11 @@ certificate bundle, and seeing a mismatch:
$ echo $?
1
Using the stealchain (../stealchain) util, print revocation and expiry
information for google.com:
$ stealchain google.com
[+] wrote google.com.pem.
$ certverify -r google.com.pem
certificate expires in 53d.

View File

@ -6,19 +6,38 @@ import (
"fmt"
"io/ioutil"
"os"
"time"
"github.com/cloudflare/cfssl/helpers"
"github.com/cloudflare/cfssl/revoke"
"github.com/kisom/die"
"github.com/kisom/goutils/lib"
)
func printRevocation(cert *x509.Certificate) {
remaining := cert.NotAfter.Sub(time.Now())
fmt.Printf("certificate expires in %s.\n", lib.Duration(remaining))
revoked, ok := revoke.VerifyCertificate(cert)
if !ok {
fmt.Fprintf(os.Stderr, "[!] the revocation check failed (failed to determine whether certificate\nwas revoked)")
return
}
if revoked {
fmt.Fprintf(os.Stderr, "[!] the certificate has been revoked\n")
return
}
}
func main() {
var caFile, intFile string
var forceIntermediateBundle, verbose bool
var forceIntermediateBundle, revexp, verbose bool
flag.StringVar(&caFile, "ca", "", "CA certificate `bundle`")
flag.StringVar(&intFile, "i", "", "intermediate `bundle`")
flag.BoolVar(&forceIntermediateBundle, "f", false,
"force the use of the intermediate bundle, ignoring any intermediates bundled with certificate")
flag.BoolVar(&revexp, "r", false, "print revocation and expiry information")
flag.BoolVar(&verbose, "v", false, "verbose")
flag.Parse()
@ -86,4 +105,8 @@ func main() {
if verbose {
fmt.Println("OK")
}
if revexp {
printRevocation(cert)
}
}

View File

@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"time"
)
var progname = filepath.Base(os.Args[0])
@ -81,3 +82,32 @@ func Itoa(i int, wid int) string {
b[bp] = byte('0' + i)
return string(b[bp:])
}
var (
dayDuration = 24 * time.Hour
yearDuration = (365 * dayDuration) + (6 * time.Hour)
)
func Duration(d time.Duration) string {
var s string
if d >= yearDuration {
years := d / yearDuration
s += fmt.Sprintf("%dy", years)
d -= (years * yearDuration)
}
if d >= dayDuration {
days := d / dayDuration
s += fmt.Sprintf("%dd", days)
}
if s != "" {
return s
}
d %= 1 * time.Second
hours := d / time.Hour
d -= (hours * time.Hour)
s += fmt.Sprintf("%dh%s", hours, d)
return s
}