Add certverify utility.
This commit is contained in:
parent
215d03bdb1
commit
8fd2e76939
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue