Home | History | Annotate | Line # | Download | only in testcode
unitverify.c revision 1.1.1.8
      1 /*
      2  * testcode/unitverify.c - unit test for signature verification routines.
      3  *
      4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
      5  *
      6  * This software is open source.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * Redistributions of source code must retain the above copyright notice,
     13  * this list of conditions and the following disclaimer.
     14  *
     15  * Redistributions in binary form must reproduce the above copyright notice,
     16  * this list of conditions and the following disclaimer in the documentation
     17  * and/or other materials provided with the distribution.
     18  *
     19  * Neither the name of the NLNET LABS nor the names of its contributors may
     20  * be used to endorse or promote products derived from this software without
     21  * specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
     29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34  *
     35  */
     36 /**
     37  * \file
     38  * Calls verification unit tests. Exits with code 1 on a failure.
     39  */
     40 
     41 #include "config.h"
     42 #include "util/log.h"
     43 #include "testcode/unitmain.h"
     44 #include "validator/val_sigcrypt.h"
     45 #include "validator/val_secalgo.h"
     46 #include "validator/val_nsec.h"
     47 #include "validator/val_nsec3.h"
     48 #include "validator/validator.h"
     49 #include "testcode/testpkts.h"
     50 #include "util/data/msgreply.h"
     51 #include "util/data/msgparse.h"
     52 #include "util/data/dname.h"
     53 #include "util/regional.h"
     54 #include "util/alloc.h"
     55 #include "util/rbtree.h"
     56 #include "util/net_help.h"
     57 #include "util/module.h"
     58 #include "util/config_file.h"
     59 #include "sldns/sbuffer.h"
     60 #include "sldns/keyraw.h"
     61 #include "sldns/str2wire.h"
     62 #include "sldns/wire2str.h"
     63 
     64 #ifdef HAVE_SSL
     65 #ifdef HAVE_OPENSSL_ERR_H
     66 #include <openssl/err.h>
     67 #endif
     68 #endif
     69 
     70 /** verbose signature test */
     71 static int vsig = 0;
     72 
     73 /** entry to packet buffer with wireformat */
     74 static void
     75 entry_to_buf(struct entry* e, sldns_buffer* pkt)
     76 {
     77 	unit_assert(e->reply_list);
     78 	if(e->reply_list->reply_from_hex) {
     79 		sldns_buffer_copy(pkt, e->reply_list->reply_from_hex);
     80 	} else {
     81 		sldns_buffer_clear(pkt);
     82 		sldns_buffer_write(pkt, e->reply_list->reply_pkt,
     83 			e->reply_list->reply_len);
     84 		sldns_buffer_flip(pkt);
     85 	}
     86 }
     87 
     88 /** entry to reply info conversion */
     89 static void
     90 entry_to_repinfo(struct entry* e, struct alloc_cache* alloc,
     91 	struct regional* region, sldns_buffer* pkt, struct query_info* qi,
     92 	struct reply_info** rep)
     93 {
     94 	int ret;
     95 	struct edns_data edns;
     96 	entry_to_buf(e, pkt);
     97 	/* lock alloc lock to please lock checking software.
     98 	 * alloc_special_obtain assumes it is talking to a ub-alloc,
     99 	 * and does not need to perform locking. Here the alloc is
    100 	 * the only one, so we lock it here */
    101 	lock_quick_lock(&alloc->lock);
    102 	ret = reply_info_parse(pkt, alloc, qi, rep, region, &edns);
    103 	lock_quick_unlock(&alloc->lock);
    104 	if(ret != 0) {
    105 		char rcode[16];
    106 		sldns_wire2str_rcode_buf(ret, rcode, sizeof(rcode));
    107 		printf("parse code %d: %s\n", ret, rcode);
    108 		unit_assert(ret != 0);
    109 	}
    110 }
    111 
    112 /** extract DNSKEY rrset from answer and convert it */
    113 static struct ub_packed_rrset_key*
    114 extract_keys(struct entry* e, struct alloc_cache* alloc,
    115 	struct regional* region, sldns_buffer* pkt)
    116 {
    117 	struct ub_packed_rrset_key* dnskey = NULL;
    118 	struct query_info qinfo;
    119 	struct reply_info* rep = NULL;
    120 	size_t i;
    121 
    122 	entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep);
    123 	for(i=0; i<rep->an_numrrsets; i++) {
    124 		if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_DNSKEY) {
    125 			dnskey = rep->rrsets[i];
    126 			rep->rrsets[i] = NULL;
    127 			break;
    128 		}
    129 	}
    130 	unit_assert(dnskey);
    131 
    132 	reply_info_parsedelete(rep, alloc);
    133 	query_info_clear(&qinfo);
    134 	return dnskey;
    135 }
    136 
    137 /** return true if answer should be bogus */
    138 static int
    139 should_be_bogus(struct ub_packed_rrset_key* rrset, struct query_info* qinfo)
    140 {
    141 	struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
    142 		entry.data;
    143 	if(d->rrsig_count == 0)
    144 		return 1;
    145 	/* name 'bogus' as first label signals bogus */
    146 	if(rrset->rk.dname_len > 6 && memcmp(rrset->rk.dname+1, "bogus", 5)==0)
    147 		return 1;
    148 	if(qinfo->qname_len > 6 && memcmp(qinfo->qname+1, "bogus", 5)==0)
    149 		return 1;
    150 	return 0;
    151 }
    152 
    153 /** return number of rrs in an rrset */
    154 static size_t
    155 rrset_get_count(struct ub_packed_rrset_key* rrset)
    156 {
    157 	struct packed_rrset_data* d = (struct packed_rrset_data*)
    158 	rrset->entry.data;
    159 	if(!d) return 0;
    160 	return d->count;
    161 }
    162 
    163 /** setup sig alg list from dnskey */
    164 static void
    165 setup_sigalg(struct ub_packed_rrset_key* dnskey, uint8_t* sigalg)
    166 {
    167 	uint8_t a[ALGO_NEEDS_MAX];
    168 	size_t i, n = 0;
    169 	memset(a, 0, sizeof(a));
    170 	for(i=0; i<rrset_get_count(dnskey); i++) {
    171 		uint8_t algo = (uint8_t)dnskey_get_algo(dnskey, i);
    172 		if(a[algo] == 0) {
    173 			a[algo] = 1;
    174 			sigalg[n++] = algo;
    175 		}
    176 	}
    177 	sigalg[n] = 0;
    178 }
    179 
    180 /** verify and test one rrset against the key rrset */
    181 static void
    182 verifytest_rrset(struct module_env* env, struct val_env* ve,
    183 	struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
    184 	struct query_info* qinfo)
    185 {
    186 	enum sec_status sec;
    187 	char reasonbuf[256];
    188 	char* reason = NULL;
    189 	uint8_t sigalg[ALGO_NEEDS_MAX+1];
    190 	int verified = 0;
    191 	if(vsig) {
    192 		log_nametypeclass(VERB_QUERY, "verify of rrset",
    193 			rrset->rk.dname, ntohs(rrset->rk.type),
    194 			ntohs(rrset->rk.rrset_class));
    195 	}
    196 	setup_sigalg(dnskey, sigalg); /* check all algorithms in the dnskey */
    197 	/* ok to give null as qstate here, won't be used for answer section. */
    198 	sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason,
    199 		NULL, LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf,
    200 		sizeof(reasonbuf));
    201 	if(vsig) {
    202 		printf("verify outcome is: %s %s\n", sec_status_to_string(sec),
    203 			reason?reason:"");
    204 	}
    205 	if(should_be_bogus(rrset, qinfo)) {
    206 		unit_assert(sec == sec_status_bogus);
    207 	} else {
    208 		unit_assert(sec == sec_status_secure);
    209 	}
    210 }
    211 
    212 /** verify and test an entry - every rr in the message */
    213 static void
    214 verifytest_entry(struct entry* e, struct alloc_cache* alloc,
    215 	struct regional* region, sldns_buffer* pkt,
    216 	struct ub_packed_rrset_key* dnskey, struct module_env* env,
    217 	struct val_env* ve)
    218 {
    219 	struct query_info qinfo;
    220 	struct reply_info* rep = NULL;
    221 	size_t i;
    222 
    223 	regional_free_all(region);
    224 	if(vsig) {
    225 		char* s = sldns_wire2str_pkt(e->reply_list->reply_pkt,
    226 			e->reply_list->reply_len);
    227 		printf("verifying pkt:\n%s\n", s?s:"outofmemory");
    228 		free(s);
    229 	}
    230 	entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep);
    231 
    232 	for(i=0; i<rep->rrset_count; i++) {
    233 		verifytest_rrset(env, ve, rep->rrsets[i], dnskey, &qinfo);
    234 	}
    235 
    236 	reply_info_parsedelete(rep, alloc);
    237 	query_info_clear(&qinfo);
    238 }
    239 
    240 /** find RRset in reply by type */
    241 static struct ub_packed_rrset_key*
    242 find_rrset_type(struct reply_info* rep, uint16_t type)
    243 {
    244 	size_t i;
    245 	for(i=0; i<rep->rrset_count; i++) {
    246 		if(ntohs(rep->rrsets[i]->rk.type) == type)
    247 			return rep->rrsets[i];
    248 	}
    249 	return NULL;
    250 }
    251 
    252 /** DS sig test an entry - get DNSKEY and DS in entry and verify */
    253 static void
    254 dstest_entry(struct entry* e, struct alloc_cache* alloc,
    255 	struct regional* region, sldns_buffer* pkt, struct module_env* env)
    256 {
    257 	struct query_info qinfo;
    258 	struct reply_info* rep = NULL;
    259 	struct ub_packed_rrset_key* ds, *dnskey;
    260 	int ret;
    261 
    262 	regional_free_all(region);
    263 	if(vsig) {
    264 		char* s = sldns_wire2str_pkt(e->reply_list->reply_pkt,
    265 			e->reply_list->reply_len);
    266 		printf("verifying DS-DNSKEY match:\n%s\n", s?s:"outofmemory");
    267 		free(s);
    268 	}
    269 	entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep);
    270 	ds = find_rrset_type(rep, LDNS_RR_TYPE_DS);
    271 	dnskey = find_rrset_type(rep, LDNS_RR_TYPE_DNSKEY);
    272 	/* check test is OK */
    273 	unit_assert(ds && dnskey);
    274 
    275 	ret = ds_digest_match_dnskey(env, dnskey, 0, ds, 0);
    276 	if(strncmp((char*)qinfo.qname, "\003yes", 4) == 0) {
    277 		if(vsig) {
    278 			printf("result(yes)= %s\n", ret?"yes":"no");
    279 		}
    280 		unit_assert(ret);
    281 	} else if (strncmp((char*)qinfo.qname, "\002no", 3) == 0) {
    282 		if(vsig) {
    283 			printf("result(no)= %s\n", ret?"yes":"no");
    284 		}
    285 		unit_assert(!ret);
    286 		verbose(VERB_QUERY, "DS fail: OK; matched unit test");
    287 	} else {
    288 		fatal_exit("Bad qname in DS unit test, yes or no");
    289 	}
    290 
    291 	reply_info_parsedelete(rep, alloc);
    292 	query_info_clear(&qinfo);
    293 }
    294 
    295 /** verify from a file */
    296 static void
    297 verifytest_file(const char* fname, const char* at_date)
    298 {
    299 	/*
    300 	 * The file contains a list of ldns-testpkts entries.
    301 	 * The first entry must be a query for DNSKEY.
    302 	 * The answer rrset is the keyset that will be used for verification
    303 	 */
    304 	struct ub_packed_rrset_key* dnskey;
    305 	struct regional* region = regional_create();
    306 	struct alloc_cache alloc;
    307 	sldns_buffer* buf = sldns_buffer_new(65535);
    308 	struct entry* e;
    309 	struct entry* list = read_datafile(fname, 1);
    310 	struct module_env env;
    311 	struct val_env ve;
    312 	time_t now = time(NULL);
    313 	unit_show_func("signature verify", fname);
    314 
    315 	if(!list)
    316 		fatal_exit("could not read %s: %s", fname, strerror(errno));
    317 	alloc_init(&alloc, NULL, 1);
    318 	memset(&env, 0, sizeof(env));
    319 	memset(&ve, 0, sizeof(ve));
    320 	env.scratch = region;
    321 	env.scratch_buffer = buf;
    322 	env.now = &now;
    323 	ve.date_override = cfg_convert_timeval(at_date);
    324 	unit_assert(region && buf);
    325 	dnskey = extract_keys(list, &alloc, region, buf);
    326 	if(vsig) log_nametypeclass(VERB_QUERY, "test dnskey",
    327 			dnskey->rk.dname, ntohs(dnskey->rk.type),
    328 			ntohs(dnskey->rk.rrset_class));
    329 	/* ready to go! */
    330 	for(e = list->next; e; e = e->next) {
    331 		verifytest_entry(e, &alloc, region, buf, dnskey, &env, &ve);
    332 	}
    333 
    334 	ub_packed_rrset_parsedelete(dnskey, &alloc);
    335 	delete_entry(list);
    336 	regional_destroy(region);
    337 	alloc_clear(&alloc);
    338 	sldns_buffer_free(buf);
    339 }
    340 
    341 /** verify DS matches DNSKEY from a file */
    342 static void
    343 dstest_file(const char* fname)
    344 {
    345 	/*
    346 	 * The file contains a list of ldns-testpkts entries.
    347 	 * The first entry must be a query for DNSKEY.
    348 	 * The answer rrset is the keyset that will be used for verification
    349 	 */
    350 	struct regional* region = regional_create();
    351 	struct alloc_cache alloc;
    352 	sldns_buffer* buf = sldns_buffer_new(65535);
    353 	struct entry* e;
    354 	struct entry* list = read_datafile(fname, 1);
    355 	struct module_env env;
    356 	unit_show_func("DS verify", fname);
    357 
    358 	if(!list)
    359 		fatal_exit("could not read %s: %s", fname, strerror(errno));
    360 	alloc_init(&alloc, NULL, 1);
    361 	memset(&env, 0, sizeof(env));
    362 	env.scratch = region;
    363 	env.scratch_buffer = buf;
    364 	unit_assert(region && buf);
    365 
    366 	/* ready to go! */
    367 	for(e = list; e; e = e->next) {
    368 		dstest_entry(e, &alloc, region, buf, &env);
    369 	}
    370 
    371 	delete_entry(list);
    372 	regional_destroy(region);
    373 	alloc_clear(&alloc);
    374 	sldns_buffer_free(buf);
    375 }
    376 
    377 /** helper for unittest of NSEC routines */
    378 static int
    379 unitest_nsec_has_type_rdata(char* bitmap, size_t len, uint16_t type)
    380 {
    381 	return nsecbitmap_has_type_rdata((uint8_t*)bitmap, len, type);
    382 }
    383 
    384 /** Test NSEC type bitmap routine */
    385 static void
    386 nsectest(void)
    387 {
    388 	/* bitmap starts at type bitmap rdata field */
    389 	/* from rfc 4034 example */
    390 	char* bitmap = "\000\006\100\001\000\000\000\003"
    391 		"\004\033\000\000\000\000\000\000"
    392 		"\000\000\000\000\000\000\000\000"
    393 		"\000\000\000\000\000\000\000\000"
    394 		"\000\000\000\000\040";
    395 	size_t len = 37;
    396 
    397 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 0));
    398 	unit_assert(unitest_nsec_has_type_rdata(bitmap, len, LDNS_RR_TYPE_A));
    399 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 2));
    400 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 3));
    401 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 4));
    402 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 5));
    403 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 6));
    404 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 7));
    405 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 8));
    406 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 9));
    407 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 10));
    408 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 11));
    409 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 12));
    410 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 13));
    411 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 14));
    412 	unit_assert(unitest_nsec_has_type_rdata(bitmap, len, LDNS_RR_TYPE_MX));
    413 	unit_assert(unitest_nsec_has_type_rdata(bitmap, len, LDNS_RR_TYPE_RRSIG));
    414 	unit_assert(unitest_nsec_has_type_rdata(bitmap, len, LDNS_RR_TYPE_NSEC));
    415 	unit_assert(unitest_nsec_has_type_rdata(bitmap, len, 1234));
    416 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 1233));
    417 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 1235));
    418 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 1236));
    419 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 1237));
    420 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 1238));
    421 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 1239));
    422 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 1240));
    423 	unit_assert(!unitest_nsec_has_type_rdata(bitmap, len, 2230));
    424 }
    425 
    426 /** Test hash algo - NSEC3 hash it and compare result */
    427 static void
    428 nsec3_hash_test_entry(struct entry* e, rbtree_type* ct,
    429 	struct alloc_cache* alloc, struct regional* region,
    430 	sldns_buffer* buf)
    431 {
    432 	struct query_info qinfo;
    433 	struct reply_info* rep = NULL;
    434 	struct ub_packed_rrset_key* answer, *nsec3, *nsec3_region;
    435 	struct nsec3_cached_hash* hash = NULL;
    436 	int ret;
    437 	uint8_t* qname;
    438 
    439 	if(vsig) {
    440 		char* s = sldns_wire2str_pkt(e->reply_list->reply_pkt,
    441 			e->reply_list->reply_len);
    442 		printf("verifying NSEC3 hash:\n%s\n", s?s:"outofmemory");
    443 		free(s);
    444 	}
    445 	entry_to_repinfo(e, alloc, region, buf, &qinfo, &rep);
    446 	nsec3 = find_rrset_type(rep, LDNS_RR_TYPE_NSEC3);
    447 	answer = find_rrset_type(rep, LDNS_RR_TYPE_AAAA);
    448 	qname = regional_alloc_init(region, qinfo.qname, qinfo.qname_len);
    449 	/* check test is OK */
    450 	unit_assert(nsec3 && answer && qname);
    451 
    452 	/* Copy the nsec3 to the region, so it can stay referenced by the
    453 	 * ct tree entry. The region is freed when the file is done. */
    454 	nsec3_region = packed_rrset_copy_region(nsec3, region, 0);
    455 
    456 	ret = nsec3_hash_name(ct, region, buf, nsec3_region, 0, qname,
    457 		qinfo.qname_len, &hash);
    458 	if(ret < 1) {
    459 		printf("Bad nsec3_hash_name retcode %d\n", ret);
    460 		unit_assert(ret == 1 || ret == 2);
    461 	}
    462 	unit_assert(hash->dname && hash->hash && hash->hash_len &&
    463 		hash->b32 && hash->b32_len);
    464 	unit_assert(hash->b32_len == (size_t)answer->rk.dname[0]);
    465 	/* does not do lowercasing. */
    466 	unit_assert(memcmp(hash->b32, answer->rk.dname+1, hash->b32_len)
    467 		== 0);
    468 
    469 	reply_info_parsedelete(rep, alloc);
    470 	query_info_clear(&qinfo);
    471 }
    472 
    473 
    474 /** Read file to test NSEC3 hash algo */
    475 static void
    476 nsec3_hash_test(const char* fname)
    477 {
    478 	/*
    479 	 * The list contains a list of ldns-testpkts entries.
    480 	 * Every entry is a test.
    481 	 * 	The qname is hashed.
    482 	 * 	The answer section AAAA RR name is the required result.
    483 	 * 	The auth section NSEC3 is used to get hash parameters.
    484 	 * The hash cache is maintained per file.
    485 	 *
    486 	 * The test does not perform canonicalization during the compare.
    487 	 */
    488 	rbtree_type ct;
    489 	struct regional* region = regional_create();
    490 	struct alloc_cache alloc;
    491 	sldns_buffer* buf = sldns_buffer_new(65535);
    492 	struct entry* e;
    493 	struct entry* list = read_datafile(fname, 1);
    494 	unit_show_func("NSEC3 hash", fname);
    495 
    496 	if(!list)
    497 		fatal_exit("could not read %s: %s", fname, strerror(errno));
    498 	rbtree_init(&ct, &nsec3_hash_cmp);
    499 	alloc_init(&alloc, NULL, 1);
    500 	unit_assert(region && buf);
    501 
    502 	/* ready to go! */
    503 	for(e = list; e; e = e->next) {
    504 		nsec3_hash_test_entry(e, &ct, &alloc, region, buf);
    505 	}
    506 
    507 	delete_entry(list);
    508 	regional_destroy(region);
    509 	alloc_clear(&alloc);
    510 	sldns_buffer_free(buf);
    511 }
    512 
    513 #define xstr(s) str(s)
    514 #define str(s) #s
    515 
    516 #define SRCDIRSTR xstr(SRCDIR)
    517 
    518 #if defined(HAVE_SSL) && defined(USE_SHA1)
    519 /* Detect if openssl is configured to disable RSASHA1 signatures,
    520  * with the rh-allow-sha1-signatures disabled. */
    521 static int
    522 rh_allow_sha1_signatures_disabled(void)
    523 {
    524 	EVP_MD_CTX* ctx;
    525 	EVP_PKEY* evp_key;
    526 	/* This key is rdata from nlnetlabs.nl DNSKEY from 20250424005001,
    527 	 * with id=50602 (ksk), size=2048b.
    528 	 * A 2048 bit key is taken to avoid key too small errors. */
    529 	unsigned char key[] = {
    530 		0x03, 0x01, 0x00, 0x01, 0xBC, 0x0B, 0xE8, 0xBB,
    531 		0x97, 0x4C, 0xB5, 0xED, 0x6F, 0x6D, 0xC2, 0xB1,
    532 		0x78, 0x69, 0x93, 0x1C, 0x72, 0x19, 0xB1, 0x05,
    533 		0x51, 0x13, 0xA1, 0xFC, 0xBF, 0x01, 0x58, 0x0D,
    534 		0x44, 0x10, 0x5F, 0x0B, 0x75, 0x0E, 0x11, 0x9A,
    535 		0xC8, 0xF8, 0x0F, 0x90, 0xFC, 0xB8, 0x09, 0xD1,
    536 		0x14, 0x39, 0x0D, 0x84, 0xCE, 0x97, 0x88, 0x82,
    537 		0x3D, 0xC5, 0xCB, 0x1A, 0xBF, 0x00, 0x46, 0x37,
    538 		0x01, 0xF1, 0xCD, 0x46, 0xA2, 0x8F, 0x83, 0x19,
    539 		0x42, 0xED, 0x6F, 0xAF, 0x37, 0x1F, 0x18, 0x82,
    540 		0x4B, 0x70, 0x2D, 0x50, 0xA5, 0xA6, 0x66, 0x48,
    541 		0x7F, 0x56, 0xA8, 0x86, 0x05, 0x41, 0xC8, 0xBE,
    542 		0x4F, 0x8B, 0x38, 0x51, 0xF0, 0xEB, 0xAD, 0x2F,
    543 		0x7A, 0xC0, 0xEF, 0xC7, 0xD2, 0x72, 0x6F, 0x16,
    544 		0x66, 0xAF, 0x59, 0x55, 0xFF, 0xEE, 0x9D, 0x50,
    545 		0xE9, 0xDB, 0xF4, 0x02, 0xBC, 0x33, 0x5C, 0xC5,
    546 		0xDA, 0x1C, 0x6A, 0xD1, 0x55, 0xD1, 0x20, 0x2B,
    547 		0x63, 0x03, 0x4B, 0x77, 0x45, 0x46, 0x78, 0x31,
    548 		0xE4, 0x90, 0xB9, 0x7F, 0x00, 0xFB, 0x62, 0x7C,
    549 		0x07, 0xD3, 0xC1, 0x00, 0xA0, 0x54, 0x63, 0x74,
    550 		0x0A, 0x17, 0x7B, 0xE7, 0xAD, 0x38, 0x07, 0x86,
    551 		0x68, 0xE4, 0xFD, 0x20, 0x68, 0xD5, 0x33, 0x92,
    552 		0xCA, 0x90, 0xDD, 0xA4, 0xE9, 0xF2, 0x11, 0xBD,
    553 		0x9D, 0xA5, 0xF5, 0xEB, 0xB9, 0xFE, 0x8F, 0xA1,
    554 		0xE4, 0xBF, 0xA4, 0xA4, 0x34, 0x5C, 0x6A, 0x95,
    555 		0xB6, 0x42, 0x22, 0xF6, 0xD6, 0x10, 0x9C, 0x9B,
    556 		0x0A, 0x56, 0xE7, 0x42, 0xE5, 0x7F, 0x1F, 0x4E,
    557 		0xBE, 0x4F, 0x8C, 0xED, 0x30, 0x63, 0xA7, 0x88,
    558 		0x93, 0xED, 0x37, 0x3C, 0x80, 0xBC, 0xD1, 0x66,
    559 		0xBD, 0xB8, 0x2E, 0x65, 0xC4, 0xC8, 0x00, 0x5B,
    560 		0xE7, 0x85, 0x96, 0xDD, 0xAA, 0x05, 0xE6, 0x4F,
    561 		0x03, 0x64, 0xFA, 0x2D, 0xF6, 0x88, 0x14, 0x8F,
    562 		0x15, 0x4D, 0xFD, 0xD3
    563 	};
    564 	size_t keylen = 260;
    565 
    566 #ifdef HAVE_EVP_MD_CTX_NEW
    567 	ctx = EVP_MD_CTX_new();
    568 #else
    569 	ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
    570 	if(ctx) EVP_MD_CTX_init(ctx);
    571 #endif
    572 	if(!ctx) return 0;
    573 
    574 	evp_key = sldns_key_rsa2pkey_raw(key, keylen);
    575 	if(!evp_key) {
    576 #ifdef HAVE_EVP_MD_CTX_NEW
    577 		EVP_MD_CTX_destroy(ctx);
    578 #else
    579 		EVP_MD_CTX_cleanup(ctx);
    580 		free(ctx);
    581 #endif
    582 		return 0;
    583 	}
    584 
    585 #ifndef HAVE_EVP_DIGESTVERIFY
    586 	(void)evp_key; /* not used */
    587 	if(EVP_DigestInit(ctx, EVP_sha1()) == 0)
    588 #else
    589 	if(EVP_DigestVerifyInit(ctx, NULL, EVP_sha1(), NULL, evp_key) == 0)
    590 #endif
    591 	{
    592 		unsigned long e = ERR_get_error();
    593 #ifdef EVP_R_INVALID_DIGEST
    594 		if (ERR_GET_LIB(e) == ERR_LIB_EVP &&
    595 			ERR_GET_REASON(e) == EVP_R_INVALID_DIGEST) {
    596 			/* rh-allow-sha1-signatures makes use of sha1 invalid. */
    597 			if(vsig)
    598 				printf("Detected that rh-allow-sha1-signatures is off, and disables SHA1 signatures\n");
    599 #ifdef HAVE_EVP_MD_CTX_NEW
    600 			EVP_MD_CTX_destroy(ctx);
    601 #else
    602 			EVP_MD_CTX_cleanup(ctx);
    603 			free(ctx);
    604 #endif
    605 			EVP_PKEY_free(evp_key);
    606 			return 1;
    607 		}
    608 #endif /* EVP_R_INVALID_DIGEST */
    609 		/* The signature verify failed for another reason. */
    610 		log_crypto_err_code("EVP_DigestVerifyInit", e);
    611 #ifdef HAVE_EVP_MD_CTX_NEW
    612 		EVP_MD_CTX_destroy(ctx);
    613 #else
    614 		EVP_MD_CTX_cleanup(ctx);
    615 		free(ctx);
    616 #endif
    617 		EVP_PKEY_free(evp_key);
    618 		return 0;
    619 	}
    620 #ifdef HAVE_EVP_MD_CTX_NEW
    621 	EVP_MD_CTX_destroy(ctx);
    622 #else
    623 	EVP_MD_CTX_cleanup(ctx);
    624 	free(ctx);
    625 #endif
    626 	EVP_PKEY_free(evp_key);
    627 	return 0;
    628 }
    629 #endif /* HAVE_SSL && USE_SHA1 */
    630 
    631 void
    632 verify_test(void)
    633 {
    634 	unit_show_feature("signature verify");
    635 
    636 #if defined(HAVE_SSL) && defined(USE_SHA1)
    637 	if(rh_allow_sha1_signatures_disabled()) {
    638 		/* Allow the use of SHA1 signatures for the test,
    639 		 * in case that OpenSSL disallows use of RSASHA1
    640 		 * with rh-allow-sha1-signatures disabled. */
    641 #ifndef UB_ON_WINDOWS
    642 		setenv("OPENSSL_ENABLE_SHA1_SIGNATURES", "1", 0);
    643 #else
    644 		_putenv("OPENSSL_ENABLE_SHA1_SIGNATURES=1");
    645 #endif
    646 	}
    647 #endif
    648 
    649 #ifdef USE_SHA1
    650 	verifytest_file(SRCDIRSTR "/testdata/test_signatures.1", "20070818005004");
    651 #endif
    652 #if defined(USE_DSA) && defined(USE_SHA1)
    653 	verifytest_file(SRCDIRSTR "/testdata/test_signatures.2", "20080414005004");
    654 	verifytest_file(SRCDIRSTR "/testdata/test_signatures.3", "20080416005004");
    655 	verifytest_file(SRCDIRSTR "/testdata/test_signatures.4", "20080416005004");
    656 	verifytest_file(SRCDIRSTR "/testdata/test_signatures.5", "20080416005004");
    657 	verifytest_file(SRCDIRSTR "/testdata/test_signatures.6", "20080416005004");
    658 	verifytest_file(SRCDIRSTR "/testdata/test_signatures.7", "20070829144150");
    659 #endif /* USE_DSA */
    660 #ifdef USE_SHA1
    661 	verifytest_file(SRCDIRSTR "/testdata/test_signatures.8", "20070829144150");
    662 #endif
    663 #if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
    664 	verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha256", "20070829144150");
    665 #  ifdef USE_SHA1
    666 	verifytest_file(SRCDIRSTR "/testdata/test_sigs.sha1_and_256", "20070829144150");
    667 #  endif
    668 	verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha256_draft", "20090101000000");
    669 #endif
    670 #if (defined(HAVE_EVP_SHA512) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
    671 	verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha512_draft", "20070829144150");
    672 	verifytest_file(SRCDIRSTR "/testdata/test_signatures.9", "20171215000000");
    673 #endif
    674 #ifdef USE_SHA1
    675 	verifytest_file(SRCDIRSTR "/testdata/test_sigs.hinfo", "20090107100022");
    676 	verifytest_file(SRCDIRSTR "/testdata/test_sigs.revoked", "20080414005004");
    677 #endif
    678 #ifdef USE_GOST
    679 	if(sldns_key_EVP_load_gost_id())
    680 	  verifytest_file(SRCDIRSTR "/testdata/test_sigs.gost", "20090807060504");
    681 	else printf("Warning: skipped GOST, openssl does not provide gost.\n");
    682 #endif
    683 #ifdef USE_ECDSA
    684 	/* test for support in case we use libNSS and ECC is removed */
    685 	if(dnskey_algo_id_is_supported(LDNS_ECDSAP256SHA256)) {
    686 		verifytest_file(SRCDIRSTR "/testdata/test_sigs.ecdsa_p256", "20100908100439");
    687 		verifytest_file(SRCDIRSTR "/testdata/test_sigs.ecdsa_p384", "20100908100439");
    688 	}
    689 	dstest_file(SRCDIRSTR "/testdata/test_ds.sha384");
    690 #endif
    691 #ifdef USE_ED25519
    692 	if(dnskey_algo_id_is_supported(LDNS_ED25519)) {
    693 		verifytest_file(SRCDIRSTR "/testdata/test_sigs.ed25519", "20170530140439");
    694 	}
    695 #endif
    696 #ifdef USE_ED448
    697 	if(dnskey_algo_id_is_supported(LDNS_ED448)) {
    698 		verifytest_file(SRCDIRSTR "/testdata/test_sigs.ed448", "20180408143630");
    699 	}
    700 #endif
    701 #ifdef USE_SHA1
    702 	dstest_file(SRCDIRSTR "/testdata/test_ds.sha1");
    703 #endif
    704 	nsectest();
    705 	nsec3_hash_test(SRCDIRSTR "/testdata/test_nsec3_hash.1");
    706 }
    707