diff --git a/ChangeLog b/ChangeLog index cc3cf584..4a87df27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ * 2018-0?-??: Version 1.4.3 + * Fix for DNSSEC bug in finding most specific key when + trust anchor proves non-existance of one of the labels + along the authentication chain other than the non- + existance of a DS record on a zonecut. * Enhancement getdnsapi/stubby#56 & getdnsapi/stubby#130: Configurable minimum and maximum TLS versions with getdns_context_set_tls_min_version() and diff --git a/src/dnssec.c b/src/dnssec.c index fd8ac932..4dca78bc 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -2606,7 +2606,7 @@ static int chain_node_get_trusted_keys( *keys = ta; return GETDNS_DNSSEC_SECURE; } - /* ta is parent's ZSK */ + /* ta is parent's ZSK proving insecurity below this node? */ if ((keytag = key_proves_nonexistance( mf, now, skew, ta, &node->ds, &opt_out))) { node->ds_signer = keytag; @@ -2621,12 +2621,18 @@ static int chain_node_get_trusted_keys( * key_proves_nonexistance() will set opt_out also for * these conditions. */ - return opt_out ? GETDNS_DNSSEC_INSECURE - : GETDNS_DNSSEC_SECURE; - } - if ((keytag = a_key_signed_rrset_no_wc( + if (opt_out) + return GETDNS_DNSSEC_INSECURE; + + /* If this is not an insecurity proof, + * continue searching one label up. + */ + + /* ta is parent's ZSK authenticating DS? */ + } else if ((keytag = a_key_signed_rrset_no_wc( mf, now, skew, ta, &node->ds))) { node->ds_signer = keytag; + /* DS should authenticate the DNSKEY rrset now */ if ((keytag = ds_authenticates_keys( mf, now, skew, &node->ds, &node->dnskey))) { *keys = &node->dnskey; @@ -2635,6 +2641,7 @@ static int chain_node_get_trusted_keys( ? GETDNS_DNSSEC_INSECURE : GETDNS_DNSSEC_SECURE; } + /* DS without DNSKEY rrset == BOGUS */ return GETDNS_DNSSEC_BOGUS; } } else