From: Willem Toorop Date: Wed, 19 Sep 2012 21:00:03 +0000 (+0000) Subject: Asked Jakob. A CA certificate is a certificate with the CA basicConstraint set to... X-Git-Tag: release-1.6.14rc1~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3abb30c1bfa361cfa46666b580497ca755450d10;p=thirdparty%2Fldns.git Asked Jakob. A CA certificate is a certificate with the CA basicConstraint set to true (provided by X509_check_ca in OpenSSL). So no need to check for it in the validation store. --- diff --git a/dane.c b/dane.c index eaa2e99e..b713f030 100644 --- a/dane.c +++ b/dane.c @@ -24,6 +24,7 @@ #ifdef HAVE_SSL #include #include +#include #endif #ifndef max @@ -555,11 +556,13 @@ ldns_dane_match_cert_with_data(X509* cert, ldns_tlsa_selector selector, /* Return whether any certificate from the chain with selector/matching_type * matches data. + * ca should be true if the certificate has to be a CA certificate too. */ static ldns_status ldns_dane_match_any_cert_with_data(STACK_OF(X509)* chain, ldns_tlsa_selector selector, - ldns_tlsa_matching_type matching_type, ldns_rdf* data) + ldns_tlsa_matching_type matching_type, + ldns_rdf* data, bool ca) { ldns_status s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH; size_t n, i; @@ -574,10 +577,16 @@ ldns_dane_match_any_cert_with_data(STACK_OF(X509)* chain, } s = ldns_dane_match_cert_with_data(cert, selector, matching_type, data); + if (ca && s == LDNS_STATUS_OK && ! X509_check_ca(cert)) { + s = LDNS_STATUS_DANE_TLSA_MATCHED_NON_CA_CERTIFICATE; + } X509_free(cert); if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH) { break; } + /* when s == LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH, + * try to match the next certificate + */ } return s; } @@ -628,7 +637,7 @@ ldns_dane_verify_rr(const ldns_rr* tlsa_rr, */ s = ldns_dane_match_any_cert_with_data( pkix_validation_chain, - selector, matching_type, data); + selector, matching_type, data, true); if (s == LDNS_STATUS_OK) { /* A TLSA record did match a cert from the @@ -641,30 +650,9 @@ ldns_dane_verify_rr(const ldns_rr* tlsa_rr, } else if (s == LDNS_STATUS_OK) { /* PKIX validated, does the TLSA match too? */ - /* Pop the last cert from the validation chain */ - cert = sk_X509_pop(pkix_validation_chain); - if (! cert) { - s = LDNS_STATUS_SSL_ERR; - } else { - s = ldns_dane_match_cert_with_data(cert, - selector, matching_type, data); - X509_free(cert); - /* - * TODO: What to do when we had no match? - * - * Does OpenSSL create the longest possible - * validation_chain? - * - * In that case we have to test whether - * intermediate certificates are in the - * pkix_validation_store. - * - * Otherwise, we have to remove the signing - * CA from the pkix_validation_store, and see - * if that removed cert might itself be - * validated by a CA that *does* match. - */ - } + s = ldns_dane_match_any_cert_with_data( + pkix_validation_chain, + selector, matching_type, data, true); } sk_X509_pop_free(pkix_validation_chain, X509_free); return s; @@ -685,7 +673,7 @@ ldns_dane_verify_rr(const ldns_rr* tlsa_rr, if (s == LDNS_STATUS_OK) { s = ldns_dane_match_any_cert_with_data( pkix_validation_chain, - selector, matching_type, data); + selector, matching_type, data, false); } else if (! pkix_validation_chain) { return s; diff --git a/error.c b/error.c index 060de862..ac980d23 100644 --- a/error.c +++ b/error.c @@ -114,11 +114,15 @@ ldns_lookup_table ldns_error_str[] = { "extra certificates" }, { LDNS_STATUS_DANE_INSECURE, /* Unused by library */ "The queried resource records were insecure" }, + { LDNS_STATUS_DANE_BOGUS, /* Unused by library */ + "The queried resource records were bogus" }, { LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH, "The TLSA record(s) " "did not match with the server certificate (chain)" }, + { LDNS_STATUS_DANE_TLSA_MATCHED_NON_CA_CERTIFICATE, + "A TLSA record matched, but was not a CA certificate" }, { LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE, - "DANE PKIX Could not validate" }, + "Could not PKIX validate" }, { LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR, /* Trust anchor assertion */ "The validation chain must end in a self-signed certificate " }, { 0, NULL } diff --git a/ldns/error.h b/ldns/error.h index cd6be5ae..25154f14 100644 --- a/ldns/error.h +++ b/ldns/error.h @@ -114,7 +114,9 @@ enum ldns_enum_status { LDNS_STATUS_DANE_EXTRA_CERTS_NOT_USED, LDNS_STATUS_DANE_INDEX_OUT_OF_RANGE, LDNS_STATUS_DANE_INSECURE, + LDNS_STATUS_DANE_BOGUS, LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH, + LDNS_STATUS_DANE_TLSA_MATCHED_NON_CA_CERTIFICATE, LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE, LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR };