diff --git a/src/blockdata.c b/src/blockdata.c index ba2e406..aef249e 100644 --- a/src/blockdata.c +++ b/src/blockdata.c @@ -96,18 +96,24 @@ void blockdata_free(struct blockdata *blocks) } } -void blockdata_retrieve(struct blockdata *block, size_t len, void *data) +/* copy blocks into data[], return 1 if data[] unchanged by so doing */ +int blockdata_retrieve(struct blockdata *block, size_t len, void *data) { size_t blen; struct blockdata *b; + int match = 1; for (b = block; len > 0 && b; b = b->next) { blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len; + if (memcmp(data, b->key, blen) != 0) + match = 0; memcpy(data, b->key, blen); data += blen; len -= blen; } + + return match; } - + #endif diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 6a087e4..230f35b 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -993,7 +993,7 @@ struct crec *cache_enumerate(int init); void blockdata_report(void); struct blockdata *blockdata_alloc(char *data, size_t len); size_t blockdata_walk(struct blockdata **key, unsigned char **p, size_t cnt); -void blockdata_retrieve(struct blockdata *block, size_t len, void *data); +int blockdata_retrieve(struct blockdata *block, size_t len, void *data); void blockdata_free(struct blockdata *blocks); #endif diff --git a/src/dnssec.c b/src/dnssec.c index f0f709d..f9d3aab 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -617,8 +617,8 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch from_wire(name); - /* TODO fragented digest */ - if (memcmp(digestalg_final(), recp1->addr.key.keydata->key, digestalg_len()) == 0 && + if (recp1->uid == digestalg_len() && + blockdata_retrieve(recp1->addr.key.keydata, recp1->uid, digestalg_final()) && validate_rrset(now, header, plen, class, T_DNSKEY, name, keyname, key, rdlen - 4, algo, keytag)) { struct all_addr a; @@ -717,6 +717,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char crecp->addr.key.keydata = key; crecp->addr.key.algo = algo; crecp->addr.key.keytag = keytag; + crecp->uid = rdlen - 4; } else return STAT_INSECURE; /* cache problem */