// ValidateEccentricCertificate verifies that the given certificate parses to a real x509 certificate
// and that it is signed by the FPCA
// DANE/TLSA record it specifies in the CN.
// TODO: Deprecate this function as it handles only direct signing by the FPCA, no SubCAs
// Use ValidateEccentricCertificateChain instead
func ValidateEccentricCertificate(cl_cert *x509.Certificate) (caCert *x509.Certificate, err error) {
	log.Printf("Validate Eccentric Certificate got client certificate: Issuer: %#v\nand Subject: %#v", cl_cert.Issuer, cl_cert.Subject)

	// Check the cn if it has the @@ in it.
	cn := cl_cert.Subject.CommonName // the chosen userid@@realm
	log.Printf("Subject CommonName is %v\n", cn)
	_, _, err = ParseCN(cn)
	if err != nil {
		return nil, err
	}

	// Now fetch the issuer. That must be the FPCA.
	issuer := cl_cert.Issuer.CommonName
	if issuer == "" {
		return nil, errors.New("Certificate does not look like an Eccentric Authenticated client certificate. It has an empty Issuer.CommonName. We expect the fqdn of its FPCA.")
	}
	unb := unbound.New()
	caCert, err = unb.GetCACert(issuer)
	check(err)
	log.Printf("Got certificate: Issuer: %#v\nand Subject: %#v", caCert.Issuer, caCert.Subject)

	err = cl_cert.CheckSignatureFrom(caCert)
	check(err) // TODO: give out neat error at validation failure, not a panic.

	return caCert, nil
}
func fetchCertificateChain(cl_cert *x509.Certificate, root *x509.Certificate) (chain []x509.Certificate, err error) {
	// check if cl_cert is signed by Root
	if cl_cert.Issuer.CommonName == root.Subject.CommonName {
		// client cert is signed by Root, there are no (more) intermediaries. We're done.
		chain = append(chain, *root)
		return chain, nil
	}

	issuer := cl_cert.Issuer.CommonName
	if issuer == "" {
		// chain is empty at this point.
		return chain, errors.New("Certificate does not look like an Eccentric Authenticated Intermediate certificate. It has an empty Issuer.CommonName. We expect the fqdn of its FPCA.")
	}
	unb := unbound.New()
	caCert, err := unb.GetCACert(issuer)
	check(err)
	log.Printf("Got certificate: Issuer: %#v\nand Subject: %#v", caCert.Issuer, caCert.Subject)

	// check if the signature matches
	err = cl_cert.CheckSignatureFrom(caCert)
	check(err) // TODO: give out neat error at validation failure, not a panic.

	// recurse to get higher up the tree.
	chain, err = FetchCertificateChain(caCert, root)
	if err != nil {
		return
	} // empty, err
	chain = append(chain, *caCert)
	return // chain, nil
}
Exemple #3
0
func (pool CertificatePool) certForIssuer(cert *x509.Certificate) *x509.Certificate {
	s := string(cert.RawIssuer)
	if string(cert.RawSubject) == s {
		if err := cert.CheckSignatureFrom(cert); err == nil {
			return cert
		}
	}
	for _, other := range pool.Cert {
		if string(other.RawSubject) == s {
			if err := cert.CheckSignatureFrom(other); err == nil {
				return other
			}
		}
	}
	return nil
}
// FindVerifiedParent attempts to find the certificate in s which has signed
// the given certificate. If no such certificate can be found or the signature
// doesn't match, it returns nil.
func (s *CASet) FindVerifiedParent(cert *x509.Certificate) (parent *x509.Certificate) {
	var candidates []*x509.Certificate

	if len(cert.AuthorityKeyId) > 0 {
		candidates = s.bySubjectKeyId[string(cert.AuthorityKeyId)]
	}
	if len(candidates) == 0 {
		candidates = s.byName[nameToKey(&cert.Issuer)]
	}

	for _, c := range candidates {
		if cert.CheckSignatureFrom(c) == nil {
			return c
		}
	}

	return nil
}
Exemple #5
0
func isSelfSigned(cert *x509.Certificate) bool {
	return cert.CheckSignatureFrom(cert) == nil
}