Add certverify utility.

This commit is contained in:
Kyle Isom 2016-01-14 17:29:55 -08:00
parent 215d03bdb1
commit 8fd2e76939
3 changed files with 126 additions and 0 deletions

View File

@ -11,6 +11,7 @@ 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.
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

36
cmd/certverify/README Normal file
View File

@ -0,0 +1,36 @@
certverify
This is a small utility to verify a TLS X.509 certificate. It returns
0 on success; on error, it prints the error and returns with exit code 1.
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
[ Flags ]
-ca bundle Specify the path to the CA certificate bundle
to use.
-f Force the use of the intermediate bundle, ignoring
any intermediates bundled with the certificate.
-i bundle Specify the path to the intermediate certificate
bundle to use.
-v Print extra information during the program's run.
If the certificate validates, also prints 'OK'.
[ Examples ]
To verify the 'www.pem' certificate against the system roots:
$ certverify www.pem
$ echo $?
0
To verify the 'www.pem' certificate against the 'ca-cert.pem' CA
certificate bundle, and seeing a mismatch:
$ certverify -ca ca-cert.pem www.pem
Verification failed: x509: certificate signed by unknown authority
$ echo $?
1

89
cmd/certverify/main.go Normal file
View File

@ -0,0 +1,89 @@
package main
import (
"crypto/x509"
"flag"
"fmt"
"io/ioutil"
"os"
"github.com/cloudflare/cfssl/helpers"
"github.com/kisom/die"
"github.com/kisom/goutils/lib"
)
func main() {
var caFile, intFile string
var forceIntermediateBundle, 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(&verbose, "v", false, "verbose")
flag.Parse()
var roots *x509.CertPool
if caFile != "" {
var err error
if verbose {
fmt.Println("[+] loading root certificates from", caFile)
}
roots, err = helpers.LoadPEMCertPool(caFile)
die.If(err)
}
var ints *x509.CertPool
if intFile != "" {
var err error
if verbose {
fmt.Println("[+] loading intermediate certificates from", intFile)
}
ints, err = helpers.LoadPEMCertPool(caFile)
die.If(err)
} else {
ints = x509.NewCertPool()
}
if flag.NArg() != 1 {
fmt.Fprintf(os.Stderr, "Usage: %s [-ca bundle] [-i bundle] cert",
lib.ProgName())
}
fileData, err := ioutil.ReadFile(flag.Arg(0))
die.If(err)
chain, err := helpers.ParseCertificatesPEM(fileData)
die.If(err)
if verbose {
fmt.Printf("[+] %s has %d certificates\n", flag.Arg(0), len(chain))
}
cert := chain[0]
if len(chain) > 1 {
if !forceIntermediateBundle {
for _, intermediate := range chain[1:] {
if verbose {
fmt.Printf("[+] adding intermediate with SKI %x\n", intermediate.SubjectKeyId)
}
ints.AddCert(intermediate)
}
}
}
opts := x509.VerifyOptions{
Intermediates: ints,
Roots: roots,
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
}
_, err = cert.Verify(opts)
if err != nil {
fmt.Fprintf(os.Stderr, "Verification failed: %v\n", err)
os.Exit(1)
}
if verbose {
fmt.Println("OK")
}
}