2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 05:57:52 +00:00

Add dns_zonemd functions

- dns_zonemd_buildrdata() iterates a zone database and constructs a
  ZONEMD record using the SIMPLE digest scheme described in RFC 8976.

- dns_zonemd_supported() checks a ZONEMD record and returns true if
  the scheme and hash algorithm are supported by this server. (Currently
  the only supported scheme is SIMPLE, and the supported hash algorithms
  are SHA-384 and SHA-512.)
This commit is contained in:
Mark Andrews 2021-06-23 19:52:08 +10:00 committed by Evan Hunt
parent 6229dad838
commit 21f69b010f
13 changed files with 936 additions and 64 deletions

View File

@ -56,13 +56,6 @@ isc_stats_t *dns_dnssec_stats;
static isc_result_t
digest_callback(void *arg, isc_region_t *data);
static int
rdata_compare_wrapper(const void *rdata1, const void *rdata2);
static isc_result_t
rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
dns_rdata_t **rdata, int *nrdata);
static isc_result_t
digest_callback(void *arg, isc_region_t *data) {
dst_context_t *ctx = arg;
@ -77,57 +70,6 @@ inc_stat(isc_statscounter_t counter) {
}
}
/*
* Make qsort happy.
*/
static int
rdata_compare_wrapper(const void *rdata1, const void *rdata2) {
return dns_rdata_compare((const dns_rdata_t *)rdata1,
(const dns_rdata_t *)rdata2);
}
/*
* Sort the rdataset into an array.
*/
static isc_result_t
rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
dns_rdata_t **rdata, int *nrdata) {
isc_result_t ret;
int i = 0, n;
dns_rdata_t *data;
dns_rdataset_t rdataset;
n = dns_rdataset_count(set);
data = isc_mem_cget(mctx, n, sizeof(dns_rdata_t));
dns_rdataset_init(&rdataset);
dns_rdataset_clone(set, &rdataset);
ret = dns_rdataset_first(&rdataset);
if (ret != ISC_R_SUCCESS) {
dns_rdataset_disassociate(&rdataset);
isc_mem_cput(mctx, data, n, sizeof(dns_rdata_t));
return ret;
}
/*
* Put them in the array.
*/
do {
dns_rdata_init(&data[i]);
dns_rdataset_current(&rdataset, &data[i++]);
} while (dns_rdataset_next(&rdataset) == ISC_R_SUCCESS);
/*
* Sort the array.
*/
qsort(data, n, sizeof(dns_rdata_t), rdata_compare_wrapper);
*rdata = data;
*nrdata = n;
dns_rdataset_disassociate(&rdataset);
return ISC_R_SUCCESS;
}
isc_result_t
dns_dnssec_keyfromrdata(const dns_name_t *name, const dns_rdata_t *rdata,
isc_mem_t *mctx, dst_key_t **key) {
@ -183,8 +125,8 @@ dns_dnssec_sign(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata) {
dns_rdata_rrsig_t sig;
dns_rdata_t tmpsigrdata;
dns_rdata_t *rdatas;
int nrdatas, i;
dns_rdata_t *rdatas = NULL;
unsigned int nrdatas, i;
isc_buffer_t sigbuf, envbuf;
isc_region_t r;
dst_context_t *ctx = NULL;
@ -280,7 +222,7 @@ dns_dnssec_sign(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
isc_buffer_putuint16(&envbuf, set->rdclass);
isc_buffer_putuint32(&envbuf, set->ttl);
ret = rdataset_to_sortedarray(set, mctx, &rdatas, &nrdatas);
ret = dns_rdataset_tosortedarray(set, mctx, &rdatas, &nrdatas);
if (ret != ISC_R_SUCCESS) {
goto cleanup_context;
}
@ -360,8 +302,8 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
dns_fixedname_t fnewname;
isc_region_t r;
isc_buffer_t envbuf;
dns_rdata_t *rdatas;
int nrdatas, i;
dns_rdata_t *rdatas = NULL;
unsigned int nrdatas, i;
isc_stdtime_t now;
isc_result_t ret;
unsigned char data[300];
@ -476,7 +418,7 @@ again:
isc_buffer_putuint16(&envbuf, set->rdclass);
isc_buffer_putuint32(&envbuf, sig.originalttl);
ret = rdataset_to_sortedarray(set, mctx, &rdatas, &nrdatas);
ret = dns_rdataset_tosortedarray(set, mctx, &rdatas, &nrdatas);
if (ret != ISC_R_SUCCESS) {
goto cleanup_context;
}

View File

@ -413,6 +413,23 @@ dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
*\li 'rdataset'.
*/
isc_result_t
dns_rdataset_tosortedarray(dns_rdataset_t *rdataset, isc_mem_t *mctx,
dns_rdata_t **rdata, unsigned int *nrdata);
/*%<
* Sort the rdata that make up the 'rdataset' in the the array 'rdata'
* in DNSSEC order with the length of the array returned in 'nrdata'.
*
* Requires:
*\li 'rdataset' is a valid, associated rdataset.
*
*\li 'mctx' is valid.
*
*\li 'rdata' is non-NULL and '*rdata' is NULL.
*
*\li 'nrdata' is non-NULL.
*/
isc_result_t
dns_rdataset_totext(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
bool omit_final_dot, bool question, isc_buffer_t *target);

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
#include <dns/types.h>
#define DNS_ZONEMD_BUFFERSIZE (6U + 64U)
isc_result_t
dns_zonemd_buildrdata(dns_rdata_t *rdata, dns_db_t *db,
dns_dbversion_t *version, uint8_t scheme,
uint8_t algorithm, isc_mem_t *mctx, unsigned char *buf,
size_t size);
bool
dns_zonemd_supported(dns_rdata_t *rdata);

View File

@ -160,6 +160,7 @@ dns_srcset.add(
'validator.c',
'view.c',
'zone.c',
'zonemd.c',
'zoneverify.c',
'zt.c',
),

View File

@ -657,3 +657,51 @@ dns_rdataset_equals(const dns_rdataset_t *rdataset1,
return false;
}
static int
rdata_compare_wrapper(const void *rdata1, const void *rdata2) {
return dns_rdata_compare((const dns_rdata_t *)rdata1,
(const dns_rdata_t *)rdata2);
}
isc_result_t
dns_rdataset_tosortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
dns_rdata_t **rdata, unsigned int *nrdata) {
isc_result_t ret;
int i = 0, n;
dns_rdata_t *data = NULL;
dns_rdataset_t rdataset;
REQUIRE(rdata != NULL && *rdata == NULL);
REQUIRE(nrdata != NULL);
n = dns_rdataset_count(set);
data = isc_mem_cget(mctx, n, sizeof(dns_rdata_t));
dns_rdataset_init(&rdataset);
dns_rdataset_clone(set, &rdataset);
ret = dns_rdataset_first(&rdataset);
if (ret != ISC_R_SUCCESS) {
dns_rdataset_disassociate(&rdataset);
isc_mem_cput(mctx, data, n, sizeof(dns_rdata_t));
return ret;
}
/*
* Put them in the array.
*/
do {
dns_rdata_init(&data[i]);
dns_rdataset_current(&rdataset, &data[i++]);
} while (dns_rdataset_next(&rdataset) == ISC_R_SUCCESS);
/*
* Sort the array.
*/
qsort(data, n, sizeof(dns_rdata_t), rdata_compare_wrapper);
*rdata = data;
*nrdata = n;
dns_rdataset_disassociate(&rdataset);
return ISC_R_SUCCESS;
}

441
lib/dns/zonemd.c Normal file
View File

@ -0,0 +1,441 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#include <isc/heap.h>
#include <isc/md.h>
#include <isc/mem.h>
#include <isc/result.h>
#include <isc/string.h>
#include <isc/util.h>
#include <dns/db.h>
#include <dns/dbiterator.h>
#include <dns/name.h>
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
#include <dns/rdatastruct.h>
#include <dns/result.h>
#include <dns/zonemd.h>
#define CHECK(r) \
do { \
result = (r); \
if (result != ISC_R_SUCCESS) \
goto cleanup; \
} while (0)
static isc_result_t
digest_callback(void *arg, isc_region_t *data) {
#ifdef ISC_ZONEMD_DEBUG
unsigned int j;
for (j = 0; j < data->length; j++) {
fprintf(stderr, "%02x", data->base[j]);
}
#endif
return isc_md_update(arg, data->base, data->length);
}
static isc_result_t
digest_rdataset(dns_name_t *name, dns_rdataset_t *rds, isc_mem_t *mctx,
isc_md_t *md) {
dns_fixedname_t fixed;
isc_region_t r;
char data[256 + 8];
isc_buffer_t envbuf;
isc_result_t result;
dns_rdata_t *rdatas = NULL;
unsigned int i, nrdatas;
#ifdef ISC_ZONEMD_DEBUG
char namebuf[DNS_NAME_FORMATSIZE];
#endif
dns_fixedname_init(&fixed);
RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fixed)) ==
ISC_R_SUCCESS);
dns_name_toregion(dns_fixedname_name(&fixed), &r);
#ifdef ISC_ZONEMD_DEBUG
dns_name_format(dns_fixedname_name(&fixed), namebuf, sizeof(namebuf));
#endif
/*
* Create an envelope for each rdata: <name|type|class|ttl>.
*/
isc_buffer_init(&envbuf, data, sizeof(data));
memmove(data, r.base, r.length);
isc_buffer_add(&envbuf, r.length);
isc_buffer_putuint16(&envbuf, rds->type);
isc_buffer_putuint16(&envbuf, rds->rdclass);
isc_buffer_putuint32(&envbuf, rds->ttl);
CHECK(dns_rdataset_tosortedarray(rds, mctx, &rdatas, &nrdatas));
isc_buffer_usedregion(&envbuf, &r);
for (i = 0; i < nrdatas; i++) {
unsigned char len[2];
/*
* Skip duplicates.
*/
if (i > 0 && dns_rdata_compare(&rdatas[i], &rdatas[i - 1]) == 0)
{
continue;
}
/*
* Digest the envelope.
*/
CHECK(isc_md_update(md, r.base, r.length));
/*
* Digest the length of the rdata.
*/
len[0] = rdatas[i].length >> 8;
len[1] = rdatas[i].length & 0xff;
CHECK(isc_md_update(md, len, 2));
#ifdef ISC_ZONEMD_DEBUG
isc_buffer_t b;
char rdatabuf[65 * 1024];
unsigned int j;
isc_buffer_init(&b, rdatabuf, sizeof(rdatabuf));
dns_rdata_totext(&rdatas[i], NULL, &b);
fprintf(stderr,
"digest %s type=%u class=%u ttl=%u rdlen=%u %.*s\n",
namebuf, rds->type, rds->rdclass, rds->ttl,
rdatas[i].length, (int)isc_buffer_usedlength(&b),
rdatabuf);
fprintf(stderr, "DIGEST:");
for (j = 0; j < r.length; j++) {
fprintf(stderr, "%02x", r.base[j]);
}
fprintf(stderr, "%02x%02x", len[0], len[1]);
#endif
/*
* Digest the rdata.
*/
CHECK(dns_rdata_digest(&rdatas[i], digest_callback, md));
#ifdef ISC_ZONEMD_DEBUG
fprintf(stderr, "\n");
#endif
}
cleanup:
if (rdatas != NULL) {
isc_mem_cput(mctx, rdatas, nrdatas, sizeof(*rdatas));
}
return result;
}
static isc_result_t
get_serial(dns_rdataset_t *rds, unsigned char *buf) {
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_soa_t soa;
isc_result_t result;
CHECK(dns_rdataset_first(rds));
dns_rdataset_current(rds, &rdata);
CHECK(dns_rdata_tostruct(&rdata, &soa, NULL));
buf[0] = (soa.serial >> 24) & 0xff;
buf[1] = (soa.serial >> 16) & 0xff;
buf[2] = (soa.serial >> 8) & 0xff;
buf[3] = (soa.serial >> 0) & 0xff;
cleanup:
return result;
}
static bool
bytype(void *a, void *b) {
dns_rdataset_t *ra = (dns_rdataset_t *)a, *rb = (dns_rdataset_t *)b;
if (ra->type < rb->type) {
return true;
}
if (ra->type != dns_rdatatype_rrsig) {
return false;
}
if (ra->covers < rb->covers) {
return true;
}
return false;
}
static isc_result_t
add_rdatasets(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
isc_mem_t *mctx, isc_heap_t *heap) {
dns_rdatasetiter_t *iter = NULL;
isc_result_t result;
CHECK(dns_db_allrdatasets(db, node, version, 0, 0, &iter));
DNS_RDATASETITER_FOREACH(iter) {
dns_rdataset_t *rdataset = isc_mem_get(mctx, sizeof(*rdataset));
dns_rdataset_init(rdataset);
dns_rdatasetiter_current(iter, rdataset);
isc_heap_insert(heap, rdataset);
}
cleanup:
if (iter != NULL) {
dns_rdatasetiter_destroy(&iter);
}
return result;
}
static isc_result_t
process_name(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
dns_dbnode_t *nsecnode, dns_dbnode_t *nsec3node, isc_heap_t *heap,
isc_mem_t *mctx, unsigned char *buf, isc_md_t *md,
bool *seen_soa) {
dns_rdataset_t *rdataset = NULL;
isc_result_t result = ISC_R_SUCCESS;
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(name, namebuf, sizeof(namebuf));
if (!dns_name_issubdomain(name, dns_db_origin(db))) {
#ifdef ISC_ZONEMD_DEBUG
fprintf(stderr, "skipping %s out-of-zone\n", namebuf);
#endif
return ISC_R_SUCCESS;
}
if (nsecnode != NULL) {
CHECK(add_rdatasets(db, version, nsecnode, mctx, heap));
}
if (nsec3node != NULL) {
CHECK(add_rdatasets(db, version, nsec3node, mctx, heap));
}
while ((rdataset = isc_heap_element(heap, 1)) != NULL) {
#ifdef ISC_ZONEMD_DEBUG
fprintf(stderr, "looking at %s %u/%u\n", namebuf,
rdataset->type, rdataset->covers);
#endif
/*
* Don't digest ZONEMD or RRSIG(ZONEMD).
*/
if ((rdataset->type == dns_rdatatype_zonemd ||
(rdataset->type == dns_rdatatype_rrsig &&
rdataset->covers == dns_rdatatype_zonemd)) &&
dns_name_equal(name, dns_db_origin(db)))
{
goto skip;
}
if (rdataset->type == dns_rdatatype_soa &&
dns_name_equal(name, dns_db_origin(db)))
{
CHECK(get_serial(rdataset, buf));
*seen_soa = true;
}
CHECK(digest_rdataset(name, rdataset, mctx, md));
skip:
isc_heap_delete(heap, 1);
dns_rdataset_disassociate(rdataset);
isc_mem_put(mctx, rdataset, sizeof(*rdataset));
}
cleanup:
while ((rdataset = isc_heap_element(heap, 1)) != NULL) {
isc_heap_delete(heap, 1);
dns_rdataset_disassociate(rdataset);
isc_mem_put(mctx, rdataset, sizeof(*rdataset));
}
return result;
}
static isc_result_t
zonemd_simple(dns_rdata_t *rdata, dns_db_t *db, dns_dbversion_t *version,
uint8_t algorithm, isc_mem_t *mctx, unsigned char *buf,
size_t size) {
bool seen_soa = false;
dns_dbiterator_t *nsecdbiter = NULL;
dns_dbiterator_t *nsec3dbiter = NULL;
dns_dbnode_t *nsecnode = NULL;
dns_dbnode_t *nsec3node = NULL;
dns_fixedname_t nsecfixed;
dns_fixedname_t nsec3fixed;
dns_name_t *nsecname;
dns_name_t *nsec3name;
isc_md_t *md = isc_md_new();
isc_heap_t *heap = NULL;
isc_result_t result, nsecresult, nsec3result;
isc_region_t r;
if (md == NULL) {
CHECK(ISC_R_NOMEMORY);
}
switch (algorithm) {
case DNS_ZONEMD_DIGEST_SHA384:
if (size < ISC_SHA384_DIGESTLENGTH + 6) {
CHECK(ISC_R_NOSPACE);
}
r.base = buf;
r.length = ISC_SHA384_DIGESTLENGTH + 6;
CHECK(isc_md_init(md, ISC_MD_SHA384));
break;
case DNS_ZONEMD_DIGEST_SHA512:
if (size < ISC_SHA512_DIGESTLENGTH + 6) {
CHECK(ISC_R_NOSPACE);
}
r.base = buf;
r.length = ISC_SHA512_DIGESTLENGTH + 6;
CHECK(isc_md_init(md, ISC_MD_SHA512));
break;
default:
CHECK(ISC_R_NOTIMPLEMENTED);
}
dns_fixedname_init(&nsecfixed);
dns_fixedname_init(&nsec3fixed);
isc_heap_create(mctx, bytype, NULL, 0, &heap);
CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &nsecdbiter));
CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &nsec3dbiter));
nsecresult = dns_dbiterator_first(nsecdbiter);
nsec3result = dns_dbiterator_first(nsec3dbiter);
while (nsecresult == ISC_R_SUCCESS || nsec3result == ISC_R_SUCCESS) {
if (nsecresult == ISC_R_SUCCESS) {
nsecname = dns_fixedname_name(&nsecfixed);
CHECK(dns_dbiterator_current(nsecdbiter, &nsecnode,
nsecname));
dns_dbiterator_pause(nsecdbiter);
} else {
nsecname = NULL;
}
if (nsec3result == ISC_R_SUCCESS) {
nsec3name = dns_fixedname_name(&nsec3fixed);
CHECK(dns_dbiterator_current(nsec3dbiter, &nsec3node,
nsec3name));
dns_dbiterator_pause(nsec3dbiter);
} else {
nsec3name = NULL;
}
/*
* Workout which name / node to process next.
*/
if (nsecname != NULL && nsec3name != NULL) {
int n = dns_name_compare(nsecname, nsec3name);
if (n < 0) {
nsec3name = NULL;
if (nsec3node != NULL) {
dns_db_detachnode(&nsec3node);
}
}
if (n > 0) {
nsecname = NULL;
if (nsecnode != NULL) {
dns_db_detachnode(&nsecnode);
}
}
}
CHECK(process_name(
db, version, nsecname != NULL ? nsecname : nsec3name,
nsecnode, nsec3node, heap, mctx, buf, md, &seen_soa));
if (nsecnode != NULL) {
dns_db_detachnode(&nsecnode);
}
if (nsec3node != NULL) {
dns_db_detachnode(&nsec3node);
}
if (nsecname != NULL) {
nsecresult = dns_dbiterator_next(nsecdbiter);
}
if (nsec3name != NULL) {
nsec3result = dns_dbiterator_next(nsec3dbiter);
}
}
if (nsecresult == ISC_R_NOMORE && nsec3result == ISC_R_NOMORE) {
unsigned int len = size - 6;
buf[4] = 1;
buf[5] = algorithm;
CHECK(isc_md_final(md, buf + 6, &len));
if (!seen_soa) {
CHECK(DNS_R_BADZONE);
}
if (len + 6 != r.length) {
CHECK(ISC_R_FAILURE);
}
if (rdata != NULL) {
dns_rdata_fromregion(rdata, dns_db_class(db),
dns_rdatatype_zonemd, &r);
}
} else {
result = nsecresult != ISC_R_NOMORE ? nsecresult : nsec3result;
}
cleanup:
if (md != NULL) {
isc_md_free(md);
}
if (heap != NULL) {
isc_heap_destroy(&heap);
}
if (nsecnode != NULL) {
dns_db_detachnode(&nsecnode);
}
if (nsec3node != NULL) {
dns_db_detachnode(&nsec3node);
}
if (nsecdbiter != NULL) {
dns_dbiterator_destroy(&nsecdbiter);
}
if (nsec3dbiter != NULL) {
dns_dbiterator_destroy(&nsec3dbiter);
}
return result;
}
isc_result_t
dns_zonemd_buildrdata(dns_rdata_t *rdata, dns_db_t *db,
dns_dbversion_t *version, uint8_t scheme,
uint8_t algorithm, isc_mem_t *mctx, unsigned char *buf,
size_t size) {
REQUIRE(db != NULL);
REQUIRE(buf != NULL);
/*
* Check for supported scheme/algorithm combinations.
*/
switch (scheme) {
case DNS_ZONEMD_SCHEME_SIMPLE:
switch (algorithm) {
case DNS_ZONEMD_DIGEST_SHA384:
case DNS_ZONEMD_DIGEST_SHA512:
return zonemd_simple(rdata, db, version, algorithm,
mctx, buf, size);
default:
return ISC_R_NOTIMPLEMENTED;
}
default:
return ISC_R_NOTIMPLEMENTED;
}
}
bool
dns_zonemd_supported(dns_rdata_t *rdata) {
REQUIRE(rdata != NULL);
REQUIRE(rdata->length >= 6);
REQUIRE(rdata->type == dns_rdatatype_zonemd);
switch (rdata->data[4]) {
case DNS_ZONEMD_SCHEME_SIMPLE:
switch (rdata->data[5]) {
case DNS_ZONEMD_DIGEST_SHA384:
case DNS_ZONEMD_DIGEST_SHA512:
return true;
default:
return false;
}
default:
return false;
}
}

