1 // 2 // dnssec_v2_structs.h 3 // mDNSResponder 4 // 5 // Copyright (c) 2020 Apple Inc. All rights reserved. 6 // 7 8 #ifndef DNSSEC_v2_STRUCTS_H 9 #define DNSSEC_v2_STRUCTS_H 10 11 #pragma mark - Includes 12 #include "mDNSEmbeddedAPI.h" 13 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 14 #include "list.h" 15 #include "mDNSEmbeddedAPI.h" 16 #include "ClientRequests.h" 17 18 #pragma mark - Enums 19 20 21 22 #pragma mark dnssec_validation_result_t 23 typedef enum dnssec_validation_result { 24 // chain of trust validation error 25 dnssec_validation_invalid, 26 dnssec_validation_valid, 27 dnssec_validation_not_trusted, 28 dnssec_validation_trusted, 29 dnssec_validation_invalid_internal_state, 30 dnssec_validation_non_dnskey_ds_record_chain, 31 dnssec_validation_no_matching_key_tag, 32 33 // DNSSEC record general error 34 dnssec_validation_algorithm_number_not_equal, 35 36 // DS validation error 37 dnssec_validation_ds_digest_not_supported, 38 39 // DNSKEY validation error 40 dnssec_validation_dnskey_algorithm_not_supported, 41 dnssec_validation_dnskey_invalid_flags, 42 dnssec_validation_dnskey_wrong_protocol, 43 44 // RRSIG validation error 45 dnssec_validation_rrsig_use_before_inception, 46 dnssec_validation_rrsig_use_after_expiration, 47 48 // NSEC validation error 49 dnssec_validation_nsec_invalid_nsec_result, 50 dnssec_validation_nsec_malformated_record, 51 // Verifiable NSEC error 52 dnssec_validation_nsec_name_error, 53 dnssec_validation_nsec_no_data, 54 dnssec_validation_nsec_wildcard_answer, 55 dnssec_validation_nsec_wildcard_no_data, 56 57 // NSEC3 validation error 58 dnssec_validation_nsec3_invalid_hash_iteration, 59 dnssec_validation_nsec3_unsupported_hash_algorithm, 60 dnssec_validation_nsec3_unsupported_flag, 61 dnssec_validation_nsec3_different_hash_iteration_salt, 62 dnssec_validation_nsec3_provable_closest_encloser, 63 dnssec_validation_nsec3_nsec3_not_from_the_zone, 64 dnssec_validation_nsec3_malformated_record, 65 // Verifiable NSEC3 error 66 dnssec_validation_nsec3_name_error, 67 dnssec_validation_nsec3_wildcard_no_data, 68 dnssec_validation_nsec3_no_data_response, 69 dnssec_validation_nsec3_no_data_response_opt_out, 70 dnssec_validation_nsec3_wildcard_answer_response, 71 72 // path validation error 73 dnssec_validation_path_invalid_node_type, 74 dnssec_validation_path_unmatched_owner_name, 75 dnssec_validation_path_unmatched_class, 76 dnssec_validation_path_unmatched_type_covered, 77 dnssec_validation_path_invalid_label_count, 78 79 // trust anchor error 80 dnssec_validation_trust_anchor_not_available, 81 dnssec_validation_trust_anchor_does_not_macth, 82 83 // general error 84 dnssec_validation_validating, 85 dnssec_validation_no_memory, 86 dnssec_validation_bogus 87 } dnssec_validation_result_t; 88 89 #pragma mark - Structures 90 91 92 93 #pragma mark - DNSSEC-related records wire format 94 95 96 97 #pragma mark dns_type_cname_t 98 // DNS CNAME record data fields (see <https://tools.ietf.org/html/rfc1035#section-3.3.1>) 99 typedef struct dns_type_cname dns_type_cname_t; 100 struct dns_type_cname { 101 mDNSu8 cname[0]; // To CNAME rdata. 102 }; 103 104 #pragma mark dns_type_ds_t 105 typedef struct dns_type_ds dns_type_ds_t; 106 // DNS DS record data fields (see <https://tools.ietf.org/html/rfc4034#section-5.1>) 107 struct dns_type_ds { 108 mDNSu16 key_tag; // key tag that identifies a specific DNSKEY. 109 mDNSu8 algorithm; // The DNSKEY algorithm that is used to sign the data. 110 mDNSu8 digest_type; // The type of the DS digest. 111 mDNSu8 digest[0]; // To digest rdata. 112 }; 113 114 #pragma mark dns_type_dnskey_t 115 // DNS DNSKEY record data fields (see <https://tools.ietf.org/html/rfc4034#section-2.1>) 116 typedef struct dns_type_dnskey dns_type_dnskey_t; 117 struct dns_type_dnskey { 118 mDNSu16 flags; // The DNSKEY flags. 119 mDNSu8 protocol; // Protocol that identifies DNSKEY as a key used in DNSSEC, it should always be 3. 120 mDNSu8 algorithm; // The DNSKEY algorithm that is used to sign the data. 121 mDNSu8 public_key[0]; // To public rdata. 122 }; 123 124 #pragma mark dns_type_rrsig_t 125 // DNS RRSIG record data fields (see <https://tools.ietf.org/html/rfc4034#section-3.1>) 126 typedef struct dns_type_rrsig dns_type_rrsig_t; 127 struct dns_type_rrsig { 128 mDNSu16 type_covered; // Indicates which DNS type RRSIG covers 129 mDNSu8 algorithm; // The DNSKEY algorithm that is used to sign the data. 130 mDNSu8 labels; // The number of labels in the RRSIG owner name, it is used to check wild matching. 131 mDNSu32 original_TTL; // The original TTL of the records that are covered by the RRSIG, it is used to reconstruct the signed data. 132 mDNSu32 signature_expiration; // The epoch time when the RRSIG expires. 133 mDNSu32 signature_inception; // The epoch time when the RRSIG should start to be valid to validate. 134 mDNSu16 key_tag; // The key tag that identifies which DNSKEY it uses to generate the current RRSIG. 135 mDNSu8 signer_name[0]; // To the signer name. 136 // mDNSu8 signature[0]; // To the signature rdata. 137 }; 138 139 #pragma mark dns_type_nsec_t 140 // DNS NSEC record data fields (see <https://tools.ietf.org/html/rfc4034#section-2.1>) 141 typedef struct dns_type_nsec dns_type_nsec_t; 142 struct dns_type_nsec { 143 mDNSu8 next_domain_name[0]; // The next domain that exists in the zone 144 // mDNSu8 type_bit_maps[0]; // To the type bit map that indicates what DNS types are covered by the current NSEC record. 145 }; 146 147 #pragma mark dns_type_nsec3_t 148 // DNS NSEC3 record data fields (see <https://tools.ietf.org/html/rfc5155#section-3.1>) 149 typedef struct dns_type_nsec3 dns_type_nsec3_t; 150 struct dns_type_nsec3 { 151 mDNSu8 hash_algorithm; // Which hash algorithm that NSEC3 uses to generate the hash. 152 mDNSu8 flags; // The NSEC3 flags 153 mDNSu16 iterations; // The iterations of hash operation on the data 154 mDNSu8 salt_length; 155 mDNSu8 salt[0]; // varied-size array 156 // mDNSu8 hash_length; 157 // mDNSu8 next_hashed_owner_name[0];// The next hashed domain that exists in the zone 158 // mDNSu8 * type_bit_maps; // To the type bit map that indicates what DNS types are covered by the current NSEC3 record. 159 }; 160 161 #pragma mark - DNSSEC records in memory 162 163 #pragma mark dnssec_rr_t 164 typedef struct dnssec_rr dnssec_rr_t; 165 struct dnssec_rr { // Represents a resource record 166 mDNSu16 rr_type; // The DNS type of the resource record. 167 mDNSu16 rr_class; // The internet class of the record, should be IN 168 mDNSu16 rdata_length; // The length of the rdata 169 mDNSu32 name_hash; // The hash of the owner name that is used to compare name quickly 170 mDNSu32 rdata_hash; // The hash of the rdata that is used to compare rdata quickly 171 domainname name; // The owner name of the record 172 mDNSu8 * _Nullable rdata; // The rdata 173 ResourceRecord * _Nullable rr; // Points to ResourceRecord in the mDNSCore cache 174 }; 175 176 #pragma mark dnssec_original_t 177 typedef struct dnssec_original dnssec_original_t; 178 struct dnssec_original { // The response that answers user's question. 179 mDNSBool answer_from_cache; // Indicates If we get the answer from the cache, instead of refresh response from DNS server. 180 DNSServiceErrorType dns_error; // DNSServiceErrorType when mDNSCore returns the answer. 181 QC_result qc_result; // Event type for the current resource record including QC_add, QC_rmv, QC_supressed. 182 dnssec_rr_t dnssec_rr; // Store the answer returned from mDNSCore. 183 }; 184 185 #pragma mark dnssec_cname_t 186 typedef struct dnssec_cname dnssec_cname_t; 187 struct dnssec_cname { // The response that does not answer user's question, but provides a CNAME to continue the query 188 mDNSu8 * _Nullable cname; // The CNAME rdata. 189 dnssec_rr_t dnssec_rr; // Store the answer returned from mDNSCore. 190 }; 191 192 #pragma mark dnssec_ds_t 193 typedef struct dnssec_ds dnssec_ds_t; 194 struct dnssec_ds { // The response that answers DS query from mDNSResponder 195 mDNSu16 key_tag; // ID that identifies the DNSKEY that the current DS verifies. 196 mDNSu8 algorithm; // The algorithm of the DNSKEY that the current DS verifies. 197 mDNSu8 digest_type; // The digest type that is used to caluclate the current DS from the DNSKEY. 198 mDNSu16 digest_length; // The length of the digest. 199 const mDNSu8 * _Nullable digest; // The DS rdata. 200 dnssec_rr_t dnssec_rr; // Store the answer returned from mDNSCore. 201 }; 202 203 // DNSKEY flag bits 204 #define DNSKEY_FLAG_ZONE_KEY 0x100 205 #define DNSKEY_FLAG_SECURITY_ENTRY_POINT 0x1 206 207 #pragma mark dnssec_dnskey_t 208 typedef struct dnssec_dnskey dnssec_dnskey_t; 209 struct dnssec_dnskey { // The response that answeres DNSKEY query from mDNSResponder. 210 mDNSu16 flags; // The bit flags for DNSKEY. 211 mDNSu8 protocol; // Should always be value 3. 212 mDNSu8 algorithm; // The type of crypoto algorithm that the current DNSKEY applies to. 213 mDNSu16 key_tag; // ID that identifies the current DNSKEY 214 mDNSu16 public_key_length; // The length of the DNSKEY. 215 mDNSu8 * _Nullable public_key; // The DNSKEY rdata 216 dnssec_rr_t dnssec_rr; // Store the answer returned from mDNSCore. 217 }; 218 219 #pragma mark dnssec_rrsig_t 220 typedef struct dnssec_rrsig dnssec_rrsig_t; 221 struct dnssec_rrsig { 222 mDNSu16 type_covered; // The DNS type that is covered by the current RRSIG 223 mDNSu8 algorithm; // The algorithm of DNSKEY that is used to generate the current RRSIG 224 mDNSu8 labels; // The number of labels of RRSIG's owner, used for wildcard matching 225 mDNSu32 original_TTL; // The original TTL of the records that are used to generate the current RRSIG, used to reconstruct the signed data 226 mDNSu32 signature_expiration; // The epoch time when the RRSIG expires. 227 mDNSu32 signature_inception; // The epoch time when the RRSIG should start to be valid to validate. 228 mDNSu16 key_tag; // The key tag that identifies which DNSKEY it uses to generate the current RRSIG. 229 mDNSu16 signature_length; // The length of the signature. 230 mDNSu8 * _Nullable signer_name; // The name of signer that signs the covered records 231 mDNSu8 * _Nullable signature; // The signature rdata 232 dnssec_rr_t dnssec_rr; // Store the answer returned from mDNSCore. 233 }; 234 235 #pragma mark dnssec_nsec_t 236 typedef struct dnssec_nsec dnssec_nsec_t; 237 struct dnssec_nsec { 238 mDNSu8 * _Nullable exist_domain_name; // The owner name of records that exist before next_domain_name by canonical order in the zone. 239 mDNSu8 * _Nullable next_domain_name; // The owner name of records that exist after next_domain_name by canonical order in the zone. 240 mDNSu8 * _Nullable type_bit_maps; // The type bit map that indicates what DNS types are covered by the current NSEC record. 241 mDNSu16 type_bit_maps_length; // The length of the type bit map. 242 dnssec_rr_t dnssec_rr; // Store the answer returned from mDNSCore. 243 }; 244 245 #pragma mark dnssec_nsec3_t 246 typedef struct dnssec_nsec3 dnssec_nsec3_t; 247 struct dnssec_nsec3 { 248 mDNSu8 hash_algorithm; // The hash algorithm that NSEC3 uses to generate the hash 249 mDNSu8 flags; // The NSEC3 flags 250 mDNSu16 iterations; // The iterations of hash operation on the data 251 mDNSu8 salt_length; // The length of the salt added when doing hash 252 mDNSu8 hash_length; // The length of the final hash result 253 mDNSu16 type_bit_maps_length; // The length of the type bit map. 254 mDNSu8 * _Nullable salt; // The salt added to the hash result for every iteration 255 mDNSu8 * _Nullable next_hashed_owner_name; // The binary-format hashed owner name of records that exist after the owner name of current NSEC3 record by canonical order in the zone. 256 mDNSu8 * _Nullable type_bit_maps; // The type bit map that indicates what DNS types are covered by the current NSEC3 record. 257 char * _Nullable next_hashed_owner_name_b32; // The b32-format string of hashed owner name 258 mDNSu32 next_hashed_owner_name_b32_length; // The length of next_hashed_owner_name_b32 string 259 dnssec_rr_t dnssec_rr; // Store the answer returned from mDNSCore. 260 }; 261 262 #pragma mark - Validation tree structures 263 264 265 266 #pragma mark nsecs_with_rrsig_t 267 typedef struct nsecs_with_rrsig nsecs_with_rrsig_t; 268 struct nsecs_with_rrsig { // The NSEC response from DNS server that indicates the non-existence of the record in the query. 269 list_t nsec_and_rrsigs_same_name; // list_t<one_nsec_with_rrsigs_t>, the list of one_nsec_with_rrsigs_t structure, each one_nsec_with_rrsigs_t represents one NSEC record with its corresponding RRSIG. 270 list_t wildcard_answers; // list_t<dnssec_rr_t>, the list of dnssec_rr_t structure, each dnssec_rr_t represents one wildcard record. 271 list_t wildcard_rrsigs; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structure, each dnssec_rrsig_t represents one RRSIG that is used to validate the wildcard answer in wildcard_answers. 272 ResourceRecord * _Nullable negative_rr; // The negative answer generated by mDNSResponder, that NSEC records try to prove. 273 dnssec_validation_result_t nsec_result; // The validation result after validating the current NSEC records, it is only meaningful after we finish the validation. 274 }; 275 276 #pragma mark one_nsec_with_rrsigs_t 277 typedef struct one_nsec_with_rrsigs one_nsec_with_rrsigs_t; 278 struct one_nsec_with_rrsigs { // One NSEC record that form a complete NSEC response with other NSEC records. 279 const mDNSu8 * _Nullable owner_name; // The onwer name of NSEC record, also indicates that this name does exist in the zone. 280 dnssec_nsec_t nsec_record; // The dnssec_nsec_t that holds the NSEC record. 281 list_t rrsig_records; // list_t<dnssec_rrsig_t>, the RRSIGs that generated from the current NSEC record. 282 }; 283 284 #pragma mark nsec3s_with_rrsig_t 285 typedef struct nsec3s_with_rrsig nsec3s_with_rrsig_t; 286 struct nsec3s_with_rrsig { // The NSEC3 response from DNS server that indicates the non-existence of the record in the query. 287 list_t nsec3_and_rrsigs_same_name; // list_t<one_nsec3_with_rrsigs_t>, the list of one_nsec3_with_rrsigs_t structure, each one_nsec3_with_rrsigs_t represents one NSEC3 record with its corresponding RRSIG. 288 list_t wildcard_answers; // list_t<dnssec_rr_t>, the list of dnssec_rr_t structure, each dnssec_rr_t represents one wildcard record. 289 list_t wildcard_rrsigs; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structure, each dnssec_rrsig_t represents one RRSIG that is used to validate the wildcard answer in wildcard_answers. 290 ResourceRecord * _Nullable negative_rr; // The negative answer generated by mDNSResponder, that NSEC3 records try to prove. 291 dnssec_validation_result_t nsec3_result; // The validation result after validating the current NSEC3 records, it is only meaningful after we finish the validation. 292 }; 293 294 #pragma mark one_nsec3_with_rrsigs_t 295 typedef struct one_nsec3_with_rrsigs one_nsec3_with_rrsigs_t; 296 struct one_nsec3_with_rrsigs { // One NSEC3 record that form a complete NSEC response with other NSEC records. 297 const mDNSu8 * _Nullable owner_name; // The onwer name of NSEC3 record, also indicates that this name does exist in the zone. 298 dnssec_nsec3_t nsec3_record; // The dnssec_nsec_t that holds the NSEC3 record. 299 list_t rrsig_records; // list_t<dnssec_rrsig_t>, the RRSIGs that generated from the current NSEC3 record. 300 }; 301 302 #pragma mark cnames_with_rrsig_t 303 typedef struct cnames_with_rrsig cnames_with_rrsig_t; 304 struct cnames_with_rrsig { // The CNAME response from DNS server that indicates the current query name is a alias of another name. 305 list_t cname_records; // list_t<dnssec_cname_t>, the list of dnssec_cname_t structure, each dnssec_cname_t represents one CNAME, in fact there should only be one CNAME in the list. 306 list_t rrsig_records; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structure, each dnssec_rrsig_t represents one RRSIG that i sused to validate the CNAME record in cname_records. 307 }; 308 309 #pragma mark trust_anchor_t 310 typedef struct trust_anchors trust_anchors_t; 311 struct trust_anchors { // The trust anchor structure that mDNSResponder loads during initialization, it stays unchanged during the life time of mDNSResponder. 312 domainname name; // The owner name of the trust anchor 313 mDNSu32 name_hash; // The hash of the owner name, used to speed up name comparsion. 314 list_t dnskey_trust_anchors; // list_t<dnssec_dnskey_t>, the list of dnssec_dnskey_t structures, the trust anchor could be a DNSKEY record. When mDNSResponder can use this trusted DNSKEY to validate the record, then the entire validation chain rooted in the validated record could be trusted. 315 list_t ds_trust_anchors; // list_t<dnssec_ds_t>, the list of dnssec_ds_t structures, the trust anchor could also be a DS record. When mDNSResponder can use this trusted DS to match DNSKEY record, then the entire validation chain rooted in the validated DNSKEY record could be trusted. 316 }; 317 318 #pragma mark response_type_t 319 typedef enum response_type { // The response type for any DNS query in DNSSEC environment. 320 unknown_response, // The initial state, which means we have not received any response. 321 original_response, // The DNS server returns what the user expects, thus it is a original response for the query. 322 cname_response, // The DNS server returns a CNAME for user's NOn-CNAME query 323 nsec_response, // The DNS server returns a NSEC response trying to prove that the name or the record type does not exist. 324 nsec3_response // The DNS server returns a NSEC3 response trying to prove that the name or the record type does not exist. 325 } response_type_t; 326 327 #pragma mark originals_with_rrsig_t 328 typedef struct originals_with_rrsig originals_with_rrsig_t; 329 struct originals_with_rrsig { // This structure holds the response that will be returned to the user after validation. 330 union { // The response can only be original_response/cname_response/nsec_response/nsec3_response. 331 struct { 332 list_t original_records; // list_t<dnssec_original_t>, the list of dnssec_original_t structures, each dnssec_original_t holds one response that user expects. 333 list_t rrsig_records; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structures, each dnssec_rrsig_t holds one RRSIG generated from the dnssec_original_t above. 334 ResourceRecord * _Nullable negative_rr; // The query may be suppressed by mDNSResponder, it is a denial of existence response that does not need NSEC/NSEC3 to validate, just put it in original. 335 mDNSBool suppressed_response; // Indicates if the original response is a suppressed one. 336 } original; // Used when the type is original_response. 337 cnames_with_rrsig_t cname_with_rrsig; // Used when the type is cname_response. 338 // NSEC and NSEC3 RRs can not co-exist in a zone. 339 nsecs_with_rrsig_t nsecs_with_rrsig; // Used when the type is nsec_response. 340 nsec3s_with_rrsig_t nsec3s_with_rrsig; // Used when the type is nsec3_response. 341 } u; 342 response_type_t type; // original_response/cname_response/nsec_response/nsec3_response. 343 }; 344 345 #pragma mark dses_with_rrsig_t 346 typedef struct dses_with_rrsig dses_with_rrsig_t; 347 struct dses_with_rrsig { // This structure holds the DS response that DNSSEC handler queries for. 348 union { // The response can only be original_response/nsec_response/nsec3_response. 349 struct { 350 list_t ds_records; // list_t<dnssec_ds_t>, the list of dnssec_ds_t structure, each dnssec_ds_t holds one DS record that could be used to verifies one DNSKEY record 351 list_t rrsig_records; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structure, each dnssec_rrsig_t holds one RRSIG generated from the dnssec_ds_t above. 352 } original; 353 // NSEC and NSEC3 RRs can not co-exist in a zone. 354 nsecs_with_rrsig_t nsecs_with_rrsig; // Used when the type is nsec_response. 355 nsec3s_with_rrsig_t nsec3s_with_rrsig; // Used when the type is nsec3_response. 356 } u; 357 response_type_t type; // original_response/nsec_response/nsec3_response, CNAME can only be the leaf node, thus there should never be CNAME for DS query. 358 mDNSBool set_completed; // Indicates if we have already get the DS records. 359 }; 360 361 #pragma mark dnskeys_with_rrsig_t 362 typedef struct dnskeys_with_rrsig dnskeys_with_rrsig_t; 363 struct dnskeys_with_rrsig { // This structure holds the DNSKEY response that DNSSEC handler queries for. The response can only be original_response, because both NSEC and NSEC3 indicate that DNSKEY does exist in order to validate the NSEC/NSEC3. 364 list_t dnskey_records; // list_t<dnssec_dnskey_t>, the list of dnssec_dnskey_t structures, each dnssec_dnskey_t holds one DNSKEY that could be used to validate signer's records with the corresponding RRSIG. 365 list_t rrsig_records; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structures, each dnssec_rrsig_t holds one RRSIG generated from the dnssec_dnskey_t above. 366 mDNSBool set_completed; // Indicates if we have already get the DNSKEY records. 367 }; 368 369 #pragma mark dnssec_zone_t 370 // This structure represents one zone node in the validation tree. For example, if the user queries for the AAAA record 371 // of "www.internetsociety.org.", there will be 3 zone nodes at last: 372 // Root zone node: "." DNSKEY 373 // Zone node: "org." DNSKEY/DS 374 // Zone node: "internetsociety.org." DNSKEY/DS 375 // Response: "www.internetsociety.org." AAAA 376 // Each node contains 2 kinds of records: DNSKEY and DS records 377 typedef struct dnssec_zone dnssec_zone_t; 378 struct dnssec_zone { 379 // general field that is used to fecth records 380 domainname domain_name; // DNS representation of the zone name. 381 mDNSu32 name_hash; // The name hash to speed up name comparison. 382 383 // dnssec resource records 384 // DS record 385 QueryRecordClientRequest ds_request; // The DS request handler 386 mDNSBool ds_request_started; // Indicates if we issued the DS request, sometimes we do not want to issue query such as we are in root "." node, and root node does not have DS record. 387 mDNSBool dses_initialized; // Indicate if the DS list is initialized 388 dses_with_rrsig_t dses_with_rrsig; // list_t<dses_with_rrsig_t>, the list of dses_with_rrsig_t structures, each dses_with_rrsig_t holds the DS records and the corresponding RRSIG records for the current zone. 389 mDNSs32 last_time_ds_add; // last time that DS records are added 390 mDNSs32 last_time_ds_rmv; // last time that DS records are removed 391 392 // DNSKEY record 393 QueryRecordClientRequest dnskey_request; // The DNSKEY request handler 394 mDNSBool dnskey_request_started; // Indicates if we issue the DNSKEY request, sometimes we do not issue the query because the current zone has a trust anchor for DNSKEY. 395 dnskeys_with_rrsig_t dnskeys_with_rrsig; // list_t<dnssec_dnskey_t>, the list of dnskeys_with_rrsig structures, each dnssec_dnskey_t holds the DNSKEY records and the corresponding RRSIG records for the current zone. 396 mDNSs32 last_time_dnskey_add; // last time that DNSKEY records are added 397 mDNSs32 last_time_dnskey_rmv; // last time that DNSKEY records are removed 398 399 // The current zone may have trust anchor installed in the system 400 const trust_anchors_t * _Nullable trust_anchor; // list_t<trust_anchor_t>, the list of trust_anchor_t structures, each trust_anchor_t represent one trust anchor. 401 }; 402 403 #pragma mark original_request_parameters_t 404 typedef struct original_request_parameters original_request_parameters_t; 405 struct original_request_parameters { // This structure contains the original request paramters set by the user. 406 mDNSu32 request_id; 407 domainname question_name; 408 mDNSu32 question_name_hash; 409 mDNSu16 question_type; 410 mDNSu16 question_class; 411 mDNSInterfaceID _Nullable interface_id; 412 mDNSs32 service_id; 413 mDNSu32 flags; 414 mDNSBool append_search_domains; 415 mDNSs32 pid; 416 mDNSu8 uuid[UUID_SIZE]; 417 mDNSs32 uid; 418 #if MDNSRESPONDER_SUPPORTS(APPLE, AUDIT_TOKEN) 419 audit_token_t peer_audit_token; 420 mDNSBool has_peer_audit_token; 421 audit_token_t delegate_audit_token; 422 mDNSBool has_delegate_audit_token; 423 #endif 424 #if MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 425 mDNSu8 resolver_uuid[UUID_SIZE]; 426 mDNSBool need_encryption; 427 mdns_dns_service_id_t custom_id; 428 #endif 429 QueryRecordResultHandler _Nullable user_handler; 430 void * _Nullable user_context; 431 }; 432 433 #pragma mark denial_of_existence_records_t 434 typedef struct denial_of_existence_records denial_of_existence_records_t; 435 struct denial_of_existence_records { 436 list_t resource_records; //list_t<ResourceRecord>; 437 }; 438 439 #pragma mark original_t 440 typedef struct original original_t; 441 struct original { // This structure contains all the useful information about the user's original request. 442 original_request_parameters_t original_parameters; // The original paramters getting from the user 443 originals_with_rrsig_t original_result_with_rrsig; // The original response that will be returned to the user. 444 const trust_anchors_t * _Nullable original_trust_anchor; // It is possible that the returned original response is a trust anchor installed. 445 mDNSs32 last_time_add; // Last time that originals_with_rrsig_t records are added. 446 mDNSs32 last_time_rmv; // Last time that originals_with_rrsig_t records are removed. 447 }; 448 449 #pragma mark returned_answers_t 450 typedef struct returned_answers returned_answers_t; 451 struct returned_answers { // This structure contains all the records that are returned to the user, these information is tracked to properly deliver ADD/RMV event to the user 452 list_t answers; // list_t<ResourceRecord *>, the list of "ResourceRecord *" pointers, each pointer points to a ResourceRecord in the cache that has been returned to the user. 453 dnssec_result_t dnssec_result; // The dnssec_result_t that has been returned to the user. 454 DNSServiceErrorType error; // The returned DNSServiceErrorType 455 response_type_t type; // The type of the returned answer, it could be original_response(including suppressed case)/nsec_response/nsec3_response 456 }; 457 458 #pragma mark dnssec_context_t 459 // This structure contains the DNSSEC context that is needed to track additional information that is not provided by 460 // mDNSCore, each DNSSEC-enabled DNS request would have a seperated DNSSEC context. 461 typedef struct dnssec_context dnssec_context_t; 462 struct dnssec_context { 463 // Necessary request 464 QueryRecordClientRequest * _Nonnull me; // The request of the question that we are currently working on. 465 QueryRecordClientRequest request_to_follow_cname; // An idle request unless there is a need to follow the CNAME reference, and start a sub request. 466 467 // Zone records that could be used to validate records. 468 list_t zone_chain; // list_t<dnssec_zone_t>, the validation tree consists of zone nodes from root to leaf. 469 470 // original request fields 471 original_t original; // Information about the user's original request. 472 473 // denial of existence fields 474 denial_of_existence_records_t * _Nullable denial_of_existence_records; // It is a temporary field that is used to pass the NSEC/NSEC3 records to the DNSSEC handler, will be cleared after running DNSSEC handler. 475 476 // save the records that are returned to the user 477 returned_answers_t returned_answers; // The records that have been returned to the user. 478 479 // DNSSEC context pointer 480 dnssec_context_t * _Nullable primary_dnssec_context; // This points to the initial DNSSEC context of the first query coming from the user, i.e. the first name in the CNAME chain. 481 dnssec_context_t * _Nullable subtask_dnssec_context; // If the DNSSEC-enabled DNS query has CNAMEs, this field is used to create another new DNSSEC context that resolves and validates the new CNAME. 482 }; 483 484 485 #pragma mark - Functions 486 487 488 489 #pragma mark - dns_type_*_t records parsing 490 491 492 493 #pragma mark parsse_dns_type_cname_t 494 mDNSexport void 495 parsse_dns_type_cname_t(const void * const _Nonnull rdata, mDNSu8 * _Nullable * const _Nonnull out_cname); 496 497 #pragma mark parse_dns_type_ds_t 498 mDNSexport mDNSBool 499 parse_dns_type_ds_t( 500 const void * const _Nonnull rdata, 501 const mDNSu16 rdata_length, 502 mDNSu16 * const _Nullable out_key_tag, 503 mDNSu8 * const _Nullable out_algorithm, 504 mDNSu8 * const _Nullable out_digest_type, 505 mDNSu16 * const _Nullable out_digest_length, 506 const mDNSu8 * _Nonnull * const _Nullable out_digest); 507 508 #pragma mark parse_dns_type_dnskey_t 509 mDNSexport mDNSBool 510 parse_dns_type_dnskey_t( 511 const void * const _Nonnull rdata, 512 const mDNSu16 rdata_length, 513 mDNSu16 * const _Nullable out_flags, 514 mDNSu8 * const _Nullable out_protocol, 515 mDNSu8 * const _Nullable out_algorithm, 516 mDNSu16 * const _Nullable out_public_key_length, 517 mDNSu8 * _Nonnull * const _Nullable out_public_key); 518 519 #pragma mark parse_dns_type_rrsig_t 520 mDNSexport mDNSBool 521 parse_dns_type_rrsig_t( 522 const void * const _Nonnull rdata, 523 const mDNSu16 rdata_length, 524 mDNSu16 * const _Nullable out_type_covered, 525 mDNSu8 * const _Nullable out_algorithm, 526 mDNSu8 * const _Nullable out_labels, 527 mDNSu32 * const _Nullable out_original_ttl, 528 mDNSu32 * const _Nullable out_signature_expiration, 529 mDNSu32 * const _Nullable out_signature_inception, 530 mDNSu16 * const _Nullable out_key_tag, 531 mDNSu16 * const _Nullable out_signature_length, 532 mDNSu8 * _Nonnull * const _Nullable out_signer_name, 533 mDNSu8 * _Nonnull * const _Nullable out_signature); 534 535 #pragma mark parse_dns_type_nsec_t 536 mDNSexport mDNSBool 537 parse_dns_type_nsec_t( 538 const void * const _Nonnull rdata, 539 const mDNSu16 rdata_length, 540 mDNSu16 * const _Nonnull out_type_bit_maps_length, 541 mDNSu8 * _Nonnull * const _Nullable out_next_domain_name, 542 mDNSu8 * _Nonnull * const _Nullable out_type_bit_maps); 543 544 #pragma mark parse_dns_type_nsec3_t 545 mDNSexport mDNSBool 546 parse_dns_type_nsec3_t( 547 const void * const _Nonnull rdata, 548 const mDNSu16 rdata_length, 549 mDNSu8 * const _Nullable out_hash_algorithm, 550 mDNSu8 * const _Nullable out_flags, 551 mDNSu16 * const _Nullable out_iterations, 552 mDNSu8 * const _Nullable out_salt_length, 553 mDNSu8 * const _Nullable out_hash_length, 554 mDNSu16 * const _Nullable out_type_bit_maps_length, 555 mDNSu8 * _Nonnull * const _Nullable out_salt, 556 mDNSu8 * _Nonnull * const _Nullable out_next_hashed_owner_name, 557 mDNSu8 * _Nonnull * const _Nullable out_type_bit_maps); 558 559 #pragma mark get_covered_type_of_dns_type_rrsig_t 560 mDNSexport mDNSu16 561 get_covered_type_of_dns_type_rrsig_t(const void * const _Nonnull rdata); 562 563 // dnssec_rr_t function prototypes 564 #pragma mark - dnssec_rr_t functions 565 566 mDNSexport void 567 initialize_dnssec_rr_t(dnssec_rr_t * const _Nonnull dnssec_rr, ResourceRecord * const _Nonnull rr); 568 569 mDNSexport void 570 uninitialize_dnssec_rr_t(dnssec_rr_t * const _Nonnull dnssec_rr); 571 572 mDNSexport mDNSBool 573 equal_dnssec_rr_t(const dnssec_rr_t * const _Nonnull left, const dnssec_rr_t * const _Nonnull right); 574 575 mDNSexport void 576 print_dnssec_rr_t(const dnssec_rr_t * const _Nonnull dnssec_rr, mDNSu8 num_of_tabs); 577 578 // dnssec_original_t function prototypes 579 #pragma mark - dnssec_original_t functions 580 581 mDNSexport void 582 initialize_dnssec_original_t( 583 dnssec_original_t * const _Nonnull original, 584 ResourceRecord * const _Nonnull rr, 585 const mDNSBool answer_from_cache, 586 const DNSServiceErrorType dns_error, 587 const QC_result qc_result); 588 589 mDNSexport void 590 uninitialize_dnssec_original_t(dnssec_original_t * const _Nonnull original); 591 592 mDNSexport void 593 print_dnssec_original_t(const dnssec_original_t * const _Nonnull original, mDNSu8 num_of_tabs); 594 595 #pragma mark - dnssec_cname_t functions 596 597 mDNSexport void 598 initialize_dnssec_cname_t(dnssec_cname_t * const _Nonnull cname, ResourceRecord * const _Nonnull rr); 599 600 mDNSexport void 601 uninitialize_dnssec_cname_t(dnssec_cname_t * const _Nonnull cname); 602 603 mDNSexport void 604 print_dnssec_cname_t(const dnssec_cname_t * const _Nonnull cname, mDNSu8 num_of_tabs); 605 606 #pragma mark - dnssec_ds_t functions 607 608 mDNSexport mDNSBool 609 initialize_dnssec_ds_t(dnssec_ds_t * const _Nonnull ds, ResourceRecord * const _Nonnull rr); 610 611 mDNSexport mDNSBool 612 equals_dnssec_ds_t(const dnssec_ds_t * const _Nonnull left, const dnssec_ds_t * const _Nonnull right); 613 614 mDNSexport void 615 uninitialize_dnssec_ds_t(dnssec_ds_t * const _Nonnull ds); 616 617 mDNSexport void 618 print_dnssec_ds_t(const dnssec_ds_t * const _Nonnull ds, mDNSu8 num_of_tabs); 619 620 #pragma mark - dnssec_dnskey_t functions 621 622 mDNSexport mDNSBool 623 initialize_dnssec_dnskey_t(dnssec_dnskey_t * const _Nonnull dnskey, ResourceRecord * const _Nonnull rr); 624 625 mDNSexport mDNSBool 626 equals_dnssec_dnskey_t(const dnssec_dnskey_t * const _Nonnull left, const dnssec_dnskey_t * const _Nonnull right); 627 628 mDNSexport void 629 uninitialize_dnssec_dnskey_t(dnssec_dnskey_t * const _Nonnull dnskey); 630 631 mDNSexport void 632 print_dnssec_dnskey_t(const dnssec_dnskey_t * const _Nonnull dnskey, mDNSu8 num_of_tabs); 633 634 #pragma mark - dnssec_rrsig_t functions 635 636 mDNSexport mDNSBool 637 initialize_dnssec_rrsig_t(dnssec_rrsig_t * const _Nonnull rrsig, ResourceRecord * const _Nonnull rr); 638 639 mDNSexport void 640 uninitialize_dnssec_rrsig_t(dnssec_rrsig_t * const _Nonnull rrsig); 641 642 mDNSexport void 643 print_dnssec_rrsig_t(const dnssec_rrsig_t * const _Nonnull rrsig, mDNSu8 num_of_tabs); 644 645 #pragma mark - dnssec_nsec_t functions 646 647 mDNSexport mDNSBool 648 initialize_dnssec_nsec_t(dnssec_nsec_t * const _Nonnull nsec, ResourceRecord * const _Nonnull rr); 649 650 mDNSexport void 651 uninitialize_dnssec_nsec_t(dnssec_nsec_t * const _Nonnull nsec); 652 653 mDNSexport void 654 print_dnssec_nsec_t(const dnssec_nsec_t * const _Nonnull nsec, mDNSu8 num_of_tabs); 655 656 #pragma mark - dnssec_nsec3_t functions 657 658 mDNSexport mDNSBool 659 initialize_dnssec_nsec3_t(dnssec_nsec3_t * const _Nonnull nsec3, ResourceRecord * const _Nonnull rr); 660 661 mDNSexport void 662 uninitialize_dnssec_nsec3_t(dnssec_nsec3_t * const _Nonnull nsec3); 663 664 mDNSexport void 665 print_dnssec_nsec3_t(const dnssec_nsec3_t * const _Nonnull nsec3, mDNSu8 num_of_tabs); 666 667 #pragma mark - nsecs_with_rrsig_t functions 668 669 mDNSexport mStatus 670 initialize_nsecs_with_rrsig_t(nsecs_with_rrsig_t * const _Nonnull nsecs); 671 672 mDNSexport void 673 uninitialize_nsecs_with_rrsig_t(nsecs_with_rrsig_t * const _Nonnull nsecs); 674 675 mDNSexport void 676 print_nsecs_with_rrsig_t(const nsecs_with_rrsig_t * const _Nonnull nsecs, mDNSu8 num_of_tabs); 677 678 # pragma mark - one_nsec_with_rrsigs_t functions 679 680 mDNSexport mDNSBool 681 initialize_one_nsec_with_rrsigs_t( 682 one_nsec_with_rrsigs_t * const _Nonnull one_nsec_with_rrsigs, 683 ResourceRecord * const _Nonnull rr); 684 685 mDNSexport void 686 uninitialize_one_nsec_with_rrsigs_t(one_nsec_with_rrsigs_t * const _Nonnull one_nsec_with_rrsigs); 687 688 # pragma mark - one_nsec3_with_rrsigs_t functions 689 690 mDNSexport mDNSBool 691 initialize_one_nsec3_with_rrsigs_t( 692 one_nsec3_with_rrsigs_t * const _Nonnull one_nsec3_with_rrsigs, 693 ResourceRecord * const _Nonnull rr); 694 695 mDNSexport void 696 uninitialize_one_nsec3_with_rrsigs_t(one_nsec3_with_rrsigs_t * const _Nonnull one_nsec3_with_rrsigs); 697 698 #pragma mark - nsec3s_with_rrsig_t functions 699 700 mDNSexport mStatus 701 initialize_nsec3s_with_rrsig_t(nsec3s_with_rrsig_t * const _Nonnull nsec3s); 702 703 mDNSexport void 704 uninitialize_nsec3s_with_rrsig_t(nsec3s_with_rrsig_t * const _Nonnull nsec3s); 705 706 mDNSexport void 707 print_nsec3s_with_rrsig_t(const nsec3s_with_rrsig_t * const _Nonnull nsec3s, mDNSu8 num_of_tabs); 708 709 #pragma mark - cnames_with_rrsig_t 710 711 mDNSexport void 712 initialize_cname_with_rrsig_t(cnames_with_rrsig_t * const _Nonnull cname); 713 714 mDNSexport void 715 uninitialize_cname_with_rrsig_t(cnames_with_rrsig_t * const _Nonnull cname); 716 717 mDNSexport void 718 print_cname_with_rrsig_t(const cnames_with_rrsig_t * const _Nonnull cname, mDNSu8 num_of_tabs); 719 720 #pragma mark - response_type_t functions 721 722 mDNSexport const char * _Nonnull 723 response_type_value_to_string(response_type_t type); 724 725 #pragma mark - originals_with_rrsig_t 726 727 mDNSexport void 728 initialize_originals_with_rrsig_t(originals_with_rrsig_t * const _Nonnull original, const response_type_t type); 729 730 mDNSexport void 731 uninitialize_originals_with_rrsig_t(originals_with_rrsig_t * const _Nonnull original); 732 733 mDNSexport mDNSBool 734 contains_rrsig_in_originals_with_rrsig_t(const originals_with_rrsig_t * const _Nonnull original); 735 736 mDNSexport void 737 print_originals_with_rrsig_t(const originals_with_rrsig_t * const _Nonnull original, mDNSu8 num_of_tabs); 738 739 #pragma mark - dses_with_rrsig_t functions 740 741 mDNSexport void 742 initialize_dses_with_rrsig_t(dses_with_rrsig_t * const _Nonnull ds, const response_type_t type); 743 744 mDNSexport void 745 uninitialize_dses_with_rrsig_t(dses_with_rrsig_t * const _Nonnull ds); 746 747 mDNSexport mDNSBool 748 contains_rrsig_in_dses_with_rrsig_t(const dses_with_rrsig_t * const _Nonnull ds); 749 750 mDNSexport void 751 print_dses_with_rrsig_t(const dses_with_rrsig_t * const _Nonnull ds, mDNSu8 num_of_tabs); 752 753 #pragma mark - dses_with_rrsig_t functions 754 755 mDNSexport void 756 initialize_dnskeys_with_rrsig_t(dnskeys_with_rrsig_t * const _Nonnull dnskey); 757 758 mDNSexport void 759 uninitialize_dnskeys_with_rrsig_t(dnskeys_with_rrsig_t * const _Nonnull dnskey); 760 761 mDNSexport mDNSBool 762 contains_rrsig_in_dnskeys_with_rrsig_t(const dnskeys_with_rrsig_t * const _Nonnull dnskey); 763 764 mDNSexport void 765 print_dnskeys_with_rrsig_t(const dnskeys_with_rrsig_t * const _Nonnull dnskey, mDNSu8 num_of_tabs); 766 767 mDNSexport void 768 print_original_request_parameters_t(const original_request_parameters_t * const _Nonnull parameters, mDNSu8 num_of_tabs); 769 770 #pragma mark - dnssec_zone_t functions 771 772 mDNSexport void 773 initialize_dnssec_zone_t( 774 dnssec_zone_t * const _Nonnull zone, 775 const mDNSu8 * const _Nonnull domain_name); 776 777 mDNSexport void 778 uninitialize_dnssec_zone_t(dnssec_zone_t * const _Nonnull zone); 779 780 mDNSexport void 781 stop_and_clean_dnssec_zone_t(dnssec_zone_t * const _Nonnull zone); 782 783 mDNSexport void 784 print_dnssec_zone_t(const dnssec_zone_t * const _Nonnull zone, mDNSu8 num_of_tabs); 785 786 #pragma mark - returned_answers_t 787 788 mDNSexport void 789 initialize_returned_answers_t( 790 returned_answers_t * const _Nonnull returned_answers, 791 const dnssec_result_t dnssec_result, 792 const DNSServiceErrorType error); 793 794 mDNSexport void 795 uninitialize_returned_answers_t(returned_answers_t * const _Nonnull returned_answers); 796 797 mDNSexport void 798 print_returned_answers_t(const returned_answers_t * const _Nonnull returned_answers, mDNSu8 num_of_tabs); 799 800 #endif // MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 801 #endif // DNSSEC_v2_STRUCTS_H 802