Move Identifiers from CertInfo to EntryInfo

It's more logical, and it avoids some redundant parsing.
This commit is contained in:
Andrew Ayer 2016-05-03 11:58:59 -07:00
parent 5f4e35843a
commit 60636ba2d7
4 changed files with 58 additions and 60 deletions

View File

@ -28,6 +28,9 @@ func processEntry (scanner *ctwatch.Scanner, entry *ct.LogEntry) {
} }
info.CertInfo, info.ParseError = ctwatch.MakeCertInfoFromLogEntry(entry) info.CertInfo, info.ParseError = ctwatch.MakeCertInfoFromLogEntry(entry)
if info.CertInfo != nil {
info.Identifiers, info.IdentifiersParseError = info.CertInfo.ParseIdentifiers()
}
if info.HasParseErrors() { if info.HasParseErrors() {
cmd.LogEntry(&info) cmd.LogEntry(&info)

View File

@ -104,12 +104,15 @@ func processEntry (scanner *ctwatch.Scanner, entry *ct.LogEntry) {
info.CertInfo, info.ParseError = ctwatch.MakeCertInfoFromLogEntry(entry) info.CertInfo, info.ParseError = ctwatch.MakeCertInfoFromLogEntry(entry)
// If there's any sort of parse error related to the identifiers, report if info.CertInfo != nil {
// the certificate because we can't say for sure it doesn't match a domain info.Identifiers, info.IdentifiersParseError = info.CertInfo.ParseIdentifiers()
// we care about (fail safe behavior). }
if info.ParseError != nil ||
info.CertInfo.IdentifiersParseError != nil || // Fail safe behavior: if info.Identifiers is nil (which is caused by a
anyDnsNameMatches(info.CertInfo.Identifiers.DNSNames) { // parse error), report the certificate because we can't say for sure it
// doesn't match a domain we care about. We try very hard to make sure
// parsing identifiers always succeeds, so false alarms should be rare.
if info.Identifiers == nil || anyDnsNameMatches(info.Identifiers.DNSNames) {
cmd.LogEntry(&info) cmd.LogEntry(&info)
} }
} }

View File

@ -96,14 +96,14 @@ type EntryInfo struct {
FullChain [][]byte // first entry is logged X509 cert or pre-cert FullChain [][]byte // first entry is logged X509 cert or pre-cert
CertInfo *CertInfo CertInfo *CertInfo
ParseError error // set iff CertInfo is nil ParseError error // set iff CertInfo is nil
Identifiers *Identifiers
IdentifiersParseError error
Filename string Filename string
} }
type CertInfo struct { type CertInfo struct {
TBS *TBSCertificate TBS *TBSCertificate
Identifiers *Identifiers
IdentifiersParseError error
Subject RDNSequence Subject RDNSequence
SubjectParseError error SubjectParseError error
Issuer RDNSequence Issuer RDNSequence
@ -121,7 +121,6 @@ type CertInfo struct {
func MakeCertInfoFromTBS (tbs *TBSCertificate) *CertInfo { func MakeCertInfoFromTBS (tbs *TBSCertificate) *CertInfo {
info := &CertInfo{TBS: tbs} info := &CertInfo{TBS: tbs}
info.Identifiers, info.IdentifiersParseError = tbs.ParseIdentifiers()
info.Subject, info.SubjectParseError = tbs.ParseSubject() info.Subject, info.SubjectParseError = tbs.ParseSubject()
info.Issuer, info.IssuerParseError = tbs.ParseIssuer() info.Issuer, info.IssuerParseError = tbs.ParseIssuer()
info.SANs, info.SANsParseError = tbs.ParseSubjectAltNames() info.SANs, info.SANsParseError = tbs.ParseSubjectAltNames()
@ -161,29 +160,6 @@ func MakeCertInfoFromLogEntry (entry *ct.LogEntry) (*CertInfo, error) {
} }
} }
func (info *CertInfo) dnsNamesString (sep string) string {
if info.IdentifiersParseError == nil {
return strings.Join(info.Identifiers.DNSNames, sep)
} else {
return ""
}
}
func (info *CertInfo) ipAddrsString (sep string) string {
if info.IdentifiersParseError == nil {
str := ""
for _, ipAddr := range info.Identifiers.IPAddrs {
if str != "" {
str += sep
}
str += ipAddr.String()
}
return str
} else {
return ""
}
}
func (info *CertInfo) NotBefore () *time.Time { func (info *CertInfo) NotBefore () *time.Time {
if info.ValidityParseError == nil { if info.ValidityParseError == nil {
return &info.Validity.NotBefore return &info.Validity.NotBefore
@ -213,13 +189,6 @@ func (info *CertInfo) Environ () []string {
env = append(env, "PUBKEY_HASH=" + info.PubkeyHash()) env = append(env, "PUBKEY_HASH=" + info.PubkeyHash())
if info.IdentifiersParseError != nil {
env = append(env, "IDENTIFIERS_PARSE_ERROR=" + info.IdentifiersParseError.Error())
} else {
env = append(env, "DNS_NAMES=" + info.dnsNamesString(","))
env = append(env, "IP_ADDRESSES=" + info.ipAddrsString(","))
}
if info.SerialNumberParseError != nil { if info.SerialNumberParseError != nil {
env = append(env, "SERIAL_PARSE_ERROR=" + info.SerialNumberParseError.Error()) env = append(env, "SERIAL_PARSE_ERROR=" + info.SerialNumberParseError.Error())
} else { } else {
@ -254,7 +223,7 @@ func (info *CertInfo) Environ () []string {
func (info *EntryInfo) HasParseErrors () bool { func (info *EntryInfo) HasParseErrors () bool {
return info.ParseError != nil || return info.ParseError != nil ||
info.CertInfo.IdentifiersParseError != nil || info.IdentifiersParseError != nil ||
info.CertInfo.SubjectParseError != nil || info.CertInfo.SubjectParseError != nil ||
info.CertInfo.IssuerParseError != nil || info.CertInfo.IssuerParseError != nil ||
info.CertInfo.SANsParseError != nil || info.CertInfo.SANsParseError != nil ||
@ -315,11 +284,17 @@ func (info *EntryInfo) Environ () []string {
if info.Filename != "" { if info.Filename != "" {
env = append(env, "CERT_FILENAME=" + info.Filename) env = append(env, "CERT_FILENAME=" + info.Filename)
} }
if info.ParseError == nil { if info.ParseError != nil {
env = append(env, "PARSE_ERROR=" + info.ParseError.Error())
} else if info.CertInfo != nil {
certEnv := info.CertInfo.Environ() certEnv := info.CertInfo.Environ()
env = append(env, certEnv...) env = append(env, certEnv...)
} else { }
env = append(env, "PARSE_ERROR=" + info.ParseError.Error()) if info.IdentifiersParseError != nil {
env = append(env, "IDENTIFIERS_PARSE_ERROR=" + info.IdentifiersParseError.Error())
} else if info.Identifiers != nil {
env = append(env, "DNS_NAMES=" + info.Identifiers.dnsNamesString(","))
env = append(env, "IP_ADDRESSES=" + info.Identifiers.ipAddrsString(","))
} }
return env return env
@ -336,19 +311,19 @@ func writeField (out io.Writer, name string, value interface{}, err error) {
func (info *EntryInfo) Write (out io.Writer) { func (info *EntryInfo) Write (out io.Writer) {
fingerprint := info.Fingerprint() fingerprint := info.Fingerprint()
fmt.Fprintf(out, "%s:\n", fingerprint) fmt.Fprintf(out, "%s:\n", fingerprint)
if info.ParseError != nil { if info.IdentifiersParseError != nil {
writeField(out, "Parse Error", "*** " + info.ParseError.Error() + " ***", nil) writeField(out, "Identifiers", nil, info.IdentifiersParseError)
} else { } else if info.Identifiers != nil {
if info.CertInfo.IdentifiersParseError != nil { for _, dnsName := range info.Identifiers.DNSNames {
writeField(out, "Identifiers", nil, info.CertInfo.IdentifiersParseError)
} else {
for _, dnsName := range info.CertInfo.Identifiers.DNSNames {
writeField(out, "DNS Name", dnsName, nil) writeField(out, "DNS Name", dnsName, nil)
} }
for _, ipaddr := range info.CertInfo.Identifiers.IPAddrs { for _, ipaddr := range info.Identifiers.IPAddrs {
writeField(out, "IP Address", ipaddr, nil) writeField(out, "IP Address", ipaddr, nil)
} }
} }
if info.ParseError != nil {
writeField(out, "Parse Error", "*** " + info.ParseError.Error() + " ***", nil)
} else if info.CertInfo != nil {
writeField(out, "Pubkey", info.CertInfo.PubkeyHash(), nil) writeField(out, "Pubkey", info.CertInfo.PubkeyHash(), nil)
writeField(out, "Subject", info.CertInfo.Subject, info.CertInfo.SubjectParseError) writeField(out, "Subject", info.CertInfo.Subject, info.CertInfo.SubjectParseError)
if info.CertInfo.SANsParseError != nil { if info.CertInfo.SANsParseError != nil {

View File

@ -232,10 +232,28 @@ func (ids *Identifiers) AddIPAddress (value net.IP) {
ids.IPAddrs = append(ids.IPAddrs, value) ids.IPAddrs = append(ids.IPAddrs, value)
} }
func (tbs *TBSCertificate) ParseIdentifiers () (*Identifiers, error) { func (ids *Identifiers) dnsNamesString (sep string) string {
return strings.Join(ids.DNSNames, sep)
}
func (ids *Identifiers) ipAddrsString (sep string) string {
str := ""
for _, ipAddr := range ids.IPAddrs {
if str != "" {
str += sep
}
str += ipAddr.String()
}
return str
}
func (cert *CertInfo) ParseIdentifiers () (*Identifiers, error) {
ids := NewIdentifiers() ids := NewIdentifiers()
cns, err := tbs.ParseSubjectCommonNames() if cert.SubjectParseError != nil {
return nil, cert.SubjectParseError
}
cns, err := cert.Subject.ParseCNs()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -243,11 +261,10 @@ func (tbs *TBSCertificate) ParseIdentifiers () (*Identifiers, error) {
ids.AddCN(cn) ids.AddCN(cn)
} }
sans, err := tbs.ParseSubjectAltNames() if cert.SANsParseError != nil {
if err != nil { return nil, cert.SANsParseError
return nil, err
} }
for _, san := range sans { for _, san := range cert.SANs {
switch san.Type { switch san.Type {
case sanDNSName: case sanDNSName:
ids.AddDnsSAN(san.Value) ids.AddDnsSAN(san.Value)