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 }
// FetchCN fetches a DANE record for CN in DNSSEC func FetchCN(cn string) (*x509.Certificate, error) { unb := unbound.New() cert, err := unb.GetCACert(cn) check(err) log.Printf("Got certificate: Issuer: %#v\nand Subject: %#v", cert.Issuer, cert.Subject) return cert, err }
// 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 }