1 /** dnssec_verify */ 2 3 #ifndef LDNS_DNSSEC_VERIFY_H 4 #define LDNS_DNSSEC_VERIFY_H 5 6 #define LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS 10 7 8 #include <ldns/dnssec.h> 9 10 #ifdef __cplusplus 11 extern "C" { 12 #endif 13 14 /** 15 * Chain structure that contains all DNSSEC data needed to 16 * verify an rrset 17 */ 18 typedef struct ldns_dnssec_data_chain_struct ldns_dnssec_data_chain; 19 struct ldns_dnssec_data_chain_struct 20 { 21 ldns_rr_list *rrset; 22 ldns_rr_list *signatures; 23 ldns_rr_type parent_type; 24 ldns_dnssec_data_chain *parent; 25 ldns_pkt_rcode packet_rcode; 26 ldns_rr_type packet_qtype; 27 bool packet_nodata; 28 }; 29 30 /** 31 * Creates a new dnssec_chain structure 32 * \return ldns_dnssec_data_chain * 33 */ 34 ldns_dnssec_data_chain *ldns_dnssec_data_chain_new(); 35 36 /** 37 * Frees a dnssec_data_chain structure 38 * 39 * \param[in] *chain The chain to free 40 */ 41 void ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain); 42 43 /** 44 * Frees a dnssec_data_chain structure, and all data 45 * contained therein 46 * 47 * \param[in] *chain The dnssec_data_chain to free 48 */ 49 void ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain); 50 51 /** 52 * Prints the dnssec_data_chain to the given file stream 53 * 54 * \param[in] *out The file stream to print to 55 * \param[in] *chain The dnssec_data_chain to print 56 */ 57 void ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain); 58 59 /** 60 * Build an ldns_dnssec_data_chain, which contains all 61 * DNSSEC data that is needed to derive the trust tree later 62 * 63 * The data_set will be cloned 64 * 65 * \param[in] *res resolver structure for further needed queries 66 * \param[in] qflags resolution flags 67 * \param[in] *data_set The original rrset where the chain ends 68 * \param[in] *pkt optional, can contain the original packet 69 * (and hence the sigs and maybe the key) 70 * \param[in] *orig_rr The original Resource Record 71 * 72 * \return the DNSSEC data chain 73 */ 74 ldns_dnssec_data_chain *ldns_dnssec_build_data_chain(ldns_resolver *res, 75 const uint16_t qflags, 76 const ldns_rr_list *data_set, 77 const ldns_pkt *pkt, 78 ldns_rr *orig_rr); 79 80 /** 81 * Tree structure that contains the relation of DNSSEC data, 82 * and their cryptographic status. 83 * 84 * This tree is derived from a data_chain, and can be used 85 * to look whether there is a connection between an RRSET 86 * and a trusted key. The tree only contains pointers to the 87 * data_chain, and therefore one should *never* free() the 88 * data_chain when there is still a trust tree derived from 89 * that chain. 90 * 91 * Example tree: 92 * key key key 93 * \ | / 94 * \ | / 95 * \ | / 96 * ds 97 * | 98 * key 99 * | 100 * key 101 * | 102 * rr 103 * 104 * For each signature there is a parent; if the parent 105 * pointer is null, it couldn't be found and there was no 106 * denial; otherwise is a tree which contains either a 107 * DNSKEY, a DS, or a NSEC rr 108 */ 109 typedef struct ldns_dnssec_trust_tree_struct ldns_dnssec_trust_tree; 110 struct ldns_dnssec_trust_tree_struct 111 { 112 ldns_rr *rr; 113 /* the complete rrset this rr was in */ 114 ldns_rr_list *rrset; 115 ldns_dnssec_trust_tree *parents[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS]; 116 ldns_status parent_status[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS]; 117 /** for debugging, add signatures too (you might want 118 those if they contain errors) */ 119 ldns_rr *parent_signature[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS]; 120 size_t parent_count; 121 }; 122 123 /** 124 * Creates a new (empty) dnssec_trust_tree structure 125 * 126 * \return ldns_dnssec_trust_tree * 127 */ 128 ldns_dnssec_trust_tree *ldns_dnssec_trust_tree_new(); 129 130 /** 131 * Frees the dnssec_trust_tree recursively 132 * 133 * There is no deep free; all data in the trust tree 134 * consists of pointers to a data_chain 135 * 136 * \param[in] tree The tree to free 137 */ 138 void ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree); 139 140 /** 141 * returns the depth of the trust tree 142 * 143 * \param[in] tree tree to calculate the depth of 144 * \return The depth of the tree 145 */ 146 size_t ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree); 147 148 /** 149 * Prints the dnssec_trust_tree structure to the given file 150 * stream. 151 * 152 * If a link status is not LDNS_STATUS_OK; the status and 153 * relevant signatures are printed too 154 * 155 * \param[in] *out The file stream to print to 156 * \param[in] tree The trust tree to print 157 * \param[in] tabs Prepend each line with tabs*2 spaces 158 * \param[in] extended If true, add little explanation lines to the output 159 */ 160 void ldns_dnssec_trust_tree_print(FILE *out, 161 ldns_dnssec_trust_tree *tree, 162 size_t tabs, 163 bool extended); 164 165 /** 166 * Adds a trust tree as a parent for the given trust tree 167 * 168 * \param[in] *tree The tree to add the parent to 169 * \param[in] *parent The parent tree to add 170 * \param[in] *parent_signature The RRSIG relevant to this parent/child 171 * connection 172 * \param[in] parent_status The DNSSEC status for this parent, child and RRSIG 173 * \return LDNS_STATUS_OK if the addition succeeds, error otherwise 174 */ 175 ldns_status ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree, 176 const ldns_dnssec_trust_tree *parent, 177 const ldns_rr *parent_signature, 178 const ldns_status parent_status); 179 180 /** 181 * Generates a dnssec_trust_ttree for the given rr from the 182 * given data_chain 183 * 184 * This does not clone the actual data; Don't free the 185 * data_chain before you are done with this tree 186 * 187 * \param[in] *data_chain The chain to derive the trust tree from 188 * \param[in] *rr The RR this tree will be about 189 * \return ldns_dnssec_trust_tree * 190 */ 191 ldns_dnssec_trust_tree *ldns_dnssec_derive_trust_tree( 192 ldns_dnssec_data_chain *data_chain, 193 ldns_rr *rr); 194 195 /** 196 * Sub function for derive_trust_tree that is used for a 197 * 'normal' rrset 198 * 199 * \param[in] new_tree The trust tree that we are building 200 * \param[in] data_chain The data chain containing the data for the trust tree 201 * \param[in] cur_sig_rr The currently relevant signature 202 */ 203 void ldns_dnssec_derive_trust_tree_normal_rrset( 204 ldns_dnssec_trust_tree *new_tree, 205 ldns_dnssec_data_chain *data_chain, 206 ldns_rr *cur_sig_rr); 207 208 /** 209 * Sub function for derive_trust_tree that is used for DNSKEY rrsets 210 * 211 * \param[in] new_tree The trust tree that we are building 212 * \param[in] data_chain The data chain containing the data for the trust tree 213 * \param[in] cur_rr The currently relevant DNSKEY RR 214 * \param[in] cur_sig_rr The currently relevant signature 215 */ 216 void ldns_dnssec_derive_trust_tree_dnskey_rrset( 217 ldns_dnssec_trust_tree *new_tree, 218 ldns_dnssec_data_chain *data_chain, 219 ldns_rr *cur_rr, 220 ldns_rr *cur_sig_rr); 221 222 /** 223 * Sub function for derive_trust_tree that is used for DS rrsets 224 * 225 * \param[in] new_tree The trust tree that we are building 226 * \param[in] data_chain The data chain containing the data for the trust tree 227 * \param[in] cur_rr The currently relevant DS RR 228 */ 229 void ldns_dnssec_derive_trust_tree_ds_rrset( 230 ldns_dnssec_trust_tree *new_tree, 231 ldns_dnssec_data_chain *data_chain, 232 ldns_rr *cur_rr); 233 234 /** 235 * Sub function for derive_trust_tree that is used when there are no 236 * signatures 237 * 238 * \param[in] new_tree The trust tree that we are building 239 * \param[in] data_chain The data chain containing the data for the trust tree 240 */ 241 void ldns_dnssec_derive_trust_tree_no_sig( 242 ldns_dnssec_trust_tree *new_tree, 243 ldns_dnssec_data_chain *data_chain); 244 245 /** 246 * Returns OK if there is a trusted path in the tree to one of 247 * the DNSKEY or DS RRs in the given list 248 * 249 * \param *tree The trust tree so search 250 * \param *keys A ldns_rr_list of DNSKEY and DS rrs to look for 251 * \return LDNS_STATUS_OK if there is a trusted path to one of 252 * the keys, or the *first* error encountered 253 * if there were no paths 254 */ 255 ldns_status ldns_dnssec_trust_tree_contains_keys( 256 ldns_dnssec_trust_tree *tree, 257 ldns_rr_list *keys); 258 259 /** 260 * Verifies a list of signatures for one rrset. 261 * 262 * \param[in] rrset the rrset to verify 263 * \param[in] rrsig a list of signatures to check 264 * \param[in] keys a list of keys to check with 265 * \param[out] good_keys if this is a (initialized) list, the pointer to keys 266 * from keys that validate one of the signatures 267 * are added to it 268 * \return status LDNS_STATUS_OK if there is at least one correct key 269 */ 270 ldns_status ldns_verify(ldns_rr_list *rrset, 271 ldns_rr_list *rrsig, 272 const ldns_rr_list *keys, 273 ldns_rr_list *good_keys); 274 275 /** 276 * Verifies a list of signatures for one rrset, but disregard the time. 277 * Inception and Expiration are not checked. 278 * 279 * \param[in] rrset the rrset to verify 280 * \param[in] rrsig a list of signatures to check 281 * \param[in] keys a list of keys to check with 282 * \param[out] good_keys if this is a (initialized) list, the pointer to keys 283 * from keys that validate one of the signatures 284 * are added to it 285 * \return status LDNS_STATUS_OK if there is at least one correct key 286 */ 287 ldns_status ldns_verify_notime(ldns_rr_list *rrset, 288 ldns_rr_list *rrsig, 289 const ldns_rr_list *keys, 290 ldns_rr_list *good_keys); 291 292 /** 293 * Tries to build an authentication chain from the given 294 * keys down to the queried domain. 295 * 296 * If we find a valid trust path, return the valid keys for the domain. 297 * 298 * \param[in] res the current resolver 299 * \param[in] domain the domain we want valid keys for 300 * \param[in] keys the current set of trusted keys 301 * \param[out] status pointer to the status variable where the result 302 * code will be stored 303 * \return the set of trusted keys for the domain, or NULL if no 304 * trust path could be built. 305 */ 306 ldns_rr_list *ldns_fetch_valid_domain_keys(const ldns_resolver * res, 307 const ldns_rdf * domain, 308 const ldns_rr_list * keys, 309 ldns_status *status); 310 311 /** 312 * Validates the DNSKEY RRset for the given domain using the provided 313 * trusted keys. 314 * 315 * \param[in] res the current resolver 316 * \param[in] domain the domain we want valid keys for 317 * \param[in] keys the current set of trusted keys 318 * \return the set of trusted keys for the domain, or NULL if the RRSET 319 * could not be validated 320 */ 321 ldns_rr_list *ldns_validate_domain_dnskey (const ldns_resolver *res, 322 const ldns_rdf *domain, 323 const ldns_rr_list *keys); 324 325 /** 326 * Validates the DS RRset for the given domain using the provided trusted keys. 327 * 328 * \param[in] res the current resolver 329 * \param[in] domain the domain we want valid keys for 330 * \param[in] keys the current set of trusted keys 331 * \return the set of trusted keys for the domain, or NULL if the RRSET could not be validated 332 */ 333 ldns_rr_list *ldns_validate_domain_ds(const ldns_resolver *res, 334 const ldns_rdf * 335 domain, 336 const ldns_rr_list * keys); 337 338 /** 339 * Verifies a list of signatures for one RRset using a valid trust path. 340 * 341 * \param[in] res the current resolver 342 * \param[in] rrset the rrset to verify 343 * \param[in] rrsigs a list of signatures to check 344 * \param[out] validating_keys if this is a (initialized) list, the 345 * keys from keys that validate one of 346 * the signatures are added to it 347 * \return status LDNS_STATUS_OK if there is at least one correct key 348 */ 349 ldns_status ldns_verify_trusted(ldns_resolver *res, 350 ldns_rr_list *rrset, 351 ldns_rr_list *rrsigs, 352 ldns_rr_list *validating_keys); 353 354 /** 355 * denial is not just a river in egypt 356 * 357 * \param[in] rr The (query) RR to check the denial of existence for 358 * \param[in] nsecs The list of NSEC RRs that are supposed to deny the 359 * existence of the RR 360 * \param[in] rrsigs The RRSIG RR covering the NSEC RRs 361 * \return LDNS_STATUS_OK if the NSEC RRs deny the existence, error code 362 * containing the reason they do not otherwise 363 */ 364 ldns_status ldns_dnssec_verify_denial(ldns_rr *rr, 365 ldns_rr_list *nsecs, 366 ldns_rr_list *rrsigs); 367 368 /** 369 * Denial of existence using NSEC3 records 370 * Since NSEC3 is a bit more complicated than normal denial, some 371 * context arguments are needed 372 * 373 * \param[in] rr The (query) RR to check the denial of existence for 374 * \param[in] nsecs The list of NSEC3 RRs that are supposed to deny the 375 * existence of the RR 376 * \param[in] rrsigs The RRSIG rr covering the NSEC RRs 377 * \param[in] packet_rcode The RCODE value of the packet that provided the 378 * NSEC3 RRs 379 * \param[in] packet_qtype The original query RR type 380 * \param[in] packet_nodata True if the providing packet had an empty ANSWER 381 * section 382 * \return LDNS_STATUS_OK if the NSEC3 RRs deny the existence, error code 383 * containing the reason they do not otherwise 384 */ 385 ldns_status ldns_dnssec_verify_denial_nsec3(ldns_rr *rr, 386 ldns_rr_list *nsecs, 387 ldns_rr_list *rrsigs, 388 ldns_pkt_rcode packet_rcode, 389 ldns_rr_type packet_qtype, 390 bool packet_nodata); 391 392 /** 393 * Verifies the already processed data in the buffers 394 * This function should probably not be used directly. 395 * 396 * \param[in] rawsig_buf Buffer containing signature data to use 397 * \param[in] verify_buf Buffer containing data to verify 398 * \param[in] key_buf Buffer containing key data to use 399 * \param[in] algo Signing algorithm 400 * \return status LDNS_STATUS_OK if the data verifies. Error if not. 401 */ 402 ldns_status ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, 403 ldns_buffer *verify_buf, 404 ldns_buffer *key_buf, 405 uint8_t algo); 406 407 /** 408 * Like ldns_verify_rrsig_buffers, but uses raw data. 409 * 410 * \param[in] sig signature data to use 411 * \param[in] siglen length of signature data to use 412 * \param[in] verify_buf Buffer containing data to verify 413 * \param[in] key key data to use 414 * \param[in] keylen length of key data to use 415 * \param[in] algo Signing algorithm 416 * \return status LDNS_STATUS_OK if the data verifies. Error if not. 417 */ 418 ldns_status ldns_verify_rrsig_buffers_raw(unsigned char* sig, 419 size_t siglen, 420 ldns_buffer *verify_buf, 421 unsigned char* key, 422 size_t keylen, 423 uint8_t algo); 424 425 /** 426 * Verifies an rrsig. All keys in the keyset are tried. 427 * \param[in] rrset the rrset to check 428 * \param[in] rrsig the signature of the rrset 429 * \param[in] keys the keys to try 430 * \param[out] good_keys if this is a (initialized) list, the pointer to keys 431 * from keys that validate one of the signatures 432 * are added to it 433 * \return a list of keys which validate the rrsig + rrset. Returns 434 * status LDNS_STATUS_OK if at least one key matched. Else an error. 435 */ 436 ldns_status ldns_verify_rrsig_keylist(ldns_rr_list *rrset, 437 ldns_rr *rrsig, 438 const ldns_rr_list *keys, 439 ldns_rr_list *good_keys); 440 441 /** 442 * Verifies an rrsig. All keys in the keyset are tried. Time is not checked. 443 * \param[in] rrset the rrset to check 444 * \param[in] rrsig the signature of the rrset 445 * \param[in] keys the keys to try 446 * \param[out] good_keys if this is a (initialized) list, the pointer to keys 447 * from keys that validate one of the signatures 448 * are added to it 449 * \return a list of keys which validate the rrsig + rrset. Returns 450 * status LDNS_STATUS_OK if at least one key matched. Else an error. 451 */ 452 ldns_status ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset, 453 ldns_rr *rrsig, 454 const ldns_rr_list *keys, 455 ldns_rr_list *good_keys); 456 457 /** 458 * verify an rrsig with 1 key 459 * \param[in] rrset the rrset 460 * \param[in] rrsig the rrsig to verify 461 * \param[in] key the key to use 462 * \return status message wether verification succeeded. 463 */ 464 ldns_status ldns_verify_rrsig(ldns_rr_list *rrset, 465 ldns_rr *rrsig, 466 ldns_rr *key); 467 468 /** 469 * verifies a buffer with signature data for a buffer with rrset data 470 * with an EVP_PKEY 471 * 472 * \param[in] sig the signature data 473 * \param[in] rrset the rrset data, sorted and processed for verification 474 * \param[in] key the EVP key structure 475 * \param[in] digest_type The digest type of the signature 476 */ 477 #ifdef HAVE_SSL 478 ldns_status ldns_verify_rrsig_evp(ldns_buffer *sig, 479 ldns_buffer *rrset, 480 EVP_PKEY *key, 481 const EVP_MD *digest_type); 482 #endif 483 484 /** 485 * Like ldns_verify_rrsig_evp, but uses raw signature data. 486 * \param[in] sig the signature data, wireformat uncompressed 487 * \param[in] siglen length of the signature data 488 * \param[in] rrset the rrset data, sorted and processed for verification 489 * \param[in] key the EVP key structure 490 * \param[in] digest_type The digest type of the signature 491 */ 492 #ifdef HAVE_SSL 493 ldns_status ldns_verify_rrsig_evp_raw(unsigned char *sig, 494 size_t siglen, 495 ldns_buffer *rrset, 496 EVP_PKEY *key, 497 const EVP_MD *digest_type); 498 #endif 499 500 /** 501 * verifies a buffer with signature data (DSA) for a buffer with rrset data 502 * with a buffer with key data. 503 * 504 * \param[in] sig the signature data 505 * \param[in] rrset the rrset data, sorted and processed for verification 506 * \param[in] key the key data 507 */ 508 ldns_status ldns_verify_rrsig_dsa(ldns_buffer *sig, 509 ldns_buffer *rrset, 510 ldns_buffer *key); 511 512 /** 513 * verifies a buffer with signature data (RSASHA1) for a buffer with rrset data 514 * with a buffer with key data. 515 * 516 * \param[in] sig the signature data 517 * \param[in] rrset the rrset data, sorted and processed for verification 518 * \param[in] key the key data 519 */ 520 ldns_status ldns_verify_rrsig_rsasha1(ldns_buffer *sig, 521 ldns_buffer *rrset, 522 ldns_buffer *key); 523 524 /** 525 * verifies a buffer with signature data (RSAMD5) for a buffer with rrset data 526 * with a buffer with key data. 527 * 528 * \param[in] sig the signature data 529 * \param[in] rrset the rrset data, sorted and processed for verification 530 * \param[in] key the key data 531 */ 532 ldns_status ldns_verify_rrsig_rsamd5(ldns_buffer *sig, 533 ldns_buffer *rrset, 534 ldns_buffer *key); 535 536 /** 537 * Like ldns_verify_rrsig_dsa, but uses raw signature and key data. 538 * \param[in] sig raw uncompressed wireformat signature data 539 * \param[in] siglen length of signature data 540 * \param[in] rrset ldns buffer with prepared rrset data. 541 * \param[in] key raw uncompressed wireformat key data 542 * \param[in] keylen length of key data 543 */ 544 ldns_status ldns_verify_rrsig_dsa_raw(unsigned char* sig, 545 size_t siglen, 546 ldns_buffer* rrset, 547 unsigned char* key, 548 size_t keylen); 549 550 /** 551 * Like ldns_verify_rrsig_rsasha1, but uses raw signature and key data. 552 * \param[in] sig raw uncompressed wireformat signature data 553 * \param[in] siglen length of signature data 554 * \param[in] rrset ldns buffer with prepared rrset data. 555 * \param[in] key raw uncompressed wireformat key data 556 * \param[in] keylen length of key data 557 */ 558 ldns_status ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, 559 size_t siglen, 560 ldns_buffer* rrset, 561 unsigned char* key, 562 size_t keylen); 563 564 /** 565 * Like ldns_verify_rrsig_rsasha256, but uses raw signature and key data. 566 * \param[in] sig raw uncompressed wireformat signature data 567 * \param[in] siglen length of signature data 568 * \param[in] rrset ldns buffer with prepared rrset data. 569 * \param[in] key raw uncompressed wireformat key data 570 * \param[in] keylen length of key data 571 */ 572 573 ldns_status ldns_verify_rrsig_rsasha256_raw(unsigned char* sig, 574 size_t siglen, 575 ldns_buffer* rrset, 576 unsigned char* key, 577 size_t keylen); 578 579 /** 580 * Like ldns_verify_rrsig_rsasha512, but uses raw signature and key data. 581 * \param[in] sig raw uncompressed wireformat signature data 582 * \param[in] siglen length of signature data 583 * \param[in] rrset ldns buffer with prepared rrset data. 584 * \param[in] key raw uncompressed wireformat key data 585 * \param[in] keylen length of key data 586 */ 587 ldns_status ldns_verify_rrsig_rsasha512_raw(unsigned char* sig, 588 size_t siglen, 589 ldns_buffer* rrset, 590 unsigned char* key, 591 size_t keylen); 592 593 /** 594 * Like ldns_verify_rrsig_rsamd5, but uses raw signature and key data. 595 * \param[in] sig raw uncompressed wireformat signature data 596 * \param[in] siglen length of signature data 597 * \param[in] rrset ldns buffer with prepared rrset data. 598 * \param[in] key raw uncompressed wireformat key data 599 * \param[in] keylen length of key data 600 */ 601 ldns_status ldns_verify_rrsig_rsamd5_raw(unsigned char* sig, 602 size_t siglen, 603 ldns_buffer* rrset, 604 unsigned char* key, 605 size_t keylen); 606 607 #ifdef __cplusplus 608 } 609 #endif 610 611 #endif 612 613