// 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 }
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 }
func isSelfSigned(cert *x509.Certificate) bool { return cert.CheckSignatureFrom(cert) == nil }