cloudflare/cfssl_trust

Public

mirrored from https://github.com/cloudflare/cfssl_trustAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
trust-store-2023.3.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

cli/expiring.go

122lines · modecode

1package cli
2
3import (
4 "database/sql"
5 "fmt"
6 "math/big"
7 "os"
8 "time"
9
10 "github.com/cloudflare/cfssl_trust/common"
11 "github.com/cloudflare/cfssl_trust/model/certdb"
12 "github.com/spf13/cobra"
13 "github.com/spf13/viper"
14)
15
16var expiringCmd = &cobra.Command{
17 Use: "expiring",
18 Short: "Show expiring (and revoked) certificates.",
19 Long: `Show certificates that will not be included in the next release, whether
20due to certificate expiry or revocation.`,
21 Run: expiring,
22}
23
24func init() {
25 rootCmd.AddCommand(expiringCmd)
26}
27
28func showExpiredCert(cert *certdb.Certificate, reason string) {
29 serial := big.NewInt(0)
30 serial.SetBytes(cert.Serial)
31 fmt.Printf("%s (SKI=%s, serial=%s, subject='%s')\n", reason, cert.SKI, serial, common.NameToString(cert.X509().Subject))
32}
33
34func scanBundleForExpirations(db *sql.DB, window time.Duration) (expired int, revoked int, err error) {
35 tx, err := db.Begin()
36 if err != nil {
37 return expired, revoked, err
38 }
39 defer tx.Rollback()
40
41 rel := &certdb.Release{
42 Bundle: bundle,
43 Version: bundleRelease,
44 }
45
46 err = rel.Select(tx)
47 if err != nil {
48 return expired, revoked, err
49 }
50
51 certs, err := certdb.CollectRelease(rel.Bundle, rel.Version, tx)
52 if err != nil {
53 return expired, revoked, err
54 }
55
56 expiresAt := time.Now().Add(window)
57 for _, cert := range certs {
58 if isRevoked, err := cert.Revoked(tx, rel.ReleasedAt); err != nil {
59 return expired, revoked, err
60 } else if isRevoked {
61 showExpiredCert(cert, "revoked certificate")
62 revoked++
63 continue
64 }
65
66 if cert.NotAfter <= expiresAt.Unix() {
67 showExpiredCert(cert, "expired certificate")
68 expired++
69 continue
70 }
71
72 if cert.NotBefore > rel.ReleasedAt {
73 showExpiredCert(cert, "certificate that isn't valid at the time of release")
74 expired++
75 continue
76 }
77 }
78
79 err = tx.Commit()
80 if err != nil {
81 return expired, revoked, err
82 }
83
84 return expired, revoked, err
85}
86
87func expiring(cmd *cobra.Command, args []string) {
88 dbPath := viper.GetString("database.path")
89 db, err := sql.Open("sqlite3", dbPath)
90 if err != nil {
91 fmt.Fprintf(os.Stderr, "[!] %s\n", err)
92 os.Exit(1)
93 }
94
95 if bundleRelease == "" {
96 latest, err := certdb.LatestRelease(db, bundle)
97 if err != nil {
98 fmt.Fprintf(os.Stderr, "[!] %s\n", err)
99 os.Exit(1)
100 }
101 bundleRelease = latest.Version
102 }
103
104 window := 30 * 24 * time.Hour
105 if len(args) > 0 {
106 window, err = time.ParseDuration(args[0])
107 if err != nil {
108 fmt.Fprintf(os.Stderr, "[!] %s\n", err)
109 os.Exit(1)
110 }
111 }
112
113 expired, revoked, err := scanBundleForExpirations(db, window)
114 if err != nil {
115 fmt.Fprintf(os.Stderr, "[!] %s\n", err)
116 os.Exit(1)
117 }
118
119 fmt.Println("Release:", bundle, bundleRelease)
120 fmt.Printf("%d certificates expiring.\n%d certificates revoked.\n",
121 expired, revoked)
122}
123