Skip to content
This repository was archived by the owner on Aug 2, 2023. It is now read-only.

Commit 6e2daf2

Browse files
committed
Add issuer cn matcher to scanner + print whole chains option
Adds a flag to match certs by issuer CN. Also adds the option to print the whole chain for matches in base64.
1 parent 94cfe39 commit 6e2daf2

File tree

2 files changed

+62
-10
lines changed

2 files changed

+62
-10
lines changed

go/scanner/main/scanner.go

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"math/big"
88
"regexp"
99

10+
"encoding/base64"
1011
"github.com/google/certificate-transparency/go"
1112
"github.com/google/certificate-transparency/go/client"
1213
"github.com/google/certificate-transparency/go/scanner"
@@ -19,13 +20,15 @@ const (
1920

2021
var logUri = flag.String("log_uri", "http://ct.googleapis.com/aviator", "CT log base URI")
2122
var matchSubjectRegex = flag.String("match_subject_regex", ".*", "Regex to match CN/SAN")
23+
var matchIssuerRegex = flag.String("match_issuer_regex", "", "Regex to match in issuer CN")
2224
var precertsOnly = flag.Bool("precerts_only", false, "Only match precerts")
2325
var serialNumber = flag.String("serial_number", "", "Serial number of certificate of interest")
2426
var batchSize = flag.Int("batch_size", 1000, "Max number of entries to request at per call to get-entries")
2527
var numWorkers = flag.Int("num_workers", 2, "Number of concurrent matchers")
2628
var parallelFetch = flag.Int("parallel_fetch", 2, "Number of concurrent GetEntries fetches")
2729
var startIndex = flag.Int64("start_index", 0, "Log index to start scanning at")
2830
var quiet = flag.Bool("quiet", false, "Don't print out extra logging messages, only matches.")
31+
var printChains = flag.Bool("print_chains", false, "If true prints the whole chain rather than a summary")
2932

3033
// Prints out a short bit of info about |cert|, found at |index| in the
3134
// specified log
@@ -40,7 +43,45 @@ func logPrecertInfo(entry *ct.LogEntry) {
4043
entry.Precert.TBSCertificate.Subject.CommonName, entry.Precert.TBSCertificate.Issuer.CommonName)
4144
}
4245

46+
func chainToString(certs []ct.ASN1Cert) string {
47+
var output []byte
48+
49+
for _, cert := range certs {
50+
output = append(output, cert...)
51+
}
52+
53+
return base64.StdEncoding.EncodeToString(output)
54+
}
55+
56+
func logCertChain(entry *ct.LogEntry) {
57+
log.Printf("Index %d: Chain: %s", entry.Index, chainToString(entry.Chain))
58+
}
59+
60+
func logPrecertChain(entry *ct.LogEntry) {
61+
log.Printf("Index %d: Chain: %s", entry.Index, chainToString(entry.Chain))
62+
}
63+
64+
func createRegexes(regexValue string) (*regexp.Regexp, *regexp.Regexp) {
65+
// Make a regex matcher
66+
var certRegex *regexp.Regexp
67+
precertRegex := regexp.MustCompile(regexValue)
68+
switch *precertsOnly {
69+
case true:
70+
certRegex = regexp.MustCompile(MatchesNothingRegex)
71+
case false:
72+
certRegex = precertRegex
73+
}
74+
75+
return certRegex, precertRegex
76+
}
77+
4378
func createMatcherFromFlags() (scanner.Matcher, error) {
79+
if *matchIssuerRegex != "" {
80+
certRegex, precertRegex := createRegexes(*matchIssuerRegex)
81+
return scanner.MatchIssuerRegex{
82+
CertificateIssuerRegex: certRegex,
83+
PrecertificateIssuerRegex: precertRegex}, nil
84+
}
4485
if *serialNumber != "" {
4586
log.Printf("Using SerialNumber matcher on %s", *serialNumber)
4687
var sn big.Int
@@ -50,15 +91,7 @@ func createMatcherFromFlags() (scanner.Matcher, error) {
5091
}
5192
return scanner.MatchSerialNumber{SerialNumber: sn}, nil
5293
} else {
53-
// Make a regex matcher
54-
var certRegex *regexp.Regexp
55-
precertRegex := regexp.MustCompile(*matchSubjectRegex)
56-
switch *precertsOnly {
57-
case true:
58-
certRegex = regexp.MustCompile(MatchesNothingRegex)
59-
case false:
60-
certRegex = precertRegex
61-
}
94+
certRegex, precertRegex := createRegexes(*matchSubjectRegex)
6295
return scanner.MatchSubjectRegex{
6396
CertificateSubjectRegex: certRegex,
6497
PrecertificateSubjectRegex: precertRegex}, nil
@@ -82,5 +115,10 @@ func main() {
82115
Quiet: *quiet,
83116
}
84117
scanner := scanner.NewScanner(logClient, opts)
85-
scanner.Scan(logCertInfo, logPrecertInfo)
118+
119+
if *printChains {
120+
scanner.Scan(logCertChain, logPrecertChain)
121+
} else {
122+
scanner.Scan(logCertInfo, logPrecertInfo)
123+
}
86124
}

go/scanner/scanner.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,20 @@ func (m MatchSubjectRegex) PrecertificateMatches(p *ct.Precertificate) bool {
9595
return false
9696
}
9797

98+
// Matches on issuer cn by regex
99+
type MatchIssuerRegex struct {
100+
CertificateIssuerRegex *regexp.Regexp
101+
PrecertificateIssuerRegex *regexp.Regexp
102+
}
103+
104+
func (m MatchIssuerRegex) CertificateMatches(c *x509.Certificate) bool {
105+
return m.CertificateIssuerRegex.FindStringIndex(c.Issuer.CommonName) != nil
106+
}
107+
108+
func (m MatchIssuerRegex) PrecertificateMatches(p *ct.Precertificate) bool {
109+
return m.PrecertificateIssuerRegex.FindStringIndex(p.TBSCertificate.Issuer.CommonName) != nil
110+
}
111+
98112
// ScannerOptions holds configuration options for the Scanner
99113
type ScannerOptions struct {
100114
// Custom matcher for x509 Certificates, functor will be called for each

0 commit comments

Comments
 (0)