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