View File

@ -44,6 +44,7 @@ dns_tests = [
'unreachcache',
'update',
'zonefile',
'zonemd',
'zonemgr',
'zt',
]

View File

@ -0,0 +1,13 @@
example. 86400 IN SOA ns1 admin 2018031900 (
1800 900 604800 86400 )
86400 IN NS ns1
86400 IN NS ns2
86400 IN ZONEMD 2018031900 1 1 (
c68090d90a7aed71
6bc459f9340e3d7c
1370d4d24b7e2fc3
a1ddc0b9a87153b9
a9713b3c9ae5cc27
777f98b8e730044c )
ns1 3600 IN A 203.0.113.63
ns2 3600 IN AAAA 2001:db8::63

View File

@ -0,0 +1,34 @@
example. 86400 IN SOA ns1 admin 2018031900 (
1800 900 604800 86400 )
86400 IN NS ns1
86400 IN NS ns2
86400 IN ZONEMD 2018031900 1 1 (
a3b69bad980a3504
e1cffcb0fd6397f9
3848071c93151f55
2ae2f6b1711d4bd2
d8b39808226d7b9d
b71e34b72077f8fe )
ns1 3600 IN A 203.0.113.63
NS2 3600 IN AAAA 2001:db8::63
occluded.sub 7200 IN TXT "I'm occluded but must be digested"
sub 7200 IN NS ns1
duplicate 300 IN TXT "I must be digested just once"
duplicate 300 IN TXT "I must be digested just once"
foo.test. 555 IN TXT "out-of-zone data must be excluded"
UPPERCASE 3600 IN TXT "canonicalize uppercase owner names"
* 777 IN PTR dont-forget-about-wildcards
mail 3600 IN MX 20 MAIL1
mail 3600 IN MX 10 Mail2.Example.
sortme 3600 IN AAAA 2001:db8::5:61
sortme 3600 IN AAAA 2001:db8::3:62
sortme 3600 IN AAAA 2001:db8::4:63
sortme 3600 IN AAAA 2001:db8::1:65
sortme 3600 IN AAAA 2001:db8::2:64
non-apex 900 IN ZONEMD 2018031900 1 1 (
616c6c6f77656420
6275742069676e6f
7265642e20616c6c
6f77656420627574
2069676e6f726564
2e20616c6c6f7765 )

