Ad expiry/revocation checking to certverify.
This commit is contained in:
parent
0851b241cd
commit
7944be7139
|
@ -11,7 +11,8 @@ 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.
|
||||||
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
|
clustersh/ Run commands or transfer files across multiple
|
||||||
servers via SSH.
|
servers via SSH.
|
||||||
csrpubdump/ Dump the public key from an X.509
|
csrpubdump/ Dump the public key from an X.509
|
||||||
|
|
|
@ -6,31 +6,40 @@ 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).
|
and it does not check the hostname (it deals only in certificate files).
|
||||||
|
|
||||||
[ Usage ]
|
[ Usage ]
|
||||||
certverify [-ca bundle] [-f] [-i bundle] [-v] certificate
|
certverify [-ca bundle] [-f] [-i bundle] [-r] [-v] certificate
|
||||||
|
|
||||||
[ Flags ]
|
[ Flags ]
|
||||||
-ca bundle Specify the path to the CA certificate bundle
|
-ca bundle Specify the path to the CA certificate bundle
|
||||||
to use.
|
to use.
|
||||||
-f Force the use of the intermediate bundle, ignoring
|
-f Force the use of the intermediate bundle, ignoring
|
||||||
any intermediates bundled with the certificate.
|
any intermediates bundled with the certificate.
|
||||||
-i bundle Specify the path to the intermediate certificate
|
-i bundle Specify the path to the intermediate certificate
|
||||||
bundle to use.
|
bundle to use.
|
||||||
-v Print extra information during the program's run.
|
-r Print revocation and expiry information.
|
||||||
If the certificate validates, also prints 'OK'.
|
-v Print extra information during the program's run.
|
||||||
|
If the certificate validates, also prints 'OK'.
|
||||||
|
|
||||||
[ Examples ]
|
[ Examples ]
|
||||||
|
|
||||||
To verify the 'www.pem' certificate against the system roots:
|
To verify the 'www.pem' certificate against the system roots:
|
||||||
|
|
||||||
$ certverify www.pem
|
$ certverify www.pem
|
||||||
$ echo $?
|
$ echo $?
|
||||||
0
|
0
|
||||||
|
|
||||||
To verify the 'www.pem' certificate against the 'ca-cert.pem' CA
|
To verify the 'www.pem' certificate against the 'ca-cert.pem' CA
|
||||||
certificate bundle, and seeing a mismatch:
|
certificate bundle, and seeing a mismatch:
|
||||||
|
|
||||||
$ certverify -ca ca-cert.pem www.pem
|
$ certverify -ca ca-cert.pem www.pem
|
||||||
Verification failed: x509: certificate signed by unknown authority
|
Verification failed: x509: certificate signed by unknown authority
|
||||||
$ echo $?
|
$ echo $?
|
||||||
1
|
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.
|
||||||
|
|
||||||
|
|
|
@ -6,19 +6,38 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/cloudflare/cfssl/helpers"
|
"github.com/cloudflare/cfssl/helpers"
|
||||||
|
"github.com/cloudflare/cfssl/revoke"
|
||||||
"github.com/kisom/die"
|
"github.com/kisom/die"
|
||||||
"github.com/kisom/goutils/lib"
|
"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() {
|
func main() {
|
||||||
var caFile, intFile string
|
var caFile, intFile string
|
||||||
var forceIntermediateBundle, verbose bool
|
var forceIntermediateBundle, revexp, verbose bool
|
||||||
flag.StringVar(&caFile, "ca", "", "CA certificate `bundle`")
|
flag.StringVar(&caFile, "ca", "", "CA certificate `bundle`")
|
||||||
flag.StringVar(&intFile, "i", "", "intermediate `bundle`")
|
flag.StringVar(&intFile, "i", "", "intermediate `bundle`")
|
||||||
flag.BoolVar(&forceIntermediateBundle, "f", false,
|
flag.BoolVar(&forceIntermediateBundle, "f", false,
|
||||||
"force the use of the intermediate bundle, ignoring any intermediates bundled with certificate")
|
"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.BoolVar(&verbose, "v", false, "verbose")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
@ -86,4 +105,8 @@ func main() {
|
||||||
if verbose {
|
if verbose {
|
||||||
fmt.Println("OK")
|
fmt.Println("OK")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if revexp {
|
||||||
|
printRevocation(cert)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
30
lib/lib.go
30
lib/lib.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var progname = filepath.Base(os.Args[0])
|
var progname = filepath.Base(os.Args[0])
|
||||||
|
@ -81,3 +82,32 @@ func Itoa(i int, wid int) string {
|
||||||
b[bp] = byte('0' + i)
|
b[bp] = byte('0' + i)
|
||||||
return string(b[bp:])
|
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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue