func()

in go/cmd/ct-fetch/ct-fetch.go [367:471]


func (ld *LogSyncEngine) insertCTWorker() {
	ld.ThreadWaitGroup.Add(1)
	defer ld.ThreadWaitGroup.Done()

	healthStatusPeriod, _ := time.ParseDuration("15s")
	healthStatusJitter := rand.Int63n(15 * 1000)
	healthStatusDuration := healthStatusPeriod + time.Duration(healthStatusJitter)*time.Millisecond
	glog.Infof("Thread health status period: %v + %v = %v", healthStatusPeriod, healthStatusJitter, healthStatusDuration)
	healthStatusTicker := time.NewTicker(healthStatusDuration)
	defer healthStatusTicker.Stop()

	for ep := range ld.entryChan {
		select { // Taking something off the queue is useful work.
		// So indicate server health when requested.
		case <-healthStatusTicker.C:
			ld.RegisterUpdate()
		default:
		}

		var cert *x509.Certificate
		var err error
		precert := false

		switch ep.LogEntry.Leaf.TimestampedEntry.EntryType {
		case ct.X509LogEntryType:
			cert = ep.LogEntry.X509Cert
		case ct.PrecertLogEntryType:
			cert, err = x509.ParseCertificate(ep.LogEntry.Precert.Submitted.Data)
			precert = true
		}

		if cert == nil {
			glog.Errorf("[%s] Fatal parsing error: index: %d error: %v", ep.LogMeta.URL, ep.LogEntry.Index, err)
			continue
		}
		if err != nil {
			glog.Warningf("[%s] Nonfatal parsing error: index: %d error: %s", ep.LogMeta.URL, ep.LogEntry.Index, err)
		}

		// Skip expired certificates unless configured otherwise
		if cert.NotAfter.Before(time.Now()) && !*ctconfig.LogExpiredEntries {
			continue
		}

		if len(ep.LogEntry.Chain) < 1 {
			glog.Warningf("[%s] No issuer known for certificate precert=%v index=%d serial=%s subject=%+v issuer=%+v",
				ep.LogMeta.URL, precert, ep.LogEntry.Index, types.NewSerial(cert).String(), cert.Subject, cert.Issuer)
			continue
		}

		preIssuerOrIssuingCert, err := x509.ParseCertificate(ep.LogEntry.Chain[0].Data)
		if err != nil {
			glog.Errorf("[%s] Problem decoding issuing certificate: index: %d error: %s", ep.LogMeta.URL, ep.LogEntry.Index, err)
			continue
		}

		// RFC 6962 allows a precertificate to be signed by "a
		// special-purpose [...] Precertificate Signing Certificate
		// [that is] certified by the (root or intermediate) CA
		// certificate that will ultimately sign the end-entity". In
		// this case, the certificate that will issue the final cert is
		// the second entry in the chain (ep.LogEntry.Chain[1]).
		var issuingCert *x509.Certificate
		if types.IsPreIssuer(preIssuerOrIssuingCert) {
			if !precert {
				glog.Errorf("[%s] X509LogEntry issuer has precertificate signing EKU: index: %d", ep.LogMeta.URL, ep.LogEntry.Index)
				continue
			}

			if len(ep.LogEntry.Chain) < 2 {
				glog.Warningf("[%s] No issuer known for certificate precert=%v index=%d serial=%s subject=%+v issuer=%+v",
					ep.LogMeta.URL, precert, ep.LogEntry.Index, types.NewSerial(cert).String(), cert.Subject, cert.Issuer)
				continue
			}

			issuingCert, err = x509.ParseCertificate(ep.LogEntry.Chain[1].Data)
			if err != nil {
				glog.Errorf("[%s] Problem decoding issuing certificate: index: %d error: %s", ep.LogMeta.URL, ep.LogEntry.Index, err)
				continue
			}

			// Bug 1955023 - This program previously failed to
			// handle precertificate signing certificates. This
			// caused some serial numbers to be stored in the bin
			// labeled "issuer::<precertificate issuer id>" rather
			// than "issuer::<issuer id>". Adding a preissuer alias
			// causes CertDatabase to merge entries from
			// "issuer::<precertificate issuer id>" into
			// "issuer::<issuer id>" in future commits.
			issuer := types.NewIssuer(issuingCert)
			preissuer := types.NewIssuer(preIssuerOrIssuingCert)
			err = ld.database.AddPreIssuerAlias(preissuer, issuer)
			if err != nil {
				glog.Warningf("[%s] Failed to add preissuer alias. index: %d, issuer=%+v", ep.LogMeta.URL, ep.LogEntry.Index, cert.Issuer)
			}
		} else {
			issuingCert = preIssuerOrIssuingCert
		}

		err = ld.database.Store(cert, issuingCert, ep.LogMeta.URL, ep.LogEntry.Index)
		if err != nil {
			glog.Errorf("[%s] Problem inserting certificate: index: %d error: %s", ep.LogMeta.URL, ep.LogEntry.Index, err)
		}
	}
}