View File

@ -0,0 +1,30 @@
example. 86400 IN SOA ns1 admin 2018031900 (
1800 900 604800 86400 )
example. 86400 IN NS ns1.example.
example. 86400 IN NS ns2.example.
example. 86400 IN ZONEMD 2018031900 1 1 (
62e6cf51b02e54b9
b5f967d547ce4313
6792901f9f88e637
493daaf401c92c27
9dd10f0edb1c56f8
080211f8480ee306 )
example. 86400 IN ZONEMD 2018031900 1 2 (
08cfa1115c7b948c
4163a901270395ea
226a930cd2cbcf2f
a9a5e6eb85f37c8a
4e114d884e66f176
eab121cb02db7d65
2e0cc4827e7a3204
f166b47e5613fd27 )
example. 86400 IN ZONEMD 2018031900 1 240 (
e2d523f654b9422a
96c5a8f44607bbee )
example. 86400 IN ZONEMD 2018031900 241 1 (
e1846540e33a9e41
89792d18d5d131f6
05fc283e )
ns1.example. 3600 IN A 203.0.113.63
ns2.example. 86400 IN TXT "This example has multiple digests"
NS2.EXAMPLE. 3600 IN AAAA 2001:db8::63

128
tests/dns/testdata/zonemd/rfc8976.A.4.db vendored Normal file
View File

