File: main.go

package info (click to toggle)
golang-github-kisom-goutils 0.0~git20161101.0.858c9cb-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 384 kB
  • ctags: 331
  • sloc: makefile: 6
file content (112 lines) | stat: -rw-r--r-- 2,567 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package main

import (
	"crypto/x509"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"time"

	"github.com/cloudflare/cfssl/helpers"
	"github.com/cloudflare/cfssl/revoke"
	"github.com/kisom/goutils/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, 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()

	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")
	}

	if revexp {
		printRevocation(cert)
	}
}