xref: /freebsd/contrib/unbound/testcode/unitzonemd.c (revision 328110da2661a8841f12000b99fea27ceacdd5b2)
1 /*
2  * testcode/unitzonemd.c - unit test for zonemd.
3  *
4  * Copyright (c) 2020, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  */
36 /**
37  * \file
38  * Unit tests for ZONEMD functionality.
39  */
40 
41 #include "config.h"
42 #include <ctype.h>
43 #include "util/log.h"
44 #include "testcode/unitmain.h"
45 #include "sldns/str2wire.h"
46 #include "services/authzone.h"
47 #include "util/data/dname.h"
48 #include "util/regional.h"
49 #include "validator/val_anchor.h"
50 
51 #define xstr(s) str(s)
52 #define str(s) #s
53 #define SRCDIRSTR xstr(SRCDIR)
54 
55 /** Add zone from file for testing */
56 struct auth_zone* authtest_addzone(struct auth_zones* az, const char* name,
57 	char* fname);
58 
59 /** zonemd unit test, generate a zonemd digest and check if correct */
60 static void zonemd_generate_test(const char* zname, char* zfile,
61 	int scheme, int hashalgo, const char* digest)
62 {
63 	uint8_t zonemd_hash[512];
64 	size_t hashlen = 0;
65 	char output[1024+1];
66 	size_t i;
67 	struct auth_zones* az;
68 	struct auth_zone* z;
69 	int result;
70 	struct regional* region = NULL;
71 	struct sldns_buffer* buf = NULL;
72 	char* reason = NULL;
73 	char* digestdup;
74 
75 	if(!zonemd_hashalgo_supported(hashalgo))
76 		return; /* cannot test unsupported algo */
77 
78 	/* setup environment */
79 	az = auth_zones_create();
80 	unit_assert(az);
81 	region = regional_create();
82 	unit_assert(region);
83 	buf = sldns_buffer_new(65535);
84 	unit_assert(buf);
85 
86 	/* read file */
87 	z = authtest_addzone(az, zname, zfile);
88 	unit_assert(z);
89 	lock_rw_wrlock(&z->lock);
90 	z->zonemd_check = 1;
91 	lock_rw_unlock(&z->lock);
92 
93 	/* create zonemd digest */
94 	result = auth_zone_generate_zonemd_hash(z, scheme, hashalgo,
95 		zonemd_hash, sizeof(zonemd_hash), &hashlen, region, buf,
96 		&reason);
97 	if(reason) printf("zonemd failure reason: %s\n", reason);
98 	unit_assert(result);
99 
100 	/* check digest */
101 	unit_assert(hashlen*2+1 <= sizeof(output));
102 	for(i=0; i<hashlen; i++) {
103 		const char* hexl = "0123456789ABCDEF";
104 		output[i*2] = hexl[(zonemd_hash[i]&0xf0)>>4];
105 		output[i*2+1] = hexl[zonemd_hash[i]&0xf];
106 	}
107 	output[hashlen*2] = 0;
108 	digestdup = strdup(digest);
109 	unit_assert(digestdup);
110 	for(i=0; i<strlen(digestdup); i++) {
111 		digestdup[i] = toupper((unsigned char)digestdup[i]);
112 	}
113 	if(verbosity >= VERB_ALGO) {
114 		char zname[LDNS_MAX_DOMAINLEN];
115 		dname_str(z->name, zname);
116 		printf("zonemd generated for %s in %s with "
117 			"scheme=%d hashalgo=%d\n", zname, z->zonefile,
118 			scheme, hashalgo);
119 		printf("digest %s\n", output);
120 		printf("wanted %s\n", digestdup);
121 	}
122 	unit_assert(strcmp(output, digestdup) == 0);
123 
124 	/* delete environment */
125 	free(digestdup);
126 	auth_zones_delete(az);
127 	regional_destroy(region);
128 	sldns_buffer_free(buf);
129 
130 	if(verbosity >= VERB_ALGO) {
131 		printf("\n");
132 	}
133 }
134 
135 /** loop over files and test generated zonemd digest */
136 static void zonemd_generate_tests(void)
137 {
138 	unit_show_func("services/authzone.c", "auth_zone_generate_zonemd_hash");
139 	zonemd_generate_test("example.org", SRCDIRSTR "/testdata/zonemd.example1.zone",
140 		1, 2, "20564D10F50A0CEBEC856C64032B7DFB53D3C449A421A5BC7A21F7627B4ACEA4DF29F2C6FE82ED9C23ADF6F4D420D5DD63EF6E6349D60FDAB910B65DF8D481B7");
141 
142 	/* https://tools.ietf.org/html/draft-ietf-dnsop-dns-zone-digest-12
143 	 * from section A.1 */
144 	zonemd_generate_test("example", SRCDIRSTR "/testdata/zonemd.example_a1.zone",
145 		1, 1, "c68090d90a7aed716bc459f9340e3d7c1370d4d24b7e2fc3a1ddc0b9a87153b9a9713b3c9ae5cc27777f98b8e730044c");
146 
147 	/* https://tools.ietf.org/html/draft-ietf-dnsop-dns-zone-digest-12
148 	 * from section A.2 */
149 	zonemd_generate_test("example", SRCDIRSTR "/testdata/zonemd.example_a2.zone",
150 		1, 1, "31cefb03814f5062ad12fa951ba0ef5f8da6ae354a415767246f7dc932ceb1e742a2108f529db6a33a11c01493de358d");
151 
152 	/* https://tools.ietf.org/html/draft-ietf-dnsop-dns-zone-digest-12
153 	 * from section A.3 SHA384 digest */
154 	zonemd_generate_test("example", SRCDIRSTR "/testdata/zonemd.example_a3.zone",
155 		1, 1, "62e6cf51b02e54b9b5f967d547ce43136792901f9f88e637493daaf401c92c279dd10f0edb1c56f8080211f8480ee306");
156 
157 	/* https://tools.ietf.org/html/draft-ietf-dnsop-dns-zone-digest-12
158 	 * from section A.3 SHA512 digest*/
159 	zonemd_generate_test("example", SRCDIRSTR "/testdata/zonemd.example_a3.zone",
160 		1, 2, "08cfa1115c7b948c4163a901270395ea226a930cd2cbcf2fa9a5e6eb85f37c8a4e114d884e66f176eab121cb02db7d652e0cc4827e7a3204f166b47e5613fd27");
161 
162 	/* https://tools.ietf.org/html/draft-ietf-dnsop-dns-zone-digest-12
163 	 * from section A.4 */
164 	zonemd_generate_test("uri.arpa", SRCDIRSTR "/testdata/zonemd.example_a4.zone",
165 		1, 1, "1291b78ddf7669b1a39d014d87626b709b55774c5d7d58fadc556439889a10eaf6f11d615900a4f996bd46279514e473");
166 
167 	/* https://tools.ietf.org/html/draft-ietf-dnsop-dns-zone-digest-12
168 	 * from section A.5.
169 	 * Adjusted with renumbered B.root. */
170 	zonemd_generate_test("root-servers.net", SRCDIRSTR "/testdata/zonemd.example_a5.zone",
171 		1, 1, "5a9521d88984ee123d9626191e2a327a43a16fd4339dd4ecc13d8672d5bae527d066d33645e35778677800005247d199");
172 }
173 
174 /** test the zonemd check routine */
175 static void zonemd_check_test(void)
176 {
177 	const char* zname = "example.org";
178 	char* zfile = SRCDIRSTR "/testdata/zonemd.example1.zone";
179 	int scheme = 1;
180 	int hashalgo = 2;
181 	const char* digest = "20564D10F50A0CEBEC856C64032B7DFB53D3C449A421A5BC7A21F7627B4ACEA4DF29F2C6FE82ED9C23ADF6F4D420D5DD63EF6E6349D60FDAB910B65DF8D481B7";
182 	const char* digestwrong = "20564D10F50A0CEBEC856C64032B7DFB53D3C449A421A5BC7A21F7627B4ACEA4DF29F2C6FE82ED9C23ADF6F4D420D5DD63EF6E6349D60FDAB910B65DF8D48100";
183 	uint8_t hash[512], hashwrong[512];
184 	size_t hashlen = 0, hashwronglen = 0;
185 	struct auth_zones* az;
186 	struct auth_zone* z;
187 	int result;
188 	struct regional* region = NULL;
189 	struct sldns_buffer* buf = NULL;
190 	char* reason = NULL;
191 
192 	if(!zonemd_hashalgo_supported(hashalgo))
193 		return; /* cannot test unsupported algo */
194 	unit_show_func("services/authzone.c", "auth_zone_generate_zonemd_check");
195 
196 	/* setup environment */
197 	az = auth_zones_create();
198 	unit_assert(az);
199 	region = regional_create();
200 	unit_assert(region);
201 	buf = sldns_buffer_new(65535);
202 	unit_assert(buf);
203 
204 	/* read file */
205 	z = authtest_addzone(az, zname, zfile);
206 	unit_assert(z);
207 	lock_rw_wrlock(&z->lock);
208 	z->zonemd_check = 1;
209 	lock_rw_unlock(&z->lock);
210 	hashlen = sizeof(hash);
211 	if(sldns_str2wire_hex_buf(digest, hash, &hashlen) != 0) {
212 		unit_assert(0); /* parse failure */
213 	}
214 	hashwronglen = sizeof(hashwrong);
215 	if(sldns_str2wire_hex_buf(digestwrong, hashwrong, &hashwronglen) != 0) {
216 		unit_assert(0); /* parse failure */
217 	}
218 
219 	/* check return values of the check routine */
220 	result = auth_zone_generate_zonemd_check(z, scheme, hashalgo,
221 		hash, hashlen, region, buf, &reason);
222 	unit_assert(result && reason == NULL);
223 	result = auth_zone_generate_zonemd_check(z, 241, hashalgo,
224 		hash, hashlen, region, buf, &reason);
225 	unit_assert(result && strcmp(reason, "unsupported scheme")==0);
226 	result = auth_zone_generate_zonemd_check(z, scheme, 242,
227 		hash, hashlen, region, buf, &reason);
228 	unit_assert(result && strcmp(reason, "unsupported algorithm")==0);
229 	result = auth_zone_generate_zonemd_check(z, scheme, hashalgo,
230 		hash, 2, region, buf, &reason);
231 	unit_assert(!result && strcmp(reason, "digest length too small, less than 12")==0);
232 	result = auth_zone_generate_zonemd_check(z, scheme, hashalgo,
233 		hashwrong, hashwronglen, region, buf, &reason);
234 	unit_assert(!result && strcmp(reason, "incorrect digest")==0);
235 	result = auth_zone_generate_zonemd_check(z, scheme, hashalgo,
236 		hashwrong, hashwronglen-3, region, buf, &reason);
237 	unit_assert(!result && strcmp(reason, "incorrect digest length")==0);
238 
239 	/* delete environment */
240 	auth_zones_delete(az);
241 	regional_destroy(region);
242 	sldns_buffer_free(buf);
243 
244 	if(verbosity >= VERB_ALGO) {
245 		printf("\n");
246 	}
247 }
248 
249 /** zonemd test verify */
250 static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
251 	char* date_override, char* result_wanted)
252 {
253 	time_t now = 0;
254 	struct module_stack mods;
255 	struct module_env env;
256 	char* result = NULL;
257 	struct auth_zone* z;
258 
259 	/* setup test harness */
260 	memset(&env, 0, sizeof(env));
261 	env.scratch = regional_create();
262 	if(!env.scratch)
263 		fatal_exit("out of memory");
264 	env.scratch_buffer = sldns_buffer_new(65553);
265 	if(!env.scratch_buffer)
266 		fatal_exit("out of memory");
267 	env.cfg = config_create();
268 	if(!env.cfg)
269 		fatal_exit("out of memory");
270 	env.now = &now;
271 	env.cfg->val_date_override = cfg_convert_timeval(date_override);
272 	if(!env.cfg->val_date_override)
273 		fatal_exit("could not parse datetime %s", date_override);
274 	if(env.cfg->module_conf)
275 		free(env.cfg->module_conf);
276 	env.cfg->module_conf = strdup("validator iterator");
277 	if(!env.cfg->module_conf)
278 		fatal_exit("out of memory");
279 	if(tastr) {
280 		if(!cfg_strlist_insert(&env.cfg->trust_anchor_list,
281 			strdup(tastr)))
282 			fatal_exit("out of memory");
283 	}
284 	env.anchors = anchors_create();
285 	if(!env.anchors)
286 		fatal_exit("out of memory");
287 	env.auth_zones = auth_zones_create();
288 	if(!env.auth_zones)
289 		fatal_exit("out of memory");
290 	modstack_init(&mods);
291 	if(!modstack_call_startup(&mods, env.cfg->module_conf, &env))
292 		fatal_exit("could not modstack_startup");
293 	if(!modstack_call_init(&mods, env.cfg->module_conf, &env))
294 		fatal_exit("could not modstack_call_init");
295 	env.mesh = mesh_create(&mods, &env);
296 	if(!env.mesh)
297 		fatal_exit("out of memory");
298 
299 	/* load data */
300 	z = authtest_addzone(env.auth_zones, zname, zfile);
301 	if(!z)
302 		fatal_exit("could not addzone %s %s", zname, zfile);
303 
304 	/* test */
305 	lock_rw_wrlock(&z->lock);
306 	z->zonemd_check = 1;
307 	auth_zone_verify_zonemd(z, &env, &mods, &result, 1, 0);
308 	lock_rw_unlock(&z->lock);
309 	if(verbosity >= VERB_ALGO) {
310 		printf("auth zone %s: ZONEMD verification %s: %s\n", zname,
311 			(strcmp(result, "ZONEMD verification successful")==0?"successful":"failed"),
312 			result);
313 	}
314 	if(!result)
315 		fatal_exit("out of memory");
316 	unit_assert(strcmp(result, result_wanted) == 0);
317 	if(strcmp(result, "ZONEMD verification successful") == 0 ||
318 		strcmp(result, "DNSSEC verified nonexistence of ZONEMD") == 0 ||
319 		strcmp(result, "no ZONEMD present") == 0) {
320 		lock_rw_rdlock(&z->lock);
321 		unit_assert(!z->zone_expired);
322 		lock_rw_unlock(&z->lock);
323 	} else {
324 		lock_rw_rdlock(&z->lock);
325 		unit_assert(z->zone_expired);
326 		lock_rw_unlock(&z->lock);
327 	}
328 	free(result);
329 
330 	/* desetup test harness */
331 	mesh_delete(env.mesh);
332 	modstack_call_deinit(&mods, &env);
333 	modstack_call_destartup(&mods, &env);
334 	modstack_free(&mods);
335 	auth_zones_delete(env.auth_zones);
336 	anchors_delete(env.anchors);
337 	config_delete(env.cfg);
338 	regional_destroy(env.scratch);
339 	sldns_buffer_free(env.scratch_buffer);
340 
341 	if(verbosity >= VERB_ALGO) {
342 		printf("\n");
343 	}
344 }
345 
346 /** zonemd test verify suite */
347 static void zonemd_verify_tests(void)
348 {
349 	unit_show_func("services/authzone.c", "auth_zone_verify_zonemd");
350 	/* give trustanchor for unsigned zone, should fail */
351 	zonemd_verify_test("example.org",
352 		SRCDIRSTR "/testdata/zonemd.example1.zone",
353 		"example.org. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
354 		"20180302005009",
355 		"verify DNSKEY RRset with trust anchor failed: have trust anchor, but zone has no DNSKEY");
356 	/* unsigned zone without ZONEMD in it */
357 	zonemd_verify_test("example.org",
358 		SRCDIRSTR "/testdata/zonemd.example1.zone",
359 		NULL,
360 		"20180302005009",
361 		"no ZONEMD present");
362 	/* no trust anchor, so it succeeds for zone with a correct ZONEMD */
363 	zonemd_verify_test("example.com",
364 		SRCDIRSTR "/testdata/zonemd.example2.zone",
365 		NULL,
366 		"20180302005009",
367 		"ZONEMD verification successful");
368 	/* trust anchor for another zone, so it is indeterminate */
369 	zonemd_verify_test("example.com",
370 		SRCDIRSTR "/testdata/zonemd.example2.zone",
371 		"example.org. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
372 		"20180302005009",
373 		"ZONEMD verification successful");
374 
375 	/* load a DNSSEC signed zone, but no trust anchor */
376 	/* this zonefile has an incorrect ZONEMD digest, with correct
377 	 * DNSSEC signature. */
378 	zonemd_verify_test("example.com",
379 		SRCDIRSTR "/testdata/zonemd.example3.zone",
380 		NULL,
381 		"20180302005009",
382 		"incorrect digest");
383 	/* load a DNSSEC zone with NSEC3, but no trust anchor */
384 	/* this zonefile has an incorrect ZONEMD digest, with correct
385 	 * DNSSEC signature. */
386 	zonemd_verify_test("example.com",
387 		SRCDIRSTR "/testdata/zonemd.example4.zone",
388 		NULL,
389 		"20180302005009",
390 		"incorrect digest");
391 	/* valid zonemd, in dnssec signed zone, no trust anchor*/
392 	/* this zonefile has a correct ZONEMD digest and
393 	 * correct DNSSEC signature */
394 	zonemd_verify_test("example.com",
395 		SRCDIRSTR "/testdata/zonemd.example5.zone",
396 		NULL,
397 		"20180302005009",
398 		"ZONEMD verification successful");
399 	/* valid zonemd, in dnssec NSEC3 zone, no trust anchor*/
400 	zonemd_verify_test("example.com",
401 		SRCDIRSTR "/testdata/zonemd.example6.zone",
402 		NULL,
403 		"20180302005009",
404 		"ZONEMD verification successful");
405 
406 	/* load a DNSSEC signed zone with a trust anchor, valid ZONEMD */
407 	zonemd_verify_test("example.com",
408 		SRCDIRSTR "/testdata/zonemd.example5.zone",
409 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
410 		"20201020135527",
411 		"ZONEMD verification successful");
412 	/* load a DNSSEC NSEC3 signed zone with a trust anchor, valid ZONEMD */
413 	zonemd_verify_test("example.com",
414 		SRCDIRSTR "/testdata/zonemd.example6.zone",
415 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
416 		"20201020135527",
417 		"ZONEMD verification successful");
418 
419 	/* load a DNSSEC NSEC zone without ZONEMD */
420 	zonemd_verify_test("example.com",
421 		SRCDIRSTR "/testdata/zonemd.example7.zone",
422 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
423 		"20201020135527",
424 		"DNSSEC verified nonexistence of ZONEMD");
425 	/* load a DNSSEC NSEC3 zone without ZONEMD */
426 	zonemd_verify_test("example.com",
427 		SRCDIRSTR "/testdata/zonemd.example8.zone",
428 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
429 		"20201020135527",
430 		"DNSSEC verified nonexistence of ZONEMD");
431 
432 	/* load DNSSEC zone but RRSIG on ZONEMD is wrong */
433 	zonemd_verify_test("example.com",
434 		SRCDIRSTR "/testdata/zonemd.example9.zone",
435 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
436 		"20201020135527",
437 #ifdef HAVE_SSL
438 		"DNSSEC verify failed for ZONEMD RRset: signature crypto failed"
439 #else /* HAVE_NETTLE */
440 		"DNSSEC verify failed for ZONEMD RRset: RSA signature verification failed"
441 #endif
442 		);
443 	/* load DNSSEC zone but RRSIG on SOA is wrong */
444 	zonemd_verify_test("example.com",
445 		SRCDIRSTR "/testdata/zonemd.example10.zone",
446 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
447 		"20201020135527",
448 #ifdef HAVE_SSL
449 		"DNSSEC verify failed for SOA RRset: signature crypto failed"
450 #else /* HAVE_NETTLE */
451 		"DNSSEC verify failed for SOA RRset: RSA signature verification failed"
452 #endif
453 		);
454 
455 	/* load DNSSEC zone without ZONEMD, but NSEC bitmap says it exists */
456 	zonemd_verify_test("example.com",
457 		SRCDIRSTR "/testdata/zonemd.example11.zone",
458 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
459 		"20201020135527",
460 		"DNSSEC NSEC bitmap says type ZONEMD exists");
461 	/* load DNSSEC zone without ZONEMD, but NSEC3 bitmap says it exists */
462 	zonemd_verify_test("example.com",
463 		SRCDIRSTR "/testdata/zonemd.example12.zone",
464 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
465 		"20201020135527",
466 		"DNSSEC NSEC3 bitmap says type ZONEMD exists");
467 
468 	/* load DNSSEC zone without ZONEMD, but RRSIG on NSEC not okay */
469 	zonemd_verify_test("example.com",
470 		SRCDIRSTR "/testdata/zonemd.example13.zone",
471 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
472 		"20201020135527",
473 #ifdef HAVE_SSL
474 		"DNSSEC verify failed for NSEC RRset: signature crypto failed"
475 #else /* HAVE_NETTLE */
476 		"DNSSEC verify failed for NSEC RRset: RSA signature verification failed"
477 #endif
478 		);
479 	/* load DNSSEC zone without ZONEMD, but RRSIG on NSEC3 not okay */
480 	zonemd_verify_test("example.com",
481 		SRCDIRSTR "/testdata/zonemd.example14.zone",
482 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
483 		"20201020135527",
484 #ifdef HAVE_SSL
485 		"DNSSEC verify failed for NSEC3 RRset: signature crypto failed"
486 #else /* HAVE_NETTLE */
487 		"DNSSEC verify failed for NSEC3 RRset: RSA signature verification failed"
488 #endif
489 		);
490 
491 	/* load DNSSEC zone, with ZONEMD, but DNSKEY RRSIG is not okay. */
492 	zonemd_verify_test("example.com",
493 		SRCDIRSTR "/testdata/zonemd.example15.zone",
494 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
495 		"20201020135527",
496 #ifdef HAVE_SSL
497 		"verify DNSKEY RRset with trust anchor failed: signature crypto failed"
498 #else /* HAVE_NETTLE */
499 		"verify DNSKEY RRset with trust anchor failed: RSA signature verification failed"
500 #endif
501 		);
502 	/* load DNSSEC zone, but trust anchor mismatches DNSKEY */
503 	zonemd_verify_test("example.com",
504 		SRCDIRSTR "/testdata/zonemd.example5.zone",
505 		/* okay anchor is
506 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af", */
507 		"example.com. IN DS 55566 8 2 0000000000111111222223333444444dfcf92595148022f2c2fd98e5deee90af",
508 		"20201020135527",
509 		"verify DNSKEY RRset with trust anchor failed: DS hash mismatches key");
510 	/* load DNSSEC zone, but trust anchor fails because the zone
511 	 * has expired signatures.  We set the date for it */
512 	zonemd_verify_test("example.com",
513 		SRCDIRSTR "/testdata/zonemd.example5.zone",
514 		"example.com. IN DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af",
515 		/* okay date: "20201020135527", */
516 		"20221020135527",
517 		"verify DNSKEY RRset with trust anchor failed: signature expired");
518 
519 	/* duplicate zonemd with same scheme and algorithm */
520 	zonemd_verify_test("example.com",
521 		SRCDIRSTR "/testdata/zonemd.example16.zone",
522 		NULL,
523 		"20180302005009",
524 		"ZONEMD RRSet contains more than one RR with the same scheme and hash algorithm");
525 	/* different capitalisation of ns name and owner names, should
526 	 * be canonicalized. */
527 	zonemd_verify_test("example.com",
528 		SRCDIRSTR "/testdata/zonemd.example17.zone",
529 		NULL,
530 		"20180302005009",
531 		"ZONEMD verification successful");
532 }
533 
534 /** zonemd unit tests */
535 void zonemd_test(void)
536 {
537 	unit_show_feature("zonemd");
538 	zonemd_generate_tests();
539 	zonemd_check_test();
540 	zonemd_verify_tests();
541 }
542