Example #1
0
File: pki.go Project: kisom/cfssl
func chainValidation(addr, hostname string) (grade Grade, output Output, err error) {
	chain, err := getChain(addr, defaultTLSConfig(hostname))
	if err != nil {
		return
	}

	var warnings []string

	for i := 0; i < len(chain)-1; i++ {
		cert, parent := chain[i], chain[i+1]

		valid := helpers.ValidExpiry(cert)
		if !valid {
			warnings = append(warnings, fmt.Sprintf("Certificate for %s is valid for too long", cert.Subject.CommonName))
		}

		revoked, ok := revoke.VerifyCertificate(cert)
		if !ok {
			warnings = append(warnings, fmt.Sprintf("couldn't check if %s is revoked", cert.Subject.CommonName))
		}
		if revoked {
			err = fmt.Errorf("%s is revoked", cert.Subject.CommonName)
			return
		}

		if !parent.IsCA {
			err = fmt.Errorf("%s is not a CA", parent.Subject.CommonName)
			return
		}

		if !bytes.Equal(cert.AuthorityKeyId, parent.SubjectKeyId) {
			err = fmt.Errorf("%s AuthorityKeyId differs from %s SubjectKeyId", cert.Subject.CommonName, parent.Subject.CommonName)
			return
		}

		if err = cert.CheckSignatureFrom(parent); err != nil {
			return
		}

		switch cert.SignatureAlgorithm {
		case x509.ECDSAWithSHA1:
			warnings = append(warnings, fmt.Sprintf("%s is signed by ECDSAWithSHA1", cert.Subject.CommonName))
		case x509.SHA1WithRSA:
			warnings = append(warnings, fmt.Sprintf("%s is signed by RSAWithSHA1", cert.Subject.CommonName))
		}
	}

	if len(warnings) == 0 {
		grade = Good
	} else {
		grade = Warning
		output = warnings
	}
	return
}
Example #2
0
// worker does all the parsing and validation of the certificate(s)
// contained in a single file. It first reads all the data in the
// file, then begins parsing certificates in the file. Those
// certificates are then checked for revocation.
func worker(paths chan string, bundler chan *x509.Certificate, pool *sync.WaitGroup) {
	defer (*pool).Done()
	for {
		path, ok := <-paths
		if !ok {
			return
		}

		log.Infof("Loading %s", path)

		fileData, err := ioutil.ReadFile(path)
		if err != nil {
			log.Warningf("%v", err)
			continue
		}

		for {
			var block *pem.Block
			if len(fileData) == 0 {
				break
			}
			block, fileData = pem.Decode(fileData)
			if block == nil {
				log.Warningf("%s: no PEM data found", path)
				break
			} else if block.Type != "CERTIFICATE" {
				log.Info("Skipping non-certificate")
				continue
			}

			cert, err := x509.ParseCertificate(block.Bytes)
			if err != nil {
				log.Warningf("Invalid certificate: %v", err)
				continue
			}

			log.Infof("Validating %+v", cert.Subject)
			revoked, ok := revoke.VerifyCertificate(cert)
			if !ok {
				log.Warning("Failed to verify certificate.")
			} else if !revoked {
				bundler <- cert
			} else {
				log.Info("Skipping revoked certificate")
			}
		}
	}
}