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