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