1 /* 2 * Copyright (c) 2021-2022 Apple Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //====================================================================================================================== 18 // MARK: - Headers 19 20 #include "dns_obj_log.h" 21 #include "rdata_parser.h" 22 #include "domain_name_labels.h" 23 #include "dns_common.h" 24 25 #include "dns_assert_macros.h" 26 #include "mdns_strict.h" 27 28 //====================================================================================================================== 29 // MARK: - Private Functions 30 31 static bool 32 type_bit_maps_check_length(const uint8_t * const type_bit_maps, const uint16_t type_bit_maps_len) 33 { 34 const uint8_t *ptr = type_bit_maps; 35 const uint8_t * const ptr_limit = ptr + type_bit_maps_len; 36 37 // Ensure each type bit map window is within the limit. 38 uint16_t window_block_size; 39 for (; ptr + 1 < ptr_limit; ptr += window_block_size) { 40 window_block_size = 1 + 1 + *(ptr + 1); 41 } 42 require_return_value(ptr == ptr_limit, false); 43 44 return true; 45 } 46 47 //====================================================================================================================== 48 // MARK: - CNAME Parser 49 50 typedef struct rdata_cname_s { 51 uint8_t canonical_name[0]; 52 } rdata_cname_t; 53 54 check_compile_time(offsetof(rdata_cname_t, canonical_name) == 0); 55 56 //====================================================================================================================== 57 58 const uint8_t * 59 rdata_parser_cname_get_canonical_name(const uint8_t * const rdata) 60 { 61 return ((const rdata_cname_t *)rdata)->canonical_name; 62 } 63 64 //====================================================================================================================== 65 66 bool 67 rdata_parser_cname_check_validity(const uint8_t * const rdata, const uint16_t rdata_len) 68 { 69 const size_t cname_length = domain_name_labels_length_with_limit(rdata, rdata + rdata_len); 70 return (cname_length != 0); 71 } 72 73 //====================================================================================================================== 74 // MARK: - SOA Parser 75 76 typedef struct rdata_soa_s { 77 // uint8_t primary_name_server[0]; // The domain name of the primary name server. 78 // uint8_t mailbox_name[0]; // The mail of the administrator in domain name format. 79 uint32_t serial; // The serial number of the original copy of the zone. 80 uint32_t refresh; // The time interval before the zone should refreshed. 81 uint32_t retry; // The time interval before the failed refresh should be retried. 82 uint32_t expire; // The time interval before the zone is no longer authoritative. 83 uint32_t minimum; // The minimum TTL should be used for any RR from this zone. 84 } rdata_soa_t; 85 86 check_compile_time(offsetof(rdata_soa_t, serial) == 0); 87 check_compile_time(offsetof(rdata_soa_t, refresh) == 4); 88 check_compile_time(offsetof(rdata_soa_t, retry) == 8); 89 check_compile_time(offsetof(rdata_soa_t, expire) == 12); 90 check_compile_time(offsetof(rdata_soa_t, minimum) == 16); 91 check_compile_time(sizeof(rdata_soa_t) == 20); 92 93 //====================================================================================================================== 94 95 uint32_t 96 rdata_parser_soa_get_minimum_ttl(const uint8_t * const rdata) 97 { 98 const uint8_t * const primary_name_server = rdata; 99 const size_t primary_name_server_len = domain_name_labels_length(primary_name_server); 100 101 const uint8_t * const mailbox_name = rdata + primary_name_server_len; 102 const size_t mailbox_name_len = domain_name_labels_length(mailbox_name); 103 104 const uint8_t * const minimum_ttl_bytes = rdata + primary_name_server_len + mailbox_name_len + offsetof(rdata_soa_t, minimum); 105 return get_uint32_from_bytes(minimum_ttl_bytes); 106 } 107 108 //====================================================================================================================== 109 110 bool 111 rdata_parser_soa_check_validity(const uint8_t * const rdata, const uint16_t rdata_len) 112 { 113 const uint8_t * const rdata_limit = rdata + rdata_len; 114 // Minimal size of the SOA rdata: <root domain name as the primary name server> + <root domain name as the mailbox> 115 // + <size of the remaining fixed length members> 116 const uint16_t min_rdata_len_soa = 1 + 1 + sizeof(rdata_soa_t); 117 require_return_value(rdata_len >= min_rdata_len_soa, false); 118 119 const uint8_t * const primary_name_server = rdata; 120 const size_t primary_name_server_len = domain_name_labels_length_with_limit(primary_name_server, rdata_limit); 121 // The shortest domain name is <root>. 122 require_return_value(primary_name_server_len >= 1, false); 123 require_return_value(primary_name_server_len + sizeof(rdata_soa_t) < rdata_len, false); 124 125 const uint8_t * const mailbox_name = rdata + primary_name_server_len; 126 const size_t mailbox_name_len = domain_name_labels_length_with_limit(mailbox_name, rdata_limit); 127 require_return_value(mailbox_name_len >= 1, false); 128 129 require_return_value(primary_name_server_len + mailbox_name_len + sizeof(rdata_soa_t) == rdata_len, false); 130 131 return true; 132 } 133 134 //====================================================================================================================== 135 // MARK: - SRV Parser 136 137 typedef struct rdata_srv_s { 138 uint16_t priority; 139 uint16_t weight; 140 uint16_t port; 141 uint8_t target[0]; 142 } rdata_srv_t; 143 144 check_compile_time(offsetof(rdata_srv_t, priority) == 0); 145 check_compile_time(offsetof(rdata_srv_t, weight) == 2); 146 check_compile_time(offsetof(rdata_srv_t, port) == 4); 147 check_compile_time(offsetof(rdata_srv_t, target) == 6); 148 check_compile_time(sizeof(rdata_srv_t) == 6); 149 150 //====================================================================================================================== 151 152 uint16_t 153 rdata_parser_srv_get_priority(const uint8_t * const rdata) 154 { 155 return get_uint16_from_bytes(rdata); 156 } 157 158 //====================================================================================================================== 159 160 uint16_t 161 rdata_parser_srv_get_weight(const uint8_t * const rdata) 162 { 163 return get_uint16_from_bytes(rdata + offsetof(rdata_srv_t, weight)); 164 } 165 166 //====================================================================================================================== 167 168 uint16_t 169 rdata_parser_srv_get_port(const uint8_t * const rdata) 170 { 171 return get_uint16_from_bytes(rdata + offsetof(rdata_srv_t, port)); 172 } 173 174 //====================================================================================================================== 175 176 const uint8_t * 177 rdata_parser_srv_get_target(const uint8_t * const rdata) 178 { 179 return rdata + offsetof(rdata_srv_t, target); 180 } 181 182 //====================================================================================================================== 183 184 bool 185 rdata_parser_srv_check_validity(const uint8_t * const UNUSED rdata, const uint16_t rdata_len) 186 { 187 return rdata_len > offsetof(rdata_srv_t, target); 188 } 189 190 //====================================================================================================================== 191 // MARK: - NSEC Parser 192 193 typedef struct rdata_nsec_s { 194 uint8_t next_domain_name[0]; // The next domain that exists in the zone. 195 // uint8_t type_bit_maps[0]; // The type bit map that indicates what DNS types are covered by the current NSEC record. 196 } rdata_nsec_t; 197 198 check_compile_time(offsetof(rdata_nsec_t, next_domain_name) == 0); 199 200 //====================================================================================================================== 201 202 const uint8_t * 203 rdata_parser_nsec_get_next_domain_name(const uint8_t * const rdata) 204 { 205 return rdata; 206 } 207 208 //====================================================================================================================== 209 210 const uint8_t * 211 rdata_parser_nsec_get_type_bit_maps(const uint8_t * const rdata, const uint16_t rdata_len, 212 uint16_t * const out_type_bit_maps_len) 213 { 214 const uint8_t * const next_domain_name = rdata_parser_nsec_get_next_domain_name(rdata); 215 const size_t next_domain_name_len = domain_name_labels_length(next_domain_name); 216 217 *out_type_bit_maps_len = rdata_len - (uint16_t)next_domain_name_len; 218 219 return rdata + next_domain_name_len; 220 } 221 222 //====================================================================================================================== 223 224 bool 225 rdata_parser_nsec_check_validity(const uint8_t * const rdata, const uint16_t rdata_len) 226 { 227 // One byte to encode window block number. 228 // One byte to encode bitmap length. 229 // One byte to encode bitmap. (which means bitmap length is 1) 230 const uint16_t min_type_bit_maps_len = 1 + 1 + 1; 231 //The minimal size: One root domain name label + the minimal type bit maps. 232 const uint16_t min_rdata_len_nsec = 1 + min_type_bit_maps_len; 233 require_return_value(rdata_len >= min_rdata_len_nsec, false); 234 235 const uint8_t * const next_domain_name = rdata_parser_nsec_get_next_domain_name(rdata); 236 const size_t next_domain_name_len = domain_name_labels_length_with_limit(next_domain_name, rdata + rdata_len); 237 // The shortest domain name is <root>. 238 require_return_value(next_domain_name_len >= 1, false); 239 // The type bit maps length has to be greater than 0. 240 require_return_value(next_domain_name_len < rdata_len, false); 241 242 // Check type bit maps format. 243 uint16_t type_bit_maps_len; 244 const uint8_t *type_bit_maps = rdata_parser_nsec_get_type_bit_maps(rdata, rdata_len, &type_bit_maps_len); 245 const bool type_bit_maps_is_valid = type_bit_maps_check_length(type_bit_maps, type_bit_maps_len); 246 require_return_value(type_bit_maps_is_valid, false); 247 248 return true; 249 } 250 251 //====================================================================================================================== 252 253 // For the detail of type bit maps and how the dns type is checked, go to: 254 // [RFC 4034 4.1.2. The Type Bit Maps Field](https://datatracker.ietf.org/doc/html/rfc4034#section-4.1.2) 255 bool 256 rdata_parser_type_bit_maps_cover_dns_type(const uint8_t * const type_bit_maps, const uint16_t type_bit_maps_len, 257 const uint16_t type) 258 { 259 bool covers; 260 const uint8_t window_block = type / 256; 261 const uint8_t offset_in_window_block = (uint8_t)(type % 256); 262 const uint8_t *ptr = type_bit_maps; 263 const uint8_t * const ptr_limit = ptr + type_bit_maps_len; 264 265 uint16_t window_block_size; 266 covers = false; 267 for (; ptr + 1 < ptr_limit; ptr += window_block_size) { 268 const uint8_t current_window_block = *ptr; 269 const uint8_t current_bitmap_length = *(ptr + 1); 270 const uint32_t current_bitmap_bit_count = current_bitmap_length * 8; 271 const uint8_t * const current_bitmap = ptr + 2; 272 const uint8_t mask_to_match = (uint8_t)(1 << (7 - (offset_in_window_block % 8))); 273 274 // One octet to encode window block number. 275 // One octet to encode bitmap length. 276 // and current_bitmap_length. 277 window_block_size = 1 + 1 + current_bitmap_length; 278 if (ptr + window_block_size > ptr_limit) { // Ensure that the entire window is within the range. 279 break; 280 } 281 282 if (current_window_block != window_block) { 283 continue; 284 } 285 286 if (offset_in_window_block >= current_bitmap_bit_count) { 287 continue; 288 } 289 290 if ((current_bitmap[offset_in_window_block / 8] & mask_to_match) != 0) { 291 covers = true; 292 } 293 } 294 295 return covers; 296 } 297 298 //====================================================================================================================== 299 // MARK: - DS Parser 300 301 typedef struct rdata_ds_s { 302 uint16_t key_tag; // The key tag of the corresponding DNSKEY that this DS record validates. 303 uint8_t algorithm; // The algorithm of the corresponding DNSKEY that this DS record validates. 304 uint8_t digest_type; // The digest type that the DS record uses to generate the DNSKEY digest. 305 uint8_t digest[0]; // The digest in bytes. 306 } rdata_ds_t; 307 308 check_compile_time(sizeof(rdata_ds_t) == 4); 309 check_compile_time(offsetof(rdata_ds_t, key_tag) == 0); 310 check_compile_time(offsetof(rdata_ds_t, algorithm) == 2); 311 check_compile_time(offsetof(rdata_ds_t, digest_type) == 3); 312 check_compile_time(offsetof(rdata_ds_t, digest) == 4); 313 314 //====================================================================================================================== 315 316 uint16_t 317 rdata_parser_ds_get_key_tag(const uint8_t * const rdata) 318 { 319 return get_uint16_from_bytes(rdata); 320 } 321 322 //====================================================================================================================== 323 324 uint8_t 325 rdata_parser_ds_get_algorithm(const uint8_t * const rdata) 326 { 327 return rdata[offsetof(rdata_ds_t, algorithm)]; 328 } 329 330 //====================================================================================================================== 331 332 uint8_t 333 rdata_parser_ds_get_digest_type(const uint8_t * const rdata) 334 { 335 return rdata[offsetof(rdata_ds_t, digest_type)]; 336 } 337 338 //====================================================================================================================== 339 340 const uint8_t * 341 rdata_parser_ds_get_digest(const uint8_t * const rdata) 342 { 343 return rdata + offsetof(rdata_ds_t, digest); 344 } 345 346 //====================================================================================================================== 347 348 uint16_t 349 rdata_parser_ds_get_digest_length(const uint16_t rdata_len) 350 { 351 require_return_value(rdata_len >= offsetof(rdata_ds_t, digest), 0); 352 return rdata_len - offsetof(rdata_ds_t, digest); 353 } 354 355 //====================================================================================================================== 356 357 bool 358 rdata_parser_ds_check_validity(const uint8_t * const UNUSED rdata, const uint16_t rdata_len) 359 { 360 return rdata_len > offsetof(rdata_ds_t, digest); 361 } 362 363 //====================================================================================================================== 364 // MARK: - RRSIG Parser 365 366 typedef struct rdata_rrsig_s { 367 uint16_t type_covered; // Indicates which DNS type RRSIG covers. 368 uint8_t algorithm; // The DNSKEY algorithm that is used to sign the data. 369 uint8_t labels; // The number of labels in the RRSIG owner name, is used to check wild matching. 370 uint32_t original_ttl; // The original TTL of the records that are covered by the RRSIG, it is used to 371 // reconstruct the signed data. 372 uint32_t signature_expiration; // The epoch time when the RRSIG expires. 373 uint32_t signature_inception; // The epoch time when the RRSIG should start to be valid to validate. 374 uint16_t key_tag; // The key tag that identifies which DNSKEY it uses to generate the current RRSIG. 375 uint8_t signer_name[0]; // The signer name. 376 // uint8_t signature[0]; // The signature data in bytes. 377 } rdata_rrsig_t; 378 379 check_compile_time(offsetof(rdata_rrsig_t, type_covered) == 0); 380 check_compile_time(offsetof(rdata_rrsig_t, algorithm) == 2); 381 check_compile_time(offsetof(rdata_rrsig_t, labels) == 3); 382 check_compile_time(offsetof(rdata_rrsig_t, original_ttl) == 4); 383 check_compile_time(offsetof(rdata_rrsig_t, signature_expiration) == 8); 384 check_compile_time(offsetof(rdata_rrsig_t, signature_inception) == 12); 385 check_compile_time(offsetof(rdata_rrsig_t, key_tag) == 16); 386 check_compile_time(offsetof(rdata_rrsig_t, signer_name) == 18); 387 388 //====================================================================================================================== 389 390 uint16_t 391 rdata_parser_rrsig_get_type_covered(const uint8_t * const rdata) 392 { 393 return get_uint16_from_bytes(rdata + offsetof(rdata_rrsig_t, type_covered)); 394 } 395 396 //====================================================================================================================== 397 398 uint8_t 399 rdata_parser_rrsig_get_algorithm(const uint8_t * const rdata) 400 { 401 return rdata[offsetof(rdata_rrsig_t, algorithm)]; 402 } 403 404 //====================================================================================================================== 405 406 uint8_t 407 rdata_parser_rrsig_get_labels(const uint8_t * const rdata) 408 { 409 return rdata[offsetof(rdata_rrsig_t, labels)]; 410 } 411 412 //====================================================================================================================== 413 414 uint32_t 415 rdata_parser_rrsig_get_original_ttl(const uint8_t * const rdata) 416 { 417 return get_uint32_from_bytes(rdata + offsetof(rdata_rrsig_t, original_ttl)); 418 } 419 420 //====================================================================================================================== 421 422 uint32_t 423 rdata_parser_rrsig_get_signature_expiration(const uint8_t * const rdata) 424 { 425 return get_uint32_from_bytes(rdata + offsetof(rdata_rrsig_t, signature_expiration)); 426 } 427 428 //====================================================================================================================== 429 430 uint32_t 431 rdata_parser_rrsig_get_signature_inception(const uint8_t * const rdata) 432 { 433 return get_uint32_from_bytes(rdata + offsetof(rdata_rrsig_t, signature_inception)); 434 } 435 436 //====================================================================================================================== 437 438 uint16_t 439 rdata_parser_rrsig_get_key_tag(const uint8_t * const rdata) 440 { 441 return get_uint16_from_bytes(rdata + offsetof(rdata_rrsig_t, key_tag)); 442 } 443 444 //====================================================================================================================== 445 446 const uint8_t * 447 rdata_parser_rrsig_get_signer_name(const uint8_t * const rdata) 448 { 449 return rdata + offsetof(rdata_rrsig_t, signer_name); 450 } 451 452 //====================================================================================================================== 453 454 const uint8_t * 455 rdata_parser_rrsig_get_signature(const uint8_t * const rdata, const uint16_t rdata_len, 456 uint16_t * const out_signature_len) 457 { 458 const rdata_rrsig_t * const rrsig = (const rdata_rrsig_t *)rdata; 459 const uint8_t * const signer_name = rrsig->signer_name; 460 const size_t signer_name_len = domain_name_labels_length(signer_name); 461 462 *out_signature_len = rdata_len - offsetof(rdata_rrsig_t, signer_name) - (uint16_t)signer_name_len; 463 464 return rdata + offsetof(rdata_rrsig_t, signer_name) + signer_name_len;; 465 } 466 467 //====================================================================================================================== 468 469 bool 470 rdata_parser_rrsig_check_validity(const uint8_t * const rdata, const uint16_t rdata_len) 471 { 472 // Minimal size of the RRSIG rdata: <all the fields before signer_name> + <1 byte root domain> + <1 byte signature> 473 const uint16_t min_rdata_len_rrsig = offsetof(rdata_rrsig_t, signer_name) + 1 + 1; 474 require_return_value(rdata_len >= min_rdata_len_rrsig, false); 475 476 const uint8_t * const signer_name = rdata_parser_rrsig_get_signer_name(rdata); 477 const size_t signer_name_len = domain_name_labels_length_with_limit(signer_name, rdata + rdata_len); 478 // The shortest domain name is <root>. 479 require_return_value(signer_name_len >= 1, false); 480 // The signature length has to be greater than 0. 481 require_return_value(signer_name_len < rdata_len - offsetof(rdata_rrsig_t, signer_name), false); 482 483 return true; 484 } 485 486 //====================================================================================================================== 487 // MARK: - DNSKEY Parser 488 489 typedef struct rdata_dnskey_s { 490 uint16_t flags; // The flags of the DNSKEY record. 491 uint8_t protocol; // The protocol of the DNSKEY record. 492 uint8_t algorithm; // The algorithm of the DNSKEY record. 493 uint8_t public_key[0]; // The public key bytes of the DNSKEY record. 494 } rdata_dnskey_t; 495 496 check_compile_time(sizeof(rdata_dnskey_t) == 4); 497 check_compile_time(offsetof(rdata_dnskey_t, flags) == 0); 498 check_compile_time(offsetof(rdata_dnskey_t, protocol) == 2); 499 check_compile_time(offsetof(rdata_dnskey_t, algorithm) == 3); 500 check_compile_time(offsetof(rdata_dnskey_t, public_key) == 4); 501 502 //====================================================================================================================== 503 504 uint16_t 505 rdata_parser_dnskey_get_flags(const uint8_t * const rdata) 506 { 507 return get_uint16_from_bytes(rdata); 508 } 509 510 //====================================================================================================================== 511 512 uint8_t 513 rdata_parser_dnskey_get_protocol(const uint8_t * const rdata) 514 { 515 return rdata[offsetof(rdata_dnskey_t, protocol)]; 516 } 517 518 //====================================================================================================================== 519 520 uint8_t 521 rdata_parser_dnskey_get_algorithm(const uint8_t * const rdata) 522 { 523 return rdata[offsetof(rdata_dnskey_t, algorithm)]; 524 } 525 526 //====================================================================================================================== 527 528 const uint8_t * 529 rdata_parser_dnskey_get_public_key(const uint8_t * const rdata) 530 { 531 return rdata + offsetof(rdata_dnskey_t, public_key); 532 } 533 534 //====================================================================================================================== 535 536 uint16_t 537 rdata_parser_dnskey_get_public_key_size(const uint16_t rdata_len) 538 { 539 require_return_value(rdata_len >= offsetof(rdata_dnskey_t, public_key), 0); 540 return rdata_len - offsetof(rdata_dnskey_t, public_key); 541 } 542 543 //====================================================================================================================== 544 545 bool 546 rdata_parser_dnskey_check_validity(const uint8_t * const UNUSED rdata, const uint16_t rdata_len) 547 { 548 return rdata_len > offsetof(rdata_dnskey_t, public_key); 549 } 550 551 //====================================================================================================================== 552 // MARK: - NSEC3 Parser 553 554 typedef struct rdata_nsec3_s { 555 uint8_t hash_algorithm; // The hash algorithm used to generate the next hashed owner name. 556 uint8_t flags; // The NSEC flags. 557 uint16_t iterations; // The number of extra hash iteration applied when generating the hash. 558 uint8_t salt_length; // The length of the salt below. 559 uint8_t salt[0]; // The salt added to the hash computation. 560 // uint8_t hash_length; // The length of the hash value bytes. 561 // uint8_t next_hashed_owner_name[0]; // The hash value in binary format. 562 // uint8_t type_bit_maps[0]; // The type bit maps that indicate what DNS types are covered by the current NSEC3 record. 563 } rdata_nsec3_t; 564 565 check_compile_time(offsetof(rdata_nsec3_t, hash_algorithm) == 0); 566 check_compile_time(offsetof(rdata_nsec3_t, flags) == 1); 567 check_compile_time(offsetof(rdata_nsec3_t, iterations) == 2); 568 check_compile_time(offsetof(rdata_nsec3_t, salt_length) == 4); 569 check_compile_time(offsetof(rdata_nsec3_t, salt) == 5); 570 571 //====================================================================================================================== 572 573 uint8_t 574 rdata_parser_nsec3_get_hash_algorithm(const uint8_t * const rdata) 575 { 576 return rdata[offsetof(rdata_nsec3_t, hash_algorithm)]; 577 } 578 579 //====================================================================================================================== 580 581 uint8_t 582 rdata_parser_nsec3_get_flags(const uint8_t * const rdata) 583 { 584 return rdata[offsetof(rdata_nsec3_t, flags)]; 585 } 586 587 //====================================================================================================================== 588 589 uint16_t 590 rdata_parser_nsec3_get_iterations(const uint8_t * const rdata) 591 { 592 return get_uint16_from_bytes(rdata + offsetof(rdata_nsec3_t, iterations)); 593 } 594 595 //====================================================================================================================== 596 597 uint8_t 598 rdata_parser_nsec3_get_salt_length(const uint8_t * const rdata) 599 { 600 return rdata[offsetof(rdata_nsec3_t, salt_length)]; 601 } 602 603 //====================================================================================================================== 604 605 const uint8_t * 606 rdata_parser_nsec3_get_salt(const uint8_t * const rdata) 607 { 608 return rdata + offsetof(rdata_nsec3_t, salt); 609 } 610 611 //====================================================================================================================== 612 613 uint8_t 614 rdata_parser_nsec3_get_hash_length(const uint8_t * const rdata) 615 { 616 const uint8_t salt_length = rdata_parser_nsec3_get_salt_length(rdata); 617 return rdata[offsetof(rdata_nsec3_t, salt) + salt_length]; 618 } 619 620 //====================================================================================================================== 621 622 const uint8_t * 623 rdata_parser_nsec3_get_next_hashed_owner_name(const uint8_t * const rdata) 624 { 625 const uint8_t salt_length = rdata_parser_nsec3_get_salt_length(rdata); 626 return (rdata + offsetof(rdata_nsec3_t, salt) + salt_length + sizeof(uint8_t)); 627 } 628 629 //====================================================================================================================== 630 631 const uint8_t * 632 rdata_parser_nsec3_get_type_bit_maps(const uint8_t * const rdata, const uint16_t rdata_len, 633 uint16_t * const out_type_bit_maps_len) 634 { 635 const uint8_t hash_length = rdata_parser_nsec3_get_hash_length(rdata); 636 const uint8_t * const type_bit_maps = rdata_parser_nsec3_get_next_hashed_owner_name(rdata) + hash_length; 637 *out_type_bit_maps_len = (uint16_t)(rdata + rdata_len - type_bit_maps); 638 639 return type_bit_maps; 640 } 641 642 //====================================================================================================================== 643 644 bool 645 rdata_parser_nsec3_check_validity(const uint8_t * const rdata, const uint16_t rdata_len) 646 { 647 // Since NSEC3 does not need to cover itself, it is possible for a NSEC3 to have no type bit map, for example, the 648 // NSEC3 record of the empty nonterminal. 649 // 1 byte <hash algorithm> + 1 byte <flags> + 2 bytes <iterations> + 1 byte <salt length> 650 // + 0 byte <salt, which means no salt> + 1 byte <hash length> + 1 byte <minimal hash length> + 0 bytes <minimal type bit maps>. 651 const uint16_t min_rdata_len_nsec3 = offsetof(rdata_nsec3_t, salt) + sizeof(uint8_t) + 1; 652 require_return_value(rdata_len >= min_rdata_len_nsec3, false); 653 654 const uint8_t * const limit = rdata + rdata_len; 655 656 // Check if the salt is within the limit. 657 const uint8_t * const salt = rdata_parser_nsec3_get_salt(rdata); 658 const uint8_t salt_len = rdata_parser_nsec3_get_salt_length(rdata); 659 require_return_value(salt + salt_len < limit, false); 660 661 // Check if the hash value is within the limit. 662 const uint8_t * const next_hashed_owner_name = rdata_parser_nsec3_get_next_hashed_owner_name(rdata); 663 const uint8_t hash_len = rdata_parser_nsec3_get_hash_length(rdata); 664 require_return_value(next_hashed_owner_name + hash_len <= limit, false); 665 666 // Check type bit maps format. 667 uint16_t type_bit_maps_len; 668 const uint8_t * const type_bit_maps = rdata_parser_nsec3_get_type_bit_maps(rdata, rdata_len, &type_bit_maps_len); 669 const bool type_bit_maps_is_valid = type_bit_maps_check_length(type_bit_maps, type_bit_maps_len); 670 require_return_value(type_bit_maps_is_valid, false); 671 672 return true; 673 } 674