Home | History | Annotate | Line # | Download | only in utilities
      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