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