@ -0,0 +1,128 @@
uri.arpa. 3600 IN SOA sns.dns.icann.org. (
noc.dns.icann.org. 2018100702 10800 3600 1209600 3600 )
uri.arpa. 3600 IN RRSIG SOA 8 2 3600 (
20210217232440 20210120232440 37444 uri.arpa.
GzQw+QzwLDJr13REPGVmpEChjD1D2XlX0ie1DnWHpgaEw1E/dhs3lCN3+B
mHd4Kx3tffTRgiyq65HxR6feQ5v7VmAifjyXUYB1DZur1eP5q0Ms2ygCB3
byoeMgCNsFS1oKZ2LdzNBRpy3oace8xQn1SpmHGfyrsgg+WbHKCT1dY= )
uri.arpa. 86400 IN NS a.iana-servers.net.
uri.arpa. 86400 IN NS b.iana-servers.net.
uri.arpa. 86400 IN NS c.iana-servers.net.
uri.arpa. 86400 IN NS ns2.lacnic.net.
uri.arpa. 86400 IN NS sec3.apnic.net.
uri.arpa. 86400 IN RRSIG NS 8 2 86400 (
20210217232440 20210120232440 37444 uri.arpa.
M+Iei2lcewWGaMtkPlrhM9FpUAHXFkCHTVpeyrjxjEONeNgKtHZor5e4V4
qJBOzNqo8go/qJpWlFBm+T5Hn3asaBZVstFIYky38/C8UeRLPKq1hTTHAR
YUlFrexr5fMtSUAVOgOQPSBfH3xBq/BgSccTdRb9clD+HE7djpqrLS4= )
uri.arpa. 600 IN MX 10 pechora.icann.org.
uri.arpa. 600 IN RRSIG MX 8 2 600 (
20210217232440 20210120232440 37444 uri.arpa.
kQAJQivmv6A5hqYBK8h6Z13ESY69gmosXwKI6WE09I8RFetfrxr24ecdnY
d0lpnDtgNNSoHkYRSOoB+C4+zuJsoyAAzGo9uoWMWj97/2xeGhf3PTC9me
Q9Ohi6hul9By7OR76XYmGhdWX8PBi60RUmZ1guslFBfQ8izwPqzuphs= )
uri.arpa. 3600 IN DNSKEY 256 3 8 (
AwEAAbMxuFuLeVDuOwIMzYOTD/bTREjLflo7wOi6ieIJhqltEzgjNzmWJf
9kGwwDmzxU7kbthMEhBNBZNn84zmcyRSCMzuStWveL7xmqqUlE3swL8kLO
vdZvc75XnmpHrk3ndTyEb6eZM7slh2C63Oh6K8VR5VkiZAkEGg0uZIT3Nj
sF )
uri.arpa. 3600 IN DNSKEY 257 3 8 (
AwEAAdkTaWkZtZuRh7/OobBUFxM+ytTst+bCu0r9w+rEwXD7GbDs0pIMhM
enrZzoAvmv1fQxw2MGs6Ri6yPKfNULcFOSt9l8i6BVBLI+SKTY6XXeDUQp
SEmSaxohHeRPMQFzpysfjxINp/L2rGtZ7yPmxY/XRiFPSO0myqwGJa9r06
Zw9CHM5UDHKWV/E+zxPFq/I7CfPbrrzbUotBX7Z6Vh3Sarllbe8cGUB2UF
NaTRgwB0TwDBPRD5ER3w2Dzbry9NhbElTr7vVfhaGWeOGuqAUXwlXEg6Cr
NkmJXJ2F1Rzr9WHUzhp7uWxhAbmJREGfi2dEyPAbUAyCjBqhFaqglknvc= )
uri.arpa. 3600 IN DNSKEY 257 3 8 (
AwEAAenQaBoFmDmvRT+/H5oNbm0Tr5FmNRNDEun0Jpj/ELkzeUrTWhNpQm
ZeIMC8I0kZ185tEvOnRvn8OvV39B17QIdrvvKGIh2HlgeDRCLolhaojfn2
QM0DStjF/WWHpxJOmE6CIuvhqYEU37yoJscGAPpPVPzNvnL1HhYTaao1VR
YWQ/maMrJ+bfHg+YX1N6M/8MnRjIKBif1FWjbCKvsn6dnuGGL9oCWYUFJ3
DwofXuhgPyZMkzPc88YkJj5EMvbMH4wtelbCwC+ivx732l0w/rXJn0ciQS
OgoeVvDio8dIJmWQITWQAuP+q/ZHFEFHPlrP3gvQh5mcVS48eLX71Bq7c= )
uri.arpa. 3600 IN RRSIG DNSKEY 8 2 3600 (
20210217232440 20210120232440 12670 uri.arpa.
DBE2gkKAoxJCfz47KKxzoImN/0AKArhIVHE7TyTwy0DdRPo44V5R+vL6th
UxlQ1CJi2Rw0jwAXymx5Y3Q873pOEllH+4bJoIT4dmoBmPXfYWW7Clvw9U
PKHRP0igKHmCVwIeBYDTU3gfLcMTbR4nEWPDN0GxlL1Mf7ITaC2Ioabo79
Ip3M/MR8I3Vx/xZ4ZKKPHtLn3xUuJluPNanqJrED2gTslL2xWZ1tqjsAjJ
v7JnJo2HJ8XVRB5zBto0IaJ2oBlqcjdcQ/0VlyoM8uOy1pDwHQ2BJl7322
gNMHBP9HSiUPIOaIDNUCwW8eUcW6DIUk+s9u3GN1uTqwWzsYB/rA== )
uri.arpa. 3600 IN RRSIG DNSKEY 8 2 3600 (
20210217232440 20210120232440 30577 uri.arpa.
Kx6HwP4UlkGc1UZ7SERXtQjPajOF4iUvkwDj7MEG1xbQFB1KoJiEb/eiW0
qmSWdIhMDv8myhgauejRLyJxwxz8HDRV4xOeHWnRGfWBk4XGYwkejVzOHz
oIArVdUVRbr2JKigcTOoyFN+uu52cNB7hRYu7dH5y1hlc6UbOnzRpMtGxc
gVyKQ+/ARbIqGG3pegdEOvV49wTPWEiyY65P2urqhvnRg5ok/jzwAdMx4X
Gshiib7Ojq0sRVl2ZIzj4rFgY/qsSO8SEXEhMo2VuSkoJNiofVzYoqpxEe
GnANkIT7Tx2xJL1BWyJxyc7E8Wr2QSgCcc+rYL6IkHDtJGHy7TaQ== )
uri.arpa. 3600 IN ZONEMD 2018100702 1 1 (
0dbc3c4dbfd75777c12ca19c337854b1577799901307c482e9d91d5d15
cd934d16319d98e30c4201cf25a1d5a0254960 )
uri.arpa. 3600 IN RRSIG ZONEMD 8 2 3600 (
20210217232440 20210120232440 37444 uri.arpa.
QDo4XZcL3HMyn8aAHyCUsu/Tqj4Gkth8xY1EqByOb8XOTwVtA4ZNQORE1s
iqNqjtJUbeJPtJSbLNqCL7rCq0CzNNnBscv6IIf4gnqJZjlGtHO30ohXtK
vEc4z7SU3IASsi6bB3nLmEAyERdYSeU6UBfx8vatQDIRhkgEnnWUTh4= )
uri.arpa. 3600 IN NSEC ftp.uri.arpa. (
NS SOA MX RRSIG NSEC DNSKEY ZONEMD )
uri.arpa. 3600 IN RRSIG NSEC 8 2 3600 (
20210217232440 20210120232440 37444 uri.arpa.
dU/rXLM/naWd1+1PiWiYVaNJyCkiuyZJSccr91pJI673T8r3685B4ODMYF
afZRboVgwnl3ZrXddY6xOhZL3n9V9nxXZwjLJ2HJUojFoKcXTlpnUyYUYv
VQ2kj4GHAo6fcGCEp5QFJ2KbCpeJoS+PhKGRRx28icCiNT4/uXQvO2E= )
ftp.uri.arpa. 604800 IN NAPTR 0 0 "" "" (
"!^ftp://([^:/?#]*).*$!\\1!i" . )
ftp.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 (
20210217232440 20210120232440 37444 uri.arpa.
EygekDgl+Lyyq4NMSEpPyOrOywYf9Y3FAB4v1DT44J3R5QGidaH8l7ZFjH
oYFI8sY64iYOCV4sBnX/dh6C1L5NgpY+8l5065Xu3vvjyzbtuJ2k6YYwJr
rCbvl5DDn53zAhhO2hL9uLgyLraZGi9i7TFGd0sm3zNyUF/EVL0CcxU= )
ftp.uri.arpa. 3600 IN NSEC http.uri.arpa. (
NAPTR RRSIG NSEC )
ftp.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 (
20210217232440 20210120232440 37444 uri.arpa.
pbP4KxevPXCu/bDqcvXiuBppXyFEmtHyiy0eAN5gS7mi6mp9Z9bWFjx/Ld
H9+6oFGYa5vGmJ5itu/4EDMe8iQeZbI8yrpM4TquB7RR/MGfBnTd8S+sjy
QtlRYG7yqEu77Vd78Fme22BKPJ+MVqjS0JHMUE/YUGomPkAjLJJwwGw= )
http.uri.arpa. 604800 IN NAPTR 0 0 "" "" (
"!^http://([^:/?#]*).*$!\\1!i" . )
http.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 (
20210217232440 20210120232440 37444 uri.arpa.
eTqbWvt1GvTeXozuvm4ebaAfkXFQKrtdu0cEiExto80sHIiCbO0WL8UDa/
J3cDivtQca7LgUbOb6c17NESsrsVkc6zNPx5RK2tG7ZQYmhYmtqtfg1oU5
BRdHZ5TyqIXcHlw9Blo2pir1Y9IQgshhD7UOGkbkEmvB1Lrd0aHhAAg= )
http.uri.arpa. 3600 IN NSEC mailto.uri.arpa. (
NAPTR RRSIG NSEC )
http.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 (
20210217232440 20210120232440 37444 uri.arpa.
R9rlNzw1CVz2N08q6DhULzcsuUm0UKcPaGAWEU40tr81jEDHsFHNM+khCd
OI8nDstzA42aee4rwCEgijxJpRCcY9hrO1Ysrrr2fdqNz60JikMdarvU5O
0p0VXeaaJDfJQT44+o+YXaBwI7Qod3FTMx7aRib8i7istvPm1Rr7ixA= )
mailto.uri.arpa. 604800 IN NAPTR 0 0 "" "" (
"!^mailto:(.*)@(.*)$!\\2!i" . )
mailto.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 (
20210217232440 20210120232440 37444 uri.arpa.
Ch2zTG2F1plEvQPyIH4Yd80XXLjXOPvMbiqDjpJBcnCJsV8QF7kr0wTLnU
T3dB+asQudOjPyzaHGwFlMzmrrAsszN4XAMJ6htDtFJdsgTMP/NkHhYRSm
Vv6rLeAhd+mVfObY12M//b/GGVTjeUI/gJaLW0fLVZxr1Fp5U5CRjyw= )
mailto.uri.arpa. 3600 IN NSEC urn.uri.arpa. (
NAPTR RRSIG NSEC )
mailto.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 (
20210217232440 20210120232440 37444 uri.arpa.
fQUbSIE6E7JDi2rosah4SpCOTrKufeszFyj5YEavbQuYlQ5cNFvtm8KuE2
xXMRgRI4RGvM2leVqcoDw5hS3m2pOJLxH8l2WE72YjYvWhvnwc5Rofe/8y
B/vaSK9WCnqN8y2q6Vmy73AGP0fuiwmuBra7LlkOiqmyx3amSFizwms= )
urn.uri.arpa. 604800 IN NAPTR 0 0 "" "" (
"/urn:([^:]+)/\\1/i" . )
urn.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 (
20210217232440 20210120232440 37444 uri.arpa.
CVt2Tgz0e5ZmaSXqRfNys/8OtVCk9nfP0zhezhN8Bo6MDt6yyKZ2kEEWJP
jkN7PCYHjO8fGjnUn0AHZI2qBNv7PKHcpR42VY03q927q85a65weOO1YE0
vPYMzACpua9TOtfNnynM2Ws0uN9URxUyvYkXBdqOC81N3sx1dVELcwc= )
urn.uri.arpa. 3600 IN NSEC uri.arpa. NAPTR RRSIG NSEC
urn.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 (
20210217232440 20210120232440 37444 uri.arpa.
JuKkMiC3/j9iM3V8/izcouXWAVGnSZjkOgEgFPhutMqoylQNRcSkbEZQzF
K8B/PIVdzZF0Y5xkO6zaKQjOzz6OkSaNPIo1a7Vyyl3wDY/uLCRRAHRJfp
knuY7O+AUNXvVVIEYJqZggd4kl/Rjh1GTzPYZTRrVi5eQidI1LqCOeg= )

View File

@ -0,0 +1,48 @@
root-servers.net. 3600000 IN SOA a.root-servers.net. (
nstld.verisign-grs.com. 2018091100 14400 7200 1209600 3600000 )
root-servers.net. 3600000 IN NS a.root-servers.net.
root-servers.net. 3600000 IN NS b.root-servers.net.
root-servers.net. 3600000 IN NS c.root-servers.net.
root-servers.net. 3600000 IN NS d.root-servers.net.
root-servers.net. 3600000 IN NS e.root-servers.net.
root-servers.net. 3600000 IN NS f.root-servers.net.
root-servers.net. 3600000 IN NS g.root-servers.net.
root-servers.net. 3600000 IN NS h.root-servers.net.
root-servers.net. 3600000 IN NS i.root-servers.net.
root-servers.net. 3600000 IN NS j.root-servers.net.
root-servers.net. 3600000 IN NS k.root-servers.net.
root-servers.net. 3600000 IN NS l.root-servers.net.
root-servers.net. 3600000 IN NS m.root-servers.net.
a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
a.root-servers.net. 3600000 IN A 198.41.0.4
b.root-servers.net. 3600000 IN MX 20 mail.isi.edu.
b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
b.root-servers.net. 3600000 IN A 199.9.14.201
c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
c.root-servers.net. 3600000 IN A 192.33.4.12
d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
d.root-servers.net. 3600000 IN A 199.7.91.13
e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
e.root-servers.net. 3600000 IN A 192.203.230.10
f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
f.root-servers.net. 3600000 IN A 192.5.5.241
g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
g.root-servers.net. 3600000 IN A 192.112.36.4
h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
h.root-servers.net. 3600000 IN A 198.97.190.53
i.root-servers.net. 3600000 IN MX 10 mx.i.root-servers.org.
i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
i.root-servers.net. 3600000 IN A 192.36.148.17
j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
j.root-servers.net. 3600000 IN A 192.58.128.30
k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
k.root-servers.net. 3600000 IN A 193.0.14.129
l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
l.root-servers.net. 3600000 IN A 199.7.83.42
m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
m.root-servers.net. 3600000 IN A 202.12.27.33
root-servers.net. 3600000 IN SOA a.root-servers.net. (
nstld.verisign-grs.com. 2018091100 14400 7200 1209600 3600000 )
root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 (
f1ca0ccd91bd5573d9f431c00ee0101b2545c97602be0a97
8a3b11dbfc1c776d5b3e86ae3d973d6b5349ba7f04340f79 )

142
tests/dns/zonemd_test.c Normal file
View File

@ -0,0 +1,142 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#include <sched.h> /* IWYU pragma: keep */
#include <setjmp.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define UNIT_TESTING
#include <cmocka.h>
#include <dns/db.h>
#include <dns/lib.h>
#include <dns/rdata.h>
#include <dns/zonemd.h>
#include <tests/dns.h>
/*
* Individual unit tests
*/
/* zonemd_buildrdata */
static void
check_dns_zonemd_buildrdata(const char *origin, const char *file,
uint32_t serial, uint32_t digest_type,
uint32_t digest_length, const char *digest) {
dns_db_t *db = NULL;
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_buffer_t target;
isc_result_t result;
unsigned char buf[DNS_ZONEMD_BUFFERSIZE];
char text[1024] = { 0 };
dns_rdata_zonemd_t zonemd;
if (debug) {
fprintf(stderr, "Loading %s\n", file);
}
result = dns_test_loaddb(&db, dns_dbtype_zone, origin, file);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_zonemd_buildrdata(&rdata, db, NULL,
DNS_ZONEMD_SCHEME_SIMPLE, digest_type,
isc_g_mctx, buf, sizeof(buf));
assert_int_equal(result, ISC_R_SUCCESS);
if (debug) {
isc_buffer_init(&target, text, sizeof(text));
result = dns_rdata_totext(&rdata, NULL, &target);
assert_int_equal(result, ISC_R_SUCCESS);
fprintf(stderr, "%.*s\n", (int)isc_buffer_usedlength(&target),
text);
}
assert_int_equal(rdata.length, 6 + digest_length);
dns_rdata_tostruct(&rdata, &zonemd, NULL);
assert_int_equal(zonemd.serial, serial);
assert_int_equal(zonemd.scheme, DNS_ZONEMD_SCHEME_SIMPLE);
assert_int_equal(zonemd.digest_type, digest_type);
assert_int_equal(zonemd.length, digest_length);
assert_memory_equal(zonemd.digest, digest, digest_length);
dns_rdata_reset(&rdata);
dns_db_detach(&db);
}
ISC_RUN_TEST_IMPL(zonemd_buildrdata) {
UNUSED(state);
assert_return_code(chdir(TESTS_DIR), 0);
check_dns_zonemd_buildrdata(
"example", "testdata/zonemd/rfc8976.A.1.db", 2018031900,
DNS_ZONEMD_DIGEST_SHA384, 384 / 8,
"\xc6\x80\x90\xd9\x0a\x7a\xed\x71\x6b\xc4\x59\xf9"
"\x34\x0e\x3d\x7c\x13\x70\xd4\xd2\x4b\x7e\x2f\xc3"
"\xa1\xdd\xc0\xb9\xa8\x71\x53\xb9\xa9\x71\x3b\x3c"
"\x9a\xe5\xcc\x27\x77\x7f\x98\xb8\xe7\x30\x04\x4c");
check_dns_zonemd_buildrdata(
"example", "testdata/zonemd/rfc8976.A.2.db", 2018031900,
DNS_ZONEMD_DIGEST_SHA384, 384 / 8,
"\xa3\xb6\x9b\xad\x98\x0a\x35\x04\xe1\xcf\xfc\xb0"
"\xfd\x63\x97\xf9\x38\x48\x07\x1c\x93\x15\x1f\x55"
"\x2a\xe2\xf6\xb1\x71\x1d\x4b\xd2\xd8\xb3\x98\x08"
"\x22\x6d\x7b\x9d\xb7\x1e\x34\xb7\x20\x77\xf8\xfe");
check_dns_zonemd_buildrdata(
"example", "testdata/zonemd/rfc8976.A.3.db", 2018031900,
DNS_ZONEMD_DIGEST_SHA384, 384 / 8,
"\x62\xe6\xcf\x51\xb0\x2e\x54\xb9\xb5\xf9\x67\xd5"
"\x47\xce\x43\x13\x67\x92\x90\x1f\x9f\x88\xe6\x37"
"\x49\x3d\xaa\xf4\x01\xc9\x2c\x27\x9d\xd1\x0f\x0e"
"\xdb\x1c\x56\xf8\x08\x02\x11\xf8\x48\x0e\xe3\x06");
check_dns_zonemd_buildrdata(
"example", "testdata/zonemd/rfc8976.A.3.db", 2018031900,
DNS_ZONEMD_DIGEST_SHA512, 512 / 8,
"\x08\xcf\xa1\x11\x5c\x7b\x94\x8c\x41\x63\xa9\x01"
"\x27\x03\x95\xea\x22\x6a\x93\x0c\xd2\xcb\xcf\x2f"
"\xa9\xa5\xe6\xeb\x85\xf3\x7c\x8a\x4e\x11\x4d\x88"
"\x4e\x66\xf1\x76\xea\xb1\x21\xcb\x02\xdb\x7d\x65"
"\x2e\x0c\xc4\x82\x7e\x7a\x32\x04\xf1\x66\xb4\x7e"
"\x56\x13\xfd\x27");
check_dns_zonemd_buildrdata(
"uri.arpa", "testdata/zonemd/rfc8976.A.4.db", 2018100702,
DNS_ZONEMD_DIGEST_SHA384, 384 / 8,
"\x0d\xbc\x3c\x4d\xbf\xd7\x57\x77\xc1\x2c\xa1\x9c"
"\x33\x78\x54\xb1\x57\x77\x99\x90\x13\x07\xc4\x82"
"\xe9\xd9\x1d\x5d\x15\xcd\x93\x4d\x16\x31\x9d\x98"
"\xe3\x0c\x42\x01\xcf\x25\xa1\xd5\xa0\x25\x49\x60");
check_dns_zonemd_buildrdata(
"root-servers.net", "testdata/zonemd/rfc8976.A.5.db",
2018091100, DNS_ZONEMD_DIGEST_SHA384, 384 / 8,
"\xf1\xca\x0c\xcd\x91\xbd\x55\x73\xd9\xf4\x31\xc0"
"\x0e\xe0\x10\x1b\x25\x45\xc9\x76\x02\xbe\x0a\x97"
"\x8a\x3b\x11\xdb\xfc\x1c\x77\x6d\x5b\x3e\x86\xae"
"\x3d\x97\x3d\x6b\x53\x49\xba\x7f\x04\x34\x0f\x79");
}
ISC_TEST_LIST_START
ISC_TEST_ENTRY(zonemd_buildrdata)
ISC_TEST_LIST_END
ISC_TEST_MAIN