1 /* 2 * validator/val_sigcrypt.c - validator signature crypto functions. 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 LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /** 37 * \file 38 * 39 * This file contains helper functions for the validator module. 40 * The functions help with signature verification and checking, the 41 * bridging between RR wireformat data and crypto calls. 42 */ 43 #include "config.h" 44 #include <ldns/ldns.h> 45 #include "validator/val_sigcrypt.h" 46 #include "validator/val_secalgo.h" 47 #include "validator/validator.h" 48 #include "util/data/msgreply.h" 49 #include "util/data/msgparse.h" 50 #include "util/data/dname.h" 51 #include "util/rbtree.h" 52 #include "util/module.h" 53 #include "util/net_help.h" 54 #include "util/regional.h" 55 56 #if !defined(HAVE_SSL) && !defined(HAVE_NSS) 57 #error "Need crypto library to do digital signature cryptography" 58 #endif 59 60 #ifdef HAVE_OPENSSL_ERR_H 61 #include <openssl/err.h> 62 #endif 63 64 #ifdef HAVE_OPENSSL_RAND_H 65 #include <openssl/rand.h> 66 #endif 67 68 #ifdef HAVE_OPENSSL_CONF_H 69 #include <openssl/conf.h> 70 #endif 71 72 #ifdef HAVE_OPENSSL_ENGINE_H 73 #include <openssl/engine.h> 74 #endif 75 76 /** return number of rrs in an rrset */ 77 static size_t 78 rrset_get_count(struct ub_packed_rrset_key* rrset) 79 { 80 struct packed_rrset_data* d = (struct packed_rrset_data*) 81 rrset->entry.data; 82 if(!d) return 0; 83 return d->count; 84 } 85 86 /** 87 * Get RR signature count 88 */ 89 static size_t 90 rrset_get_sigcount(struct ub_packed_rrset_key* k) 91 { 92 struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data; 93 return d->rrsig_count; 94 } 95 96 /** 97 * Get signature keytag value 98 * @param k: rrset (with signatures) 99 * @param sig_idx: signature index. 100 * @return keytag or 0 if malformed rrsig. 101 */ 102 static uint16_t 103 rrset_get_sig_keytag(struct ub_packed_rrset_key* k, size_t sig_idx) 104 { 105 uint16_t t; 106 struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data; 107 log_assert(sig_idx < d->rrsig_count); 108 if(d->rr_len[d->count + sig_idx] < 2+18) 109 return 0; 110 memmove(&t, d->rr_data[d->count + sig_idx]+2+16, 2); 111 return ntohs(t); 112 } 113 114 /** 115 * Get signature signing algorithm value 116 * @param k: rrset (with signatures) 117 * @param sig_idx: signature index. 118 * @return algo or 0 if malformed rrsig. 119 */ 120 static int 121 rrset_get_sig_algo(struct ub_packed_rrset_key* k, size_t sig_idx) 122 { 123 struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data; 124 log_assert(sig_idx < d->rrsig_count); 125 if(d->rr_len[d->count + sig_idx] < 2+3) 126 return 0; 127 return (int)d->rr_data[d->count + sig_idx][2+2]; 128 } 129 130 /** get rdata pointer and size */ 131 static void 132 rrset_get_rdata(struct ub_packed_rrset_key* k, size_t idx, uint8_t** rdata, 133 size_t* len) 134 { 135 struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data; 136 log_assert(d && idx < (d->count + d->rrsig_count)); 137 *rdata = d->rr_data[idx]; 138 *len = d->rr_len[idx]; 139 } 140 141 uint16_t 142 dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx) 143 { 144 uint8_t* rdata; 145 size_t len; 146 uint16_t f; 147 rrset_get_rdata(k, idx, &rdata, &len); 148 if(len < 2+2) 149 return 0; 150 memmove(&f, rdata+2, 2); 151 f = ntohs(f); 152 return f; 153 } 154 155 /** 156 * Get DNSKEY protocol value from rdata 157 * @param k: DNSKEY rrset. 158 * @param idx: which key. 159 * @return protocol octet value 160 */ 161 static int 162 dnskey_get_protocol(struct ub_packed_rrset_key* k, size_t idx) 163 { 164 uint8_t* rdata; 165 size_t len; 166 rrset_get_rdata(k, idx, &rdata, &len); 167 if(len < 2+4) 168 return 0; 169 return (int)rdata[2+2]; 170 } 171 172 int 173 dnskey_get_algo(struct ub_packed_rrset_key* k, size_t idx) 174 { 175 uint8_t* rdata; 176 size_t len; 177 rrset_get_rdata(k, idx, &rdata, &len); 178 if(len < 2+4) 179 return 0; 180 return (int)rdata[2+3]; 181 } 182 183 /** get public key rdata field from a dnskey RR and do some checks */ 184 static void 185 dnskey_get_pubkey(struct ub_packed_rrset_key* k, size_t idx, 186 unsigned char** pk, unsigned int* pklen) 187 { 188 uint8_t* rdata; 189 size_t len; 190 rrset_get_rdata(k, idx, &rdata, &len); 191 if(len < 2+5) { 192 *pk = NULL; 193 *pklen = 0; 194 return; 195 } 196 *pk = (unsigned char*)rdata+2+4; 197 *pklen = (unsigned)len-2-4; 198 } 199 200 int 201 ds_get_key_algo(struct ub_packed_rrset_key* k, size_t idx) 202 { 203 uint8_t* rdata; 204 size_t len; 205 rrset_get_rdata(k, idx, &rdata, &len); 206 if(len < 2+3) 207 return 0; 208 return (int)rdata[2+2]; 209 } 210 211 int 212 ds_get_digest_algo(struct ub_packed_rrset_key* k, size_t idx) 213 { 214 uint8_t* rdata; 215 size_t len; 216 rrset_get_rdata(k, idx, &rdata, &len); 217 if(len < 2+4) 218 return 0; 219 return (int)rdata[2+3]; 220 } 221 222 uint16_t 223 ds_get_keytag(struct ub_packed_rrset_key* ds_rrset, size_t ds_idx) 224 { 225 uint16_t t; 226 uint8_t* rdata; 227 size_t len; 228 rrset_get_rdata(ds_rrset, ds_idx, &rdata, &len); 229 if(len < 2+2) 230 return 0; 231 memmove(&t, rdata+2, 2); 232 return ntohs(t); 233 } 234 235 /** 236 * Return pointer to the digest in a DS RR. 237 * @param k: DS rrset. 238 * @param idx: which DS. 239 * @param digest: digest data is returned. 240 * on error, this is NULL. 241 * @param len: length of digest is returned. 242 * on error, the length is 0. 243 */ 244 static void 245 ds_get_sigdata(struct ub_packed_rrset_key* k, size_t idx, uint8_t** digest, 246 size_t* len) 247 { 248 uint8_t* rdata; 249 size_t rdlen; 250 rrset_get_rdata(k, idx, &rdata, &rdlen); 251 if(rdlen < 2+5) { 252 *digest = NULL; 253 *len = 0; 254 return; 255 } 256 *digest = rdata + 2 + 4; 257 *len = rdlen - 2 - 4; 258 } 259 260 /** 261 * Return size of DS digest according to its hash algorithm. 262 * @param k: DS rrset. 263 * @param idx: which DS. 264 * @return size in bytes of digest, or 0 if not supported. 265 */ 266 static size_t 267 ds_digest_size_algo(struct ub_packed_rrset_key* k, size_t idx) 268 { 269 return ds_digest_size_supported(ds_get_digest_algo(k, idx)); 270 } 271 272 /** 273 * Create a DS digest for a DNSKEY entry. 274 * 275 * @param env: module environment. Uses scratch space. 276 * @param dnskey_rrset: DNSKEY rrset. 277 * @param dnskey_idx: index of RR in rrset. 278 * @param ds_rrset: DS rrset 279 * @param ds_idx: index of RR in DS rrset. 280 * @param digest: digest is returned in here (must be correctly sized). 281 * @return false on error. 282 */ 283 static int 284 ds_create_dnskey_digest(struct module_env* env, 285 struct ub_packed_rrset_key* dnskey_rrset, size_t dnskey_idx, 286 struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, 287 uint8_t* digest) 288 { 289 ldns_buffer* b = env->scratch_buffer; 290 uint8_t* dnskey_rdata; 291 size_t dnskey_len; 292 rrset_get_rdata(dnskey_rrset, dnskey_idx, &dnskey_rdata, &dnskey_len); 293 294 /* create digest source material in buffer 295 * digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA); 296 * DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key. */ 297 ldns_buffer_clear(b); 298 ldns_buffer_write(b, dnskey_rrset->rk.dname, 299 dnskey_rrset->rk.dname_len); 300 query_dname_tolower(ldns_buffer_begin(b)); 301 ldns_buffer_write(b, dnskey_rdata+2, dnskey_len-2); /* skip rdatalen*/ 302 ldns_buffer_flip(b); 303 304 return secalgo_ds_digest(ds_get_digest_algo(ds_rrset, ds_idx), 305 (unsigned char*)ldns_buffer_begin(b), ldns_buffer_limit(b), 306 (unsigned char*)digest); 307 } 308 309 int ds_digest_match_dnskey(struct module_env* env, 310 struct ub_packed_rrset_key* dnskey_rrset, size_t dnskey_idx, 311 struct ub_packed_rrset_key* ds_rrset, size_t ds_idx) 312 { 313 uint8_t* ds; /* DS digest */ 314 size_t dslen; 315 uint8_t* digest; /* generated digest */ 316 size_t digestlen = ds_digest_size_algo(ds_rrset, ds_idx); 317 318 if(digestlen == 0) { 319 verbose(VERB_QUERY, "DS fail: not supported, or DS RR " 320 "format error"); 321 return 0; /* not supported, or DS RR format error */ 322 } 323 /* check digest length in DS with length from hash function */ 324 ds_get_sigdata(ds_rrset, ds_idx, &ds, &dslen); 325 if(!ds || dslen != digestlen) { 326 verbose(VERB_QUERY, "DS fail: DS RR algo and digest do not " 327 "match each other"); 328 return 0; /* DS algorithm and digest do not match */ 329 } 330 331 digest = regional_alloc(env->scratch, digestlen); 332 if(!digest) { 333 verbose(VERB_QUERY, "DS fail: out of memory"); 334 return 0; /* mem error */ 335 } 336 if(!ds_create_dnskey_digest(env, dnskey_rrset, dnskey_idx, ds_rrset, 337 ds_idx, digest)) { 338 verbose(VERB_QUERY, "DS fail: could not calc key digest"); 339 return 0; /* digest algo failed */ 340 } 341 if(memcmp(digest, ds, dslen) != 0) { 342 verbose(VERB_QUERY, "DS fail: digest is different"); 343 return 0; /* digest different */ 344 } 345 return 1; 346 } 347 348 int 349 ds_digest_algo_is_supported(struct ub_packed_rrset_key* ds_rrset, 350 size_t ds_idx) 351 { 352 return (ds_digest_size_algo(ds_rrset, ds_idx) != 0); 353 } 354 355 int 356 ds_key_algo_is_supported(struct ub_packed_rrset_key* ds_rrset, 357 size_t ds_idx) 358 { 359 return dnskey_algo_id_is_supported(ds_get_key_algo(ds_rrset, ds_idx)); 360 } 361 362 uint16_t 363 dnskey_calc_keytag(struct ub_packed_rrset_key* dnskey_rrset, size_t dnskey_idx) 364 { 365 uint8_t* data; 366 size_t len; 367 rrset_get_rdata(dnskey_rrset, dnskey_idx, &data, &len); 368 /* do not pass rdatalen to ldns */ 369 return ldns_calc_keytag_raw(data+2, len-2); 370 } 371 372 int dnskey_algo_is_supported(struct ub_packed_rrset_key* dnskey_rrset, 373 size_t dnskey_idx) 374 { 375 return dnskey_algo_id_is_supported(dnskey_get_algo(dnskey_rrset, 376 dnskey_idx)); 377 } 378 379 void algo_needs_init_dnskey_add(struct algo_needs* n, 380 struct ub_packed_rrset_key* dnskey, uint8_t* sigalg) 381 { 382 uint8_t algo; 383 size_t i, total = n->num; 384 size_t num = rrset_get_count(dnskey); 385 386 for(i=0; i<num; i++) { 387 algo = (uint8_t)dnskey_get_algo(dnskey, i); 388 if(!dnskey_algo_id_is_supported((int)algo)) 389 continue; 390 if(n->needs[algo] == 0) { 391 n->needs[algo] = 1; 392 sigalg[total] = algo; 393 total++; 394 } 395 } 396 sigalg[total] = 0; 397 n->num = total; 398 } 399 400 void algo_needs_init_list(struct algo_needs* n, uint8_t* sigalg) 401 { 402 uint8_t algo; 403 size_t total = 0; 404 405 memset(n->needs, 0, sizeof(uint8_t)*ALGO_NEEDS_MAX); 406 while( (algo=*sigalg++) != 0) { 407 log_assert(dnskey_algo_id_is_supported((int)algo)); 408 log_assert(n->needs[algo] == 0); 409 n->needs[algo] = 1; 410 total++; 411 } 412 n->num = total; 413 } 414 415 void algo_needs_init_ds(struct algo_needs* n, struct ub_packed_rrset_key* ds, 416 int fav_ds_algo, uint8_t* sigalg) 417 { 418 uint8_t algo; 419 size_t i, total = 0; 420 size_t num = rrset_get_count(ds); 421 422 memset(n->needs, 0, sizeof(uint8_t)*ALGO_NEEDS_MAX); 423 for(i=0; i<num; i++) { 424 if(ds_get_digest_algo(ds, i) != fav_ds_algo) 425 continue; 426 algo = (uint8_t)ds_get_key_algo(ds, i); 427 if(!dnskey_algo_id_is_supported((int)algo)) 428 continue; 429 log_assert(algo != 0); /* we do not support 0 and is EOS */ 430 if(n->needs[algo] == 0) { 431 n->needs[algo] = 1; 432 sigalg[total] = algo; 433 total++; 434 } 435 } 436 sigalg[total] = 0; 437 n->num = total; 438 } 439 440 int algo_needs_set_secure(struct algo_needs* n, uint8_t algo) 441 { 442 if(n->needs[algo]) { 443 n->needs[algo] = 0; 444 n->num --; 445 if(n->num == 0) /* done! */ 446 return 1; 447 } 448 return 0; 449 } 450 451 void algo_needs_set_bogus(struct algo_needs* n, uint8_t algo) 452 { 453 if(n->needs[algo]) n->needs[algo] = 2; /* need it, but bogus */ 454 } 455 456 size_t algo_needs_num_missing(struct algo_needs* n) 457 { 458 return n->num; 459 } 460 461 int algo_needs_missing(struct algo_needs* n) 462 { 463 int i; 464 /* first check if a needed algo was bogus - report that */ 465 for(i=0; i<ALGO_NEEDS_MAX; i++) 466 if(n->needs[i] == 2) 467 return 0; 468 /* now check which algo is missing */ 469 for(i=0; i<ALGO_NEEDS_MAX; i++) 470 if(n->needs[i] == 1) 471 return i; 472 return 0; 473 } 474 475 enum sec_status 476 dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve, 477 struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, 478 uint8_t* sigalg, char** reason) 479 { 480 enum sec_status sec; 481 size_t i, num; 482 rbtree_t* sortree = NULL; 483 /* make sure that for all DNSKEY algorithms there are valid sigs */ 484 struct algo_needs needs; 485 int alg; 486 487 num = rrset_get_sigcount(rrset); 488 if(num == 0) { 489 verbose(VERB_QUERY, "rrset failed to verify due to a lack of " 490 "signatures"); 491 *reason = "no signatures"; 492 return sec_status_bogus; 493 } 494 495 if(sigalg) { 496 algo_needs_init_list(&needs, sigalg); 497 if(algo_needs_num_missing(&needs) == 0) { 498 verbose(VERB_QUERY, "zone has no known algorithms"); 499 *reason = "zone has no known algorithms"; 500 return sec_status_insecure; 501 } 502 } 503 for(i=0; i<num; i++) { 504 sec = dnskeyset_verify_rrset_sig(env, ve, *env->now, rrset, 505 dnskey, i, &sortree, reason); 506 /* see which algorithm has been fixed up */ 507 if(sec == sec_status_secure) { 508 if(!sigalg) 509 return sec; /* done! */ 510 else if(algo_needs_set_secure(&needs, 511 (uint8_t)rrset_get_sig_algo(rrset, i))) 512 return sec; /* done! */ 513 } else if(sigalg && sec == sec_status_bogus) { 514 algo_needs_set_bogus(&needs, 515 (uint8_t)rrset_get_sig_algo(rrset, i)); 516 } 517 } 518 if(sigalg && (alg=algo_needs_missing(&needs)) != 0) { 519 verbose(VERB_ALGO, "rrset failed to verify: " 520 "no valid signatures for %d algorithms", 521 (int)algo_needs_num_missing(&needs)); 522 algo_needs_reason(env, alg, reason, "no signatures"); 523 } else { 524 verbose(VERB_ALGO, "rrset failed to verify: " 525 "no valid signatures"); 526 } 527 return sec_status_bogus; 528 } 529 530 void algo_needs_reason(struct module_env* env, int alg, char** reason, char* s) 531 { 532 char buf[256]; 533 ldns_lookup_table *t = ldns_lookup_by_id(ldns_algorithms, alg); 534 if(t&&t->name) 535 snprintf(buf, sizeof(buf), "%s with algorithm %s", s, t->name); 536 else snprintf(buf, sizeof(buf), "%s with algorithm ALG%u", s, 537 (unsigned)alg); 538 *reason = regional_strdup(env->scratch, buf); 539 if(!*reason) 540 *reason = s; 541 } 542 543 enum sec_status 544 dnskey_verify_rrset(struct module_env* env, struct val_env* ve, 545 struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, 546 size_t dnskey_idx, char** reason) 547 { 548 enum sec_status sec; 549 size_t i, num, numchecked = 0; 550 rbtree_t* sortree = NULL; 551 int buf_canon = 0; 552 uint16_t tag = dnskey_calc_keytag(dnskey, dnskey_idx); 553 int algo = dnskey_get_algo(dnskey, dnskey_idx); 554 555 num = rrset_get_sigcount(rrset); 556 if(num == 0) { 557 verbose(VERB_QUERY, "rrset failed to verify due to a lack of " 558 "signatures"); 559 *reason = "no signatures"; 560 return sec_status_bogus; 561 } 562 for(i=0; i<num; i++) { 563 /* see if sig matches keytag and algo */ 564 if(algo != rrset_get_sig_algo(rrset, i) || 565 tag != rrset_get_sig_keytag(rrset, i)) 566 continue; 567 buf_canon = 0; 568 sec = dnskey_verify_rrset_sig(env->scratch, 569 env->scratch_buffer, ve, *env->now, rrset, 570 dnskey, dnskey_idx, i, &sortree, &buf_canon, reason); 571 if(sec == sec_status_secure) 572 return sec; 573 numchecked ++; 574 } 575 verbose(VERB_ALGO, "rrset failed to verify: all signatures are bogus"); 576 if(!numchecked) *reason = "signature missing"; 577 return sec_status_bogus; 578 } 579 580 enum sec_status 581 dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve, 582 uint32_t now, struct ub_packed_rrset_key* rrset, 583 struct ub_packed_rrset_key* dnskey, size_t sig_idx, 584 struct rbtree_t** sortree, char** reason) 585 { 586 /* find matching keys and check them */ 587 enum sec_status sec = sec_status_bogus; 588 uint16_t tag = rrset_get_sig_keytag(rrset, sig_idx); 589 int algo = rrset_get_sig_algo(rrset, sig_idx); 590 size_t i, num = rrset_get_count(dnskey); 591 size_t numchecked = 0; 592 int buf_canon = 0; 593 verbose(VERB_ALGO, "verify sig %d %d", (int)tag, algo); 594 if(!dnskey_algo_id_is_supported(algo)) { 595 verbose(VERB_QUERY, "verify sig: unknown algorithm"); 596 return sec_status_insecure; 597 } 598 599 for(i=0; i<num; i++) { 600 /* see if key matches keytag and algo */ 601 if(algo != dnskey_get_algo(dnskey, i) || 602 tag != dnskey_calc_keytag(dnskey, i)) 603 continue; 604 numchecked ++; 605 606 /* see if key verifies */ 607 sec = dnskey_verify_rrset_sig(env->scratch, 608 env->scratch_buffer, ve, now, rrset, dnskey, i, 609 sig_idx, sortree, &buf_canon, reason); 610 if(sec == sec_status_secure) 611 return sec; 612 } 613 if(numchecked == 0) { 614 *reason = "signatures from unknown keys"; 615 verbose(VERB_QUERY, "verify: could not find appropriate key"); 616 return sec_status_bogus; 617 } 618 return sec_status_bogus; 619 } 620 621 /** 622 * RR entries in a canonical sorted tree of RRs 623 */ 624 struct canon_rr { 625 /** rbtree node, key is this structure */ 626 rbnode_t node; 627 /** rrset the RR is in */ 628 struct ub_packed_rrset_key* rrset; 629 /** which RR in the rrset */ 630 size_t rr_idx; 631 }; 632 633 /** 634 * Compare two RR for canonical order, in a field-style sweep. 635 * @param d: rrset data 636 * @param desc: ldns wireformat descriptor. 637 * @param i: first RR to compare 638 * @param j: first RR to compare 639 * @return comparison code. 640 */ 641 static int 642 canonical_compare_byfield(struct packed_rrset_data* d, 643 const ldns_rr_descriptor* desc, size_t i, size_t j) 644 { 645 /* sweep across rdata, keep track of some state: 646 * which rr field, and bytes left in field. 647 * current position in rdata, length left. 648 * are we in a dname, length left in a label. 649 */ 650 int wfi = -1; /* current wireformat rdata field (rdf) */ 651 int wfj = -1; 652 uint8_t* di = d->rr_data[i]+2; /* ptr to current rdata byte */ 653 uint8_t* dj = d->rr_data[j]+2; 654 size_t ilen = d->rr_len[i]-2; /* length left in rdata */ 655 size_t jlen = d->rr_len[j]-2; 656 int dname_i = 0; /* true if these bytes are part of a name */ 657 int dname_j = 0; 658 size_t lablen_i = 0; /* 0 for label length byte,for first byte of rdf*/ 659 size_t lablen_j = 0; /* otherwise remaining length of rdf or label */ 660 int dname_num_i = (int)desc->_dname_count; /* decreased at root label */ 661 int dname_num_j = (int)desc->_dname_count; 662 663 /* loop while there are rdata bytes available for both rrs, 664 * and still some lowercasing needs to be done; either the dnames 665 * have not been reached yet, or they are currently being processed */ 666 while(ilen > 0 && jlen > 0 && (dname_num_i > 0 || dname_num_j > 0)) { 667 /* compare these two bytes */ 668 /* lowercase if in a dname and not a label length byte */ 669 if( ((dname_i && lablen_i)?(uint8_t)tolower((int)*di):*di) 670 != ((dname_j && lablen_j)?(uint8_t)tolower((int)*dj):*dj) 671 ) { 672 if(((dname_i && lablen_i)?(uint8_t)tolower((int)*di):*di) 673 < ((dname_j && lablen_j)?(uint8_t)tolower((int)*dj):*dj)) 674 return -1; 675 return 1; 676 } 677 ilen--; 678 jlen--; 679 /* bytes are equal */ 680 681 /* advance field i */ 682 /* lablen 0 means that this byte is the first byte of the 683 * next rdata field; inspect this rdata field and setup 684 * to process the rest of this rdata field. 685 * The reason to first read the byte, then setup the rdf, 686 * is that we are then sure the byte is available and short 687 * rdata is handled gracefully (even if it is a formerr). */ 688 if(lablen_i == 0) { 689 if(dname_i) { 690 /* scan this dname label */ 691 /* capture length to lowercase */ 692 lablen_i = (size_t)*di; 693 if(lablen_i == 0) { 694 /* end root label */ 695 dname_i = 0; 696 dname_num_i--; 697 /* if dname num is 0, then the 698 * remainder is binary only */ 699 if(dname_num_i == 0) 700 lablen_i = ilen; 701 } 702 } else { 703 /* scan this rdata field */ 704 wfi++; 705 if(desc->_wireformat[wfi] 706 == LDNS_RDF_TYPE_DNAME) { 707 dname_i = 1; 708 lablen_i = (size_t)*di; 709 if(lablen_i == 0) { 710 dname_i = 0; 711 dname_num_i--; 712 if(dname_num_i == 0) 713 lablen_i = ilen; 714 } 715 } else if(desc->_wireformat[wfi] 716 == LDNS_RDF_TYPE_STR) 717 lablen_i = (size_t)*di; 718 else lablen_i = get_rdf_size( 719 desc->_wireformat[wfi]) - 1; 720 } 721 } else lablen_i--; 722 723 /* advance field j; same as for i */ 724 if(lablen_j == 0) { 725 if(dname_j) { 726 lablen_j = (size_t)*dj; 727 if(lablen_j == 0) { 728 dname_j = 0; 729 dname_num_j--; 730 if(dname_num_j == 0) 731 lablen_j = jlen; 732 } 733 } else { 734 wfj++; 735 if(desc->_wireformat[wfj] 736 == LDNS_RDF_TYPE_DNAME) { 737 dname_j = 1; 738 lablen_j = (size_t)*dj; 739 if(lablen_j == 0) { 740 dname_j = 0; 741 dname_num_j--; 742 if(dname_num_j == 0) 743 lablen_j = jlen; 744 } 745 } else if(desc->_wireformat[wfj] 746 == LDNS_RDF_TYPE_STR) 747 lablen_j = (size_t)*dj; 748 else lablen_j = get_rdf_size( 749 desc->_wireformat[wfj]) - 1; 750 } 751 } else lablen_j--; 752 di++; 753 dj++; 754 } 755 /* end of the loop; because we advanced byte by byte; now we have 756 * that the rdata has ended, or that there is a binary remainder */ 757 /* shortest first */ 758 if(ilen == 0 && jlen == 0) 759 return 0; 760 if(ilen == 0) 761 return -1; 762 if(jlen == 0) 763 return 1; 764 /* binary remainder, capture comparison in wfi variable */ 765 if((wfi = memcmp(di, dj, (ilen<jlen)?ilen:jlen)) != 0) 766 return wfi; 767 if(ilen < jlen) 768 return -1; 769 if(jlen < ilen) 770 return 1; 771 return 0; 772 } 773 774 /** 775 * Compare two RRs in the same RRset and determine their relative 776 * canonical order. 777 * @param rrset: the rrset in which to perform compares. 778 * @param i: first RR to compare 779 * @param j: first RR to compare 780 * @return 0 if RR i== RR j, -1 if <, +1 if >. 781 */ 782 static int 783 canonical_compare(struct ub_packed_rrset_key* rrset, size_t i, size_t j) 784 { 785 struct packed_rrset_data* d = (struct packed_rrset_data*) 786 rrset->entry.data; 787 const ldns_rr_descriptor* desc; 788 uint16_t type = ntohs(rrset->rk.type); 789 size_t minlen; 790 int c; 791 792 if(i==j) 793 return 0; 794 /* in case rdata-len is to be compared for canonical order 795 c = memcmp(d->rr_data[i], d->rr_data[j], 2); 796 if(c != 0) 797 return c; */ 798 799 switch(type) { 800 /* These RR types have only a name as RDATA. 801 * This name has to be canonicalized.*/ 802 case LDNS_RR_TYPE_NS: 803 case LDNS_RR_TYPE_MD: 804 case LDNS_RR_TYPE_MF: 805 case LDNS_RR_TYPE_CNAME: 806 case LDNS_RR_TYPE_MB: 807 case LDNS_RR_TYPE_MG: 808 case LDNS_RR_TYPE_MR: 809 case LDNS_RR_TYPE_PTR: 810 case LDNS_RR_TYPE_DNAME: 811 return query_dname_compare(d->rr_data[i]+2, 812 d->rr_data[j]+2); 813 814 /* These RR types have STR and fixed size rdata fields 815 * before one or more name fields that need canonicalizing, 816 * and after that a byte-for byte remainder can be compared. 817 */ 818 /* type starts with the name; remainder is binary compared */ 819 case LDNS_RR_TYPE_NXT: 820 /* use rdata field formats */ 821 case LDNS_RR_TYPE_MINFO: 822 case LDNS_RR_TYPE_RP: 823 case LDNS_RR_TYPE_SOA: 824 case LDNS_RR_TYPE_RT: 825 case LDNS_RR_TYPE_AFSDB: 826 case LDNS_RR_TYPE_KX: 827 case LDNS_RR_TYPE_MX: 828 case LDNS_RR_TYPE_SIG: 829 /* RRSIG signer name has to be downcased */ 830 case LDNS_RR_TYPE_RRSIG: 831 case LDNS_RR_TYPE_PX: 832 case LDNS_RR_TYPE_NAPTR: 833 case LDNS_RR_TYPE_SRV: 834 desc = ldns_rr_descript(type); 835 log_assert(desc); 836 /* this holds for the types that need canonicalizing */ 837 log_assert(desc->_minimum == desc->_maximum); 838 return canonical_compare_byfield(d, desc, i, j); 839 840 case LDNS_RR_TYPE_HINFO: /* no longer downcased */ 841 case LDNS_RR_TYPE_NSEC: 842 default: 843 /* For unknown RR types, or types not listed above, 844 * no canonicalization is needed, do binary compare */ 845 /* byte for byte compare, equal means shortest first*/ 846 minlen = d->rr_len[i]-2; 847 if(minlen > d->rr_len[j]-2) 848 minlen = d->rr_len[j]-2; 849 c = memcmp(d->rr_data[i]+2, d->rr_data[j]+2, minlen); 850 if(c!=0) 851 return c; 852 /* rdata equal, shortest is first */ 853 if(d->rr_len[i] < d->rr_len[j]) 854 return -1; 855 if(d->rr_len[i] > d->rr_len[j]) 856 return 1; 857 /* rdata equal, length equal */ 858 break; 859 } 860 return 0; 861 } 862 863 int 864 canonical_tree_compare(const void* k1, const void* k2) 865 { 866 struct canon_rr* r1 = (struct canon_rr*)k1; 867 struct canon_rr* r2 = (struct canon_rr*)k2; 868 log_assert(r1->rrset == r2->rrset); 869 return canonical_compare(r1->rrset, r1->rr_idx, r2->rr_idx); 870 } 871 872 /** 873 * Sort RRs for rrset in canonical order. 874 * Does not actually canonicalize the RR rdatas. 875 * Does not touch rrsigs. 876 * @param rrset: to sort. 877 * @param d: rrset data. 878 * @param sortree: tree to sort into. 879 * @param rrs: rr storage. 880 */ 881 static void 882 canonical_sort(struct ub_packed_rrset_key* rrset, struct packed_rrset_data* d, 883 rbtree_t* sortree, struct canon_rr* rrs) 884 { 885 size_t i; 886 /* insert into rbtree to sort and detect duplicates */ 887 for(i=0; i<d->count; i++) { 888 rrs[i].node.key = &rrs[i]; 889 rrs[i].rrset = rrset; 890 rrs[i].rr_idx = i; 891 if(!rbtree_insert(sortree, &rrs[i].node)) { 892 /* this was a duplicate */ 893 } 894 } 895 } 896 897 /** 898 * Inser canonical owner name into buffer. 899 * @param buf: buffer to insert into at current position. 900 * @param k: rrset with its owner name. 901 * @param sig: signature with signer name and label count. 902 * must be length checked, at least 18 bytes long. 903 * @param can_owner: position in buffer returned for future use. 904 * @param can_owner_len: length of canonical owner name. 905 */ 906 static void 907 insert_can_owner(ldns_buffer* buf, struct ub_packed_rrset_key* k, 908 uint8_t* sig, uint8_t** can_owner, size_t* can_owner_len) 909 { 910 int rrsig_labels = (int)sig[3]; 911 int fqdn_labels = dname_signame_label_count(k->rk.dname); 912 *can_owner = ldns_buffer_current(buf); 913 if(rrsig_labels == fqdn_labels) { 914 /* no change */ 915 ldns_buffer_write(buf, k->rk.dname, k->rk.dname_len); 916 query_dname_tolower(*can_owner); 917 *can_owner_len = k->rk.dname_len; 918 return; 919 } 920 log_assert(rrsig_labels < fqdn_labels); 921 /* *. | fqdn(rightmost rrsig_labels) */ 922 if(rrsig_labels < fqdn_labels) { 923 int i; 924 uint8_t* nm = k->rk.dname; 925 size_t len = k->rk.dname_len; 926 /* so skip fqdn_labels-rrsig_labels */ 927 for(i=0; i<fqdn_labels-rrsig_labels; i++) { 928 dname_remove_label(&nm, &len); 929 } 930 *can_owner_len = len+2; 931 ldns_buffer_write(buf, (uint8_t*)"\001*", 2); 932 ldns_buffer_write(buf, nm, len); 933 query_dname_tolower(*can_owner); 934 } 935 } 936 937 /** 938 * Canonicalize Rdata in buffer. 939 * @param buf: buffer at position just after the rdata. 940 * @param rrset: rrset with type. 941 * @param len: length of the rdata (including rdatalen uint16). 942 */ 943 static void 944 canonicalize_rdata(ldns_buffer* buf, struct ub_packed_rrset_key* rrset, 945 size_t len) 946 { 947 uint8_t* datstart = ldns_buffer_current(buf)-len+2; 948 switch(ntohs(rrset->rk.type)) { 949 case LDNS_RR_TYPE_NXT: 950 case LDNS_RR_TYPE_NS: 951 case LDNS_RR_TYPE_MD: 952 case LDNS_RR_TYPE_MF: 953 case LDNS_RR_TYPE_CNAME: 954 case LDNS_RR_TYPE_MB: 955 case LDNS_RR_TYPE_MG: 956 case LDNS_RR_TYPE_MR: 957 case LDNS_RR_TYPE_PTR: 958 case LDNS_RR_TYPE_DNAME: 959 /* type only has a single argument, the name */ 960 query_dname_tolower(datstart); 961 return; 962 case LDNS_RR_TYPE_MINFO: 963 case LDNS_RR_TYPE_RP: 964 case LDNS_RR_TYPE_SOA: 965 /* two names after another */ 966 query_dname_tolower(datstart); 967 query_dname_tolower(datstart + 968 dname_valid(datstart, len-2)); 969 return; 970 case LDNS_RR_TYPE_RT: 971 case LDNS_RR_TYPE_AFSDB: 972 case LDNS_RR_TYPE_KX: 973 case LDNS_RR_TYPE_MX: 974 /* skip fixed part */ 975 if(len < 2+2+1) /* rdlen, skiplen, 1byteroot */ 976 return; 977 datstart += 2; 978 query_dname_tolower(datstart); 979 return; 980 case LDNS_RR_TYPE_SIG: 981 /* downcase the RRSIG, compat with BIND (kept it from SIG) */ 982 case LDNS_RR_TYPE_RRSIG: 983 /* skip fixed part */ 984 if(len < 2+18+1) 985 return; 986 datstart += 18; 987 query_dname_tolower(datstart); 988 return; 989 case LDNS_RR_TYPE_PX: 990 /* skip, then two names after another */ 991 if(len < 2+2+1) 992 return; 993 datstart += 2; 994 query_dname_tolower(datstart); 995 query_dname_tolower(datstart + 996 dname_valid(datstart, len-2-2)); 997 return; 998 case LDNS_RR_TYPE_NAPTR: 999 if(len < 2+4) 1000 return; 1001 len -= 2+4; 1002 datstart += 4; 1003 if(len < (size_t)datstart[0]+1) /* skip text field */ 1004 return; 1005 len -= (size_t)datstart[0]+1; 1006 datstart += (size_t)datstart[0]+1; 1007 if(len < (size_t)datstart[0]+1) /* skip text field */ 1008 return; 1009 len -= (size_t)datstart[0]+1; 1010 datstart += (size_t)datstart[0]+1; 1011 if(len < (size_t)datstart[0]+1) /* skip text field */ 1012 return; 1013 len -= (size_t)datstart[0]+1; 1014 datstart += (size_t)datstart[0]+1; 1015 if(len < 1) /* check name is at least 1 byte*/ 1016 return; 1017 query_dname_tolower(datstart); 1018 return; 1019 case LDNS_RR_TYPE_SRV: 1020 /* skip fixed part */ 1021 if(len < 2+6+1) 1022 return; 1023 datstart += 6; 1024 query_dname_tolower(datstart); 1025 return; 1026 1027 /* do not canonicalize NSEC rdata name, compat with 1028 * from bind 9.4 signer, where it does not do so */ 1029 case LDNS_RR_TYPE_NSEC: /* type starts with the name */ 1030 case LDNS_RR_TYPE_HINFO: /* not downcased */ 1031 /* A6 not supported */ 1032 default: 1033 /* nothing to do for unknown types */ 1034 return; 1035 } 1036 } 1037 1038 /** 1039 * Create canonical form of rrset in the scratch buffer. 1040 * @param region: temporary region. 1041 * @param buf: the buffer to use. 1042 * @param k: the rrset to insert. 1043 * @param sig: RRSIG rdata to include. 1044 * @param siglen: RRSIG rdata len excluding signature field, but inclusive 1045 * signer name length. 1046 * @param sortree: if NULL is passed a new sorted rrset tree is built. 1047 * Otherwise it is reused. 1048 * @return false on alloc error. 1049 */ 1050 static int 1051 rrset_canonical(struct regional* region, ldns_buffer* buf, 1052 struct ub_packed_rrset_key* k, uint8_t* sig, size_t siglen, 1053 struct rbtree_t** sortree) 1054 { 1055 struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data; 1056 uint8_t* can_owner = NULL; 1057 size_t can_owner_len = 0; 1058 struct canon_rr* walk; 1059 struct canon_rr* rrs; 1060 1061 if(!*sortree) { 1062 *sortree = (struct rbtree_t*)regional_alloc(region, 1063 sizeof(rbtree_t)); 1064 if(!*sortree) 1065 return 0; 1066 rrs = regional_alloc(region, sizeof(struct canon_rr)*d->count); 1067 if(!rrs) { 1068 *sortree = NULL; 1069 return 0; 1070 } 1071 rbtree_init(*sortree, &canonical_tree_compare); 1072 canonical_sort(k, d, *sortree, rrs); 1073 } 1074 1075 ldns_buffer_clear(buf); 1076 ldns_buffer_write(buf, sig, siglen); 1077 /* canonicalize signer name */ 1078 query_dname_tolower(ldns_buffer_begin(buf)+18); 1079 RBTREE_FOR(walk, struct canon_rr*, (*sortree)) { 1080 /* see if there is enough space left in the buffer */ 1081 if(ldns_buffer_remaining(buf) < can_owner_len + 2 + 2 + 4 1082 + d->rr_len[walk->rr_idx]) { 1083 log_err("verify: failed to canonicalize, " 1084 "rrset too big"); 1085 return 0; 1086 } 1087 /* determine canonical owner name */ 1088 if(can_owner) 1089 ldns_buffer_write(buf, can_owner, can_owner_len); 1090 else insert_can_owner(buf, k, sig, &can_owner, 1091 &can_owner_len); 1092 ldns_buffer_write(buf, &k->rk.type, 2); 1093 ldns_buffer_write(buf, &k->rk.rrset_class, 2); 1094 ldns_buffer_write(buf, sig+4, 4); 1095 ldns_buffer_write(buf, d->rr_data[walk->rr_idx], 1096 d->rr_len[walk->rr_idx]); 1097 canonicalize_rdata(buf, k, d->rr_len[walk->rr_idx]); 1098 } 1099 ldns_buffer_flip(buf); 1100 return 1; 1101 } 1102 1103 /** pretty print rrsig error with dates */ 1104 static void 1105 sigdate_error(const char* str, int32_t expi, int32_t incep, int32_t now) 1106 { 1107 struct tm tm; 1108 char expi_buf[16]; 1109 char incep_buf[16]; 1110 char now_buf[16]; 1111 time_t te, ti, tn; 1112 1113 if(verbosity < VERB_QUERY) 1114 return; 1115 te = (time_t)expi; 1116 ti = (time_t)incep; 1117 tn = (time_t)now; 1118 memset(&tm, 0, sizeof(tm)); 1119 if(gmtime_r(&te, &tm) && strftime(expi_buf, 15, "%Y%m%d%H%M%S", &tm) 1120 &&gmtime_r(&ti, &tm) && strftime(incep_buf, 15, "%Y%m%d%H%M%S", &tm) 1121 &&gmtime_r(&tn, &tm) && strftime(now_buf, 15, "%Y%m%d%H%M%S", &tm)) { 1122 log_info("%s expi=%s incep=%s now=%s", str, expi_buf, 1123 incep_buf, now_buf); 1124 } else 1125 log_info("%s expi=%u incep=%u now=%u", str, (unsigned)expi, 1126 (unsigned)incep, (unsigned)now); 1127 } 1128 1129 /** check rrsig dates */ 1130 static int 1131 check_dates(struct val_env* ve, uint32_t unow, 1132 uint8_t* expi_p, uint8_t* incep_p, char** reason) 1133 { 1134 /* read out the dates */ 1135 int32_t expi, incep, now; 1136 memmove(&expi, expi_p, sizeof(expi)); 1137 memmove(&incep, incep_p, sizeof(incep)); 1138 expi = ntohl(expi); 1139 incep = ntohl(incep); 1140 1141 /* get current date */ 1142 if(ve->date_override) { 1143 if(ve->date_override == -1) { 1144 verbose(VERB_ALGO, "date override: ignore date"); 1145 return 1; 1146 } 1147 now = ve->date_override; 1148 verbose(VERB_ALGO, "date override option %d", (int)now); 1149 } else now = (int32_t)unow; 1150 1151 /* check them */ 1152 if(incep - expi > 0) { 1153 sigdate_error("verify: inception after expiration, " 1154 "signature bad", expi, incep, now); 1155 *reason = "signature inception after expiration"; 1156 return 0; 1157 } 1158 if(incep - now > 0) { 1159 /* within skew ? (calc here to avoid calculation normally) */ 1160 int32_t skew = (expi-incep)/10; 1161 if(skew < ve->skew_min) skew = ve->skew_min; 1162 if(skew > ve->skew_max) skew = ve->skew_max; 1163 if(incep - now > skew) { 1164 sigdate_error("verify: signature bad, current time is" 1165 " before inception date", expi, incep, now); 1166 *reason = "signature before inception date"; 1167 return 0; 1168 } 1169 sigdate_error("verify warning suspicious signature inception " 1170 " or bad local clock", expi, incep, now); 1171 } 1172 if(now - expi > 0) { 1173 int32_t skew = (expi-incep)/10; 1174 if(skew < ve->skew_min) skew = ve->skew_min; 1175 if(skew > ve->skew_max) skew = ve->skew_max; 1176 if(now - expi > skew) { 1177 sigdate_error("verify: signature expired", expi, 1178 incep, now); 1179 *reason = "signature expired"; 1180 return 0; 1181 } 1182 sigdate_error("verify warning suspicious signature expiration " 1183 " or bad local clock", expi, incep, now); 1184 } 1185 return 1; 1186 } 1187 1188 /** adjust rrset TTL for verified rrset, compare to original TTL and expi */ 1189 static void 1190 adjust_ttl(struct val_env* ve, uint32_t unow, 1191 struct ub_packed_rrset_key* rrset, uint8_t* orig_p, 1192 uint8_t* expi_p, uint8_t* incep_p) 1193 { 1194 struct packed_rrset_data* d = 1195 (struct packed_rrset_data*)rrset->entry.data; 1196 /* read out the dates */ 1197 int32_t origttl, expittl, expi, incep, now; 1198 memmove(&origttl, orig_p, sizeof(origttl)); 1199 memmove(&expi, expi_p, sizeof(expi)); 1200 memmove(&incep, incep_p, sizeof(incep)); 1201 expi = ntohl(expi); 1202 incep = ntohl(incep); 1203 origttl = ntohl(origttl); 1204 1205 /* get current date */ 1206 if(ve->date_override) { 1207 now = ve->date_override; 1208 } else now = (int32_t)unow; 1209 expittl = expi - now; 1210 1211 /* so now: 1212 * d->ttl: rrset ttl read from message or cache. May be reduced 1213 * origttl: original TTL from signature, authoritative TTL max. 1214 * expittl: TTL until the signature expires. 1215 * 1216 * Use the smallest of these. 1217 */ 1218 if(d->ttl > (uint32_t)origttl) { 1219 verbose(VERB_QUERY, "rrset TTL larger than original TTL," 1220 " adjusting TTL downwards"); 1221 d->ttl = origttl; 1222 } 1223 if(expittl > 0 && d->ttl > (uint32_t)expittl) { 1224 verbose(VERB_ALGO, "rrset TTL larger than sig expiration ttl," 1225 " adjusting TTL downwards"); 1226 d->ttl = expittl; 1227 } 1228 } 1229 1230 enum sec_status 1231 dnskey_verify_rrset_sig(struct regional* region, ldns_buffer* buf, 1232 struct val_env* ve, uint32_t now, 1233 struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, 1234 size_t dnskey_idx, size_t sig_idx, 1235 struct rbtree_t** sortree, int* buf_canon, char** reason) 1236 { 1237 enum sec_status sec; 1238 uint8_t* sig; /* RRSIG rdata */ 1239 size_t siglen; 1240 size_t rrnum = rrset_get_count(rrset); 1241 uint8_t* signer; /* rrsig signer name */ 1242 size_t signer_len; 1243 unsigned char* sigblock; /* signature rdata field */ 1244 unsigned int sigblock_len; 1245 uint16_t ktag; /* DNSKEY key tag */ 1246 unsigned char* key; /* public key rdata field */ 1247 unsigned int keylen; 1248 rrset_get_rdata(rrset, rrnum + sig_idx, &sig, &siglen); 1249 /* min length of rdatalen, fixed rrsig, root signer, 1 byte sig */ 1250 if(siglen < 2+20) { 1251 verbose(VERB_QUERY, "verify: signature too short"); 1252 *reason = "signature too short"; 1253 return sec_status_bogus; 1254 } 1255 1256 if(!(dnskey_get_flags(dnskey, dnskey_idx) & DNSKEY_BIT_ZSK)) { 1257 verbose(VERB_QUERY, "verify: dnskey without ZSK flag"); 1258 *reason = "dnskey without ZSK flag"; 1259 return sec_status_bogus; 1260 } 1261 1262 if(dnskey_get_protocol(dnskey, dnskey_idx) != LDNS_DNSSEC_KEYPROTO) { 1263 /* RFC 4034 says DNSKEY PROTOCOL MUST be 3 */ 1264 verbose(VERB_QUERY, "verify: dnskey has wrong key protocol"); 1265 *reason = "dnskey has wrong protocolnumber"; 1266 return sec_status_bogus; 1267 } 1268 1269 /* verify as many fields in rrsig as possible */ 1270 signer = sig+2+18; 1271 signer_len = dname_valid(signer, siglen-2-18); 1272 if(!signer_len) { 1273 verbose(VERB_QUERY, "verify: malformed signer name"); 1274 *reason = "signer name malformed"; 1275 return sec_status_bogus; /* signer name invalid */ 1276 } 1277 if(!dname_subdomain_c(rrset->rk.dname, signer)) { 1278 verbose(VERB_QUERY, "verify: signer name is off-tree"); 1279 *reason = "signer name off-tree"; 1280 return sec_status_bogus; /* signer name offtree */ 1281 } 1282 sigblock = (unsigned char*)signer+signer_len; 1283 if(siglen < 2+18+signer_len+1) { 1284 verbose(VERB_QUERY, "verify: too short, no signature data"); 1285 *reason = "signature too short, no signature data"; 1286 return sec_status_bogus; /* sig rdf is < 1 byte */ 1287 } 1288 sigblock_len = (unsigned int)(siglen - 2 - 18 - signer_len); 1289 1290 /* verify key dname == sig signer name */ 1291 if(query_dname_compare(signer, dnskey->rk.dname) != 0) { 1292 verbose(VERB_QUERY, "verify: wrong key for rrsig"); 1293 log_nametypeclass(VERB_QUERY, "RRSIG signername is", 1294 signer, 0, 0); 1295 log_nametypeclass(VERB_QUERY, "the key name is", 1296 dnskey->rk.dname, 0, 0); 1297 *reason = "signer name mismatches key name"; 1298 return sec_status_bogus; 1299 } 1300 1301 /* verify covered type */ 1302 /* memcmp works because type is in network format for rrset */ 1303 if(memcmp(sig+2, &rrset->rk.type, 2) != 0) { 1304 verbose(VERB_QUERY, "verify: wrong type covered"); 1305 *reason = "signature covers wrong type"; 1306 return sec_status_bogus; 1307 } 1308 /* verify keytag and sig algo (possibly again) */ 1309 if((int)sig[2+2] != dnskey_get_algo(dnskey, dnskey_idx)) { 1310 verbose(VERB_QUERY, "verify: wrong algorithm"); 1311 *reason = "signature has wrong algorithm"; 1312 return sec_status_bogus; 1313 } 1314 ktag = htons(dnskey_calc_keytag(dnskey, dnskey_idx)); 1315 if(memcmp(sig+2+16, &ktag, 2) != 0) { 1316 verbose(VERB_QUERY, "verify: wrong keytag"); 1317 *reason = "signature has wrong keytag"; 1318 return sec_status_bogus; 1319 } 1320 1321 /* verify labels is in a valid range */ 1322 if((int)sig[2+3] > dname_signame_label_count(rrset->rk.dname)) { 1323 verbose(VERB_QUERY, "verify: labelcount out of range"); 1324 *reason = "signature labelcount out of range"; 1325 return sec_status_bogus; 1326 } 1327 1328 /* original ttl, always ok */ 1329 1330 if(!*buf_canon) { 1331 /* create rrset canonical format in buffer, ready for 1332 * signature */ 1333 if(!rrset_canonical(region, buf, rrset, sig+2, 1334 18 + signer_len, sortree)) { 1335 log_err("verify: failed due to alloc error"); 1336 return sec_status_unchecked; 1337 } 1338 *buf_canon = 1; 1339 } 1340 1341 /* check that dnskey is available */ 1342 dnskey_get_pubkey(dnskey, dnskey_idx, &key, &keylen); 1343 if(!key) { 1344 verbose(VERB_QUERY, "verify: short DNSKEY RR"); 1345 return sec_status_unchecked; 1346 } 1347 1348 /* verify */ 1349 sec = verify_canonrrset(buf, (int)sig[2+2], 1350 sigblock, sigblock_len, key, keylen, reason); 1351 1352 if(sec == sec_status_secure) { 1353 /* check if TTL is too high - reduce if so */ 1354 adjust_ttl(ve, now, rrset, sig+2+4, sig+2+8, sig+2+12); 1355 1356 /* verify inception, expiration dates 1357 * Do this last so that if you ignore expired-sigs the 1358 * rest is sure to be OK. */ 1359 if(!check_dates(ve, now, sig+2+8, sig+2+12, reason)) { 1360 return sec_status_bogus; 1361 } 1362 } 1363 1364 return sec; 1365 } 1366