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