diff options
| author | Cy Schubert <cy@FreeBSD.org> | 2024-03-16 23:58:33 +0000 |
|---|---|---|
| committer | Cy Schubert <cy@FreeBSD.org> | 2024-03-17 00:00:52 +0000 |
| commit | 5a33598e88ad8fbc0affa74dee0a2d8cc4010fbc (patch) | |
| tree | 211c17b0e7eeb34cdd84e378e3720514e8987b8c /validator | |
| parent | 217a625642d38bfc0d3d03192b013d4bc7a32458 (diff) | |
unbound: Vendor import 1.19.3vendor/unbound/1.19.3
Release notes at
https://www.nlnetlabs.nl/news/2024/Mar/14/unbound-1.19.3-released/
Diffstat (limited to 'validator')
| -rw-r--r-- | validator/autotrust.c | 8 | ||||
| -rw-r--r-- | validator/val_sigcrypt.c | 2 | ||||
| -rw-r--r-- | validator/val_utils.c | 55 | ||||
| -rw-r--r-- | validator/validator.c | 2 |
4 files changed, 54 insertions, 13 deletions
diff --git a/validator/autotrust.c b/validator/autotrust.c index 3011a0ace7a2..3eb13b35c229 100644 --- a/validator/autotrust.c +++ b/validator/autotrust.c @@ -353,17 +353,21 @@ autr_tp_create(struct val_anchors* anchors, uint8_t* own, size_t own_len, lock_basic_lock(&anchors->lock); if(!rbtree_insert(anchors->tree, &tp->node)) { + char buf[LDNS_MAX_DOMAINLEN+1]; lock_basic_unlock(&anchors->lock); - log_err("trust anchor presented twice"); + dname_str(tp->name, buf); + log_err("trust anchor for '%s' presented twice", buf); free(tp->name); free(tp->autr); free(tp); return NULL; } if(!rbtree_insert(&anchors->autr->probe, &tp->autr->pnode)) { + char buf[LDNS_MAX_DOMAINLEN+1]; (void)rbtree_delete(anchors->tree, tp); lock_basic_unlock(&anchors->lock); - log_err("trust anchor in probetree twice"); + dname_str(tp->name, buf); + log_err("trust anchor for '%s' in probetree twice", buf); free(tp->name); free(tp->autr); free(tp); diff --git a/validator/val_sigcrypt.c b/validator/val_sigcrypt.c index f4b866366f3c..7c2b9d7e6608 100644 --- a/validator/val_sigcrypt.c +++ b/validator/val_sigcrypt.c @@ -748,7 +748,6 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve, return sec_status_bogus; } } - verbose(VERB_ALGO, "rrset failed to verify: all signatures are bogus"); if(!numchecked) { *reason = "signature for expected key and algorithm missing"; if(reason_bogus) @@ -761,6 +760,7 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve, *reason = "algorithm refused by cryptolib"; return sec_status_indeterminate; } + verbose(VERB_ALGO, "rrset failed to verify: all signatures are bogus"); return sec_status_bogus; } diff --git a/validator/val_utils.c b/validator/val_utils.c index 67a958ae2ade..c316183a9d9e 100644 --- a/validator/val_utils.c +++ b/validator/val_utils.c @@ -424,11 +424,13 @@ static enum sec_status verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset, struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason, - sldns_ede_code *reason_bogus, struct module_qstate* qstate) + sldns_ede_code *reason_bogus, struct module_qstate* qstate, + int *nonechecked) { enum sec_status sec = sec_status_bogus; size_t i, num, numchecked = 0, numhashok = 0, numsizesupp = 0; num = rrset_get_count(dnskey_rrset); + *nonechecked = 0; for(i=0; i<num; i++) { /* Skip DNSKEYs that don't match the basic criteria. */ if(ds_get_key_algo(ds_rrset, ds_idx) @@ -476,13 +478,15 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve, /* there is a working DS, but that DNSKEY is not supported */ return sec_status_insecure; } - if(numchecked == 0) + if(numchecked == 0) { algo_needs_reason(env, ds_get_key_algo(ds_rrset, ds_idx), reason, "no keys have a DS"); - else if(numhashok == 0) + *nonechecked = 1; + } else if(numhashok == 0) { *reason = "DS hash mismatches key"; - else if(!*reason) + } else if(!*reason) { *reason = "keyset not secured by DNSKEY that matches DS"; + } return sec_status_bogus; } @@ -511,7 +515,8 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve, { /* as long as this is false, we can consider this DS rrset to be * equivalent to no DS rrset. */ - int has_useful_ds = 0, digest_algo, alg; + int has_useful_ds = 0, digest_algo, alg, has_algo_refusal = 0, + nonechecked, has_checked_ds = 0; struct algo_needs needs; size_t i, num; enum sec_status sec; @@ -544,9 +549,16 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve, } sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset, - ds_rrset, i, reason, reason_bogus, qstate); - if(sec == sec_status_insecure) + ds_rrset, i, reason, reason_bogus, qstate, + &nonechecked); + if(sec == sec_status_insecure) { + /* DNSKEY too large unsupported or algo refused by + * crypto lib. */ + has_algo_refusal = 1; continue; + } + if(!nonechecked) + has_checked_ds = 1; /* Once we see a single DS with a known digestID and * algorithm, we cannot return INSECURE (with a @@ -571,6 +583,15 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve, /* None of the DS's worked out. */ + /* If none of the DSes have been checked, eg. that means no matches + * for keytags, and the other dses are all algo_refusal, it is an + * insecure delegation point, since the only matched DS records + * have an algo refusal, or are unsupported. */ + if(has_algo_refusal && !has_checked_ds) { + verbose(VERB_ALGO, "No supported DS records were found -- " + "treating as insecure."); + return sec_status_insecure; + } /* If no DSs were understandable, then this is OK. */ if(!has_useful_ds) { verbose(VERB_ALGO, "No usable DS records were found -- " @@ -624,7 +645,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve, { /* as long as this is false, we can consider this anchor to be * equivalent to no anchor. */ - int has_useful_ta = 0, digest_algo = 0, alg; + int has_useful_ta = 0, digest_algo = 0, alg, has_algo_refusal = 0, + nonechecked, has_checked_ds = 0; struct algo_needs needs; size_t i, num; enum sec_status sec; @@ -670,9 +692,13 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve, continue; sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset, - ta_ds, i, reason, reason_bogus, qstate); - if(sec == sec_status_insecure) + ta_ds, i, reason, reason_bogus, qstate, &nonechecked); + if(sec == sec_status_insecure) { + has_algo_refusal = 1; continue; + } + if(!nonechecked) + has_checked_ds = 1; /* Once we see a single DS with a known digestID and * algorithm, we cannot return INSECURE (with a @@ -728,6 +754,15 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve, } } + /* If none of the DSes have been checked, eg. that means no matches + * for keytags, and the other dses are all algo_refusal, it is an + * insecure delegation point, since the only matched DS records + * have an algo refusal, or are unsupported. */ + if(has_algo_refusal && !has_checked_ds) { + verbose(VERB_ALGO, "No supported trust anchors were found -- " + "treating as insecure."); + return sec_status_insecure; + } /* If no DSs were understandable, then this is OK. */ if(!has_useful_ta) { verbose(VERB_ALGO, "No usable trust anchors were found -- " diff --git a/validator/validator.c b/validator/validator.c index 26d33a37ff31..aa71df9cbf58 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -3010,6 +3010,8 @@ return_bogus: * @param msg: result message (if rcode is OK). * @param qinfo: from the sub query state, query info. * @param origin: the origin of msg. + * @param suspend: returned true if the task takes too long and needs to + * suspend to continue the effort later. */ static void process_ds_response(struct module_qstate* qstate, struct val_qstate* vq, |
