zonemd, fix to detect duplicate zonemd scheme and algo RRs.

This commit is contained in:
W.C.A. Wijngaards 2021-01-22 14:36:53 +01:00
parent 72d7587138
commit 20ff80c5bb
3 changed files with 65 additions and 1 deletions

View File

@ -1823,6 +1823,43 @@ static int zonemd_fetch_parameters(struct auth_rrset* zonemd_rrset, size_t i,
return 1;
}
/**
* See if the ZONEMD scheme, hash occurs more than once.
* @param zonemd_rrset: the zonemd rrset to check with the RRs in it.
* @param index: index of the original, this is allowed to have that
* scheme and hashalgo, but other RRs should not have it.
* @param scheme: the scheme to check for.
* @param hashalgo: the hash algorithm to check for.
* @return true if it occurs more than once.
*/
static int zonemd_is_duplicate_scheme_hash(struct auth_rrset* zonemd_rrset,
size_t index, int scheme, int hashalgo)
{
size_t j;
for(j=0; j<zonemd_rrset->data->count; j++) {
uint32_t serial2 = 0;
int scheme2 = 0, hashalgo2 = 0;
uint8_t* hash2 = NULL;
size_t hashlen2 = 0;
if(index == j) {
/* this is the original */
continue;
}
if(!zonemd_fetch_parameters(zonemd_rrset, j, &serial2,
&scheme2, &hashalgo2, &hash2, &hashlen2)) {
/* malformed, skip it */
continue;
}
if(scheme == scheme2 && hashalgo == hashalgo2) {
/* duplicate scheme, hash */
verbose(VERB_ALGO, "zonemd duplicate for scheme %d "
"and hash %d", scheme, hashalgo);
return 1;
}
}
return 0;
}
/**
* Check ZONEMDs if present for the auth zone. Depending on config
* it can warn or fail on that. Checks the hash of the ZONEMD.
@ -1875,6 +1912,15 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z,
*reason = "ZONEMD rdata malformed";
continue;
}
/* check for duplicates */
if(zonemd_is_duplicate_scheme_hash(zonemd_rrset, i, scheme,
hashalgo)) {
/* duplicate hash of the same scheme,hash
* is not allowed. */
*reason = "ZONEMD RRSet contains more than one RR "
"with the same scheme and hash algorithm";
continue;
}
regional_free_all(region);
if(serial != soa_serial) {
*reason = "ZONEMD serial is wrong";
@ -7381,7 +7427,7 @@ static void add_rrlist_rrsigs_into_data(struct packed_rrset_data* data,
data->rr_len[*done] = rrlist[i]->data->rr_len[rrlist[i]->data->count + j];
data->rr_ttl[*done] = rrlist[i]->data->rr_ttl[rrlist[i]->data->count + j];
/* reference the rdata in the rrset, no need to
* copy it, it is no longer need at the end of
* copy it, it is no longer needed at the end of
* the routine */
data->rr_data[*done] = rrlist[i]->data->rr_data[rrlist[i]->data->count + j];
(*done)++;

View File

@ -467,6 +467,13 @@ static void zonemd_verify_tests(void)
/* okay date: "20201020135527", */
"20221020135527",
"verify DNSKEY RRset with trust anchor failed: signature expired");
/* duplicate zonemd with same scheme and algorithm */
zonemd_verify_test("example.com",
"testdata/zonemd.example16.zone",
NULL,
"20180302005009",
"ZONEMD RRSet contains more than one RR with the same scheme and hash algorithm");
}
/** zonemd unit tests */

11
testdata/zonemd.example16.zone vendored Normal file
View File

@ -0,0 +1,11 @@
example.com. IN SOA ns.example.com. hostmaster.example.com. 200154054 28800 7200 604800 3600
example.com. IN NS ns.example.com.
; the ZONEMD that should be in this file, without DNSSEC
example.com. IN ZONEMD 200154054 1 2 EFAA5B78B38AB1C45DE57B8167BCCE906451D0E72118E1F5E80B5F0C3CF04BFFC65D53C011185528EAD439D6F3A02F511961E090E5E4E0DFA013BD276D728B22
; duplicate zonemd with same scheme and algorithm (different at end)
example.com. IN ZONEMD 200154054 1 2 EFAA5B78B38AB1C45DE57B8167BCCE906451D0E72118E1F5E80B5F0C3CF04BFFC65D53C011185528EAD439D6F3A02F511961E090E5E4E0DFA013BD276D720000
www.example.com. IN A 127.0.0.1
ns.example.com. IN A 127.0.0.1
bar.example.com. IN A 1.2.3.4
ding.example.com. IN A 1.2.3.4
foo.example.com. IN A 1.2.3.4