- algorithm compromise protection using the algorithms signalled in

the DS record.  Also, trust anchors, DLV, and RFC5011 receive this,
         and thus, if you have multiple algorithms in your trust-anchor-file
         then it will now behave different than before.  Also, 5011 rollover
         for algorithms needs to be double-signature until the old algorithm
         is revoked.


git-svn-id: file:///svn/unbound/trunk@2358 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2010-12-21 14:19:55 +00:00
parent f378068b32
commit daab92e954
5 changed files with 52 additions and 31 deletions

View file

@ -1,3 +1,12 @@
21 December 2010: Wouter
- algorithm compromise protection using the algorithms signalled in
the DS record. Also, trust anchors, DLV, and RFC5011 receive this,
and thus, if you have multiple algorithms in your trust-anchor-file
then it will now behave different than before. Also, 5011 rollover
for algorithms needs to be double-signature until the old algorithm
is revoked.
It is not an option, because I see no use to turn the security off.
17 December 2010: Wouter
- squelch 'tcp connect: bla' in logfile, (set verbosity 2 to see them).
- fix validation in this case: CNAME to nodata for co-hosted opt-in

View file

@ -972,27 +972,17 @@ verify_dnskey(struct module_env* env, struct val_env* ve,
struct trust_anchor* tp, struct ub_packed_rrset_key* rrset)
{
char* reason = NULL;
if(tp->ds_rrset) {
/* verify with ds, any will do to prime autotrust */
enum sec_status sec = val_verify_DNSKEY_with_DS(
env, ve, rrset, tp->ds_rrset, 0, &reason);
verbose(VERB_ALGO, "autotrust: validate DNSKEY with DS: %s",
sec_status_to_string(sec));
if(sec == sec_status_secure) {
return 1;
}
}
if(tp->dnskey_rrset) {
/* verify with keys */
enum sec_status sec = val_verify_rrset(env, ve, rrset,
tp->dnskey_rrset, 0, &reason);
verbose(VERB_ALGO, "autotrust: validate DNSKEY with keys: %s",
sec_status_to_string(sec));
if(sec == sec_status_secure) {
return 1;
}
}
return 0;
uint8_t sigalg[ALGO_NEEDS_MAX+1];
int downprot = 1;
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, rrset,
tp->ds_rrset, tp->dnskey_rrset, downprot?sigalg:NULL, &reason);
/* sigalg is ignored, it returns algorithms signalled to exist, but
* in 5011 there are no other rrsets to check. if downprot is
* enabled, then it checks that the DNSKEY is signed with all
* algorithms available in the trust store. */
verbose(VERB_ALGO, "autotrust: validate DNSKEY with anchor: %s",
sec_status_to_string(sec));
return sec == sec_status_secure;
}
/** Find minimum expiration interval from signatures */
@ -1024,6 +1014,8 @@ rr_is_selfsigned_revoked(struct module_env* env, struct val_env* ve,
char* reason = NULL;
verbose(VERB_ALGO, "seen REVOKE flag, check self-signed, rr %d",
(int)i);
/* no algorithm downgrade protection necessary, if it is selfsigned
* revoked it can be removed. */
sec = dnskey_verify_rrset(env, ve, dnskey_rrset, dnskey_rrset, i,
&reason);
return (sec == sec_status_secure);

View file

@ -551,8 +551,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* ta_ds,
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason)
{
/* as long as this is false, we can consider this DS rrset to be
* equivalent to no DS rrset. */
/* 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;
struct algo_needs needs;
size_t i, num;
@ -591,9 +591,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
* And check it is the strongest digest */
if(!ds_digest_algo_is_supported(ta_ds, i) ||
!ds_key_algo_is_supported(ta_ds, i) ||
ds_get_digest_algo(ta_ds, i) != digest_algo) {
ds_get_digest_algo(ta_ds, i) != digest_algo)
continue;
}
/* Once we see a single DS with a known digestID and
* algorithm, we cannot return INSECURE (with a
@ -620,9 +619,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
num = rrset_get_count(ta_dnskey);
for(i=0; i<num; i++) {
/* Check to see if we can understand this DNSKEY */
if(!dnskey_algo_is_supported(ta_dnskey, i)) {
if(!dnskey_algo_is_supported(ta_dnskey, i))
continue;
}
/* we saw a useful TA */
has_useful_ta = true;
@ -632,7 +630,7 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
if(sec == sec_status_secure) {
if(!sigalg || algo_needs_set_secure(&needs,
(uint8_t)dnskey_get_algo(ta_dnskey, i))) {
verbose(VERB_ALGO, "DS matched DNSKEY.");
verbose(VERB_ALGO, "anchor matched DNSKEY.");
return sec_status_secure;
}
} else if(sigalg && sec == sec_status_bogus) {
@ -642,7 +640,6 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
}
}
/* If no DSs were understandable, then this is OK. */
if(!has_useful_ta) {
verbose(VERB_ALGO, "No usable trust anchors were found -- "
@ -659,7 +656,7 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
}
struct key_entry_key*
val_verify_new_DNSKEYs_with_ta(struct regional* region, struct module_env* env,
val_verify_new_DNSKEYs_with_ta(struct regional* region, struct module_env* env,
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ta_ds_rrset,
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,

View file

@ -158,6 +158,27 @@ enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason);
/**
* Verify DNSKEYs with DS and DNSKEY rrset. Like val_verify_DNSKEY_with_DS
* but for a trust anchor.
* @param env: module environment (scratch buffer)
* @param ve: validator environment (verification settings)
* @param dnskey_rrset: DNSKEY rrset to verify
* @param ta_ds: DS rrset to verify with.
* @param ta_dnskey: DNSKEY rrset to verify with.
* @param sigalg: if nonNULL provide downgrade protection otherwise one
* algorithm is enough. The list of signalled algorithms is returned,
* must have enough space for ALGO_NEEDS_MAX+1.
* @param reason: reason of failure. Fixed string or alloced in scratch.
* @return: sec_status_secure if a DS matches.
* sec_status_insecure if end of trust (i.e., unknown algorithms).
* sec_status_bogus if it fails.
*/
enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ta_ds,
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason);
/**
* Verify new DNSKEYs with DS rrset. The DS contains hash values that should
* match the DNSKEY keys.

View file

@ -2241,6 +2241,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
struct key_entry_key* kkey = NULL;
enum sec_status sec = sec_status_unchecked;
char* reason = NULL;
int downprot = 1;
if(!dnskey_rrset) {
log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- "
@ -2262,7 +2263,8 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
}
/* attempt to verify with trust anchor DS and DNSKEY */
kkey = val_verify_new_DNSKEYs_with_ta(qstate->region, qstate->env, ve,
dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, 0, &reason);
dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, downprot,
&reason);
if(!kkey) {
log_err("out of memory: verifying prime TA");
return NULL;