]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/dnssec_v2/dnssec_v2_structs.h
mDNSResponder-1310.80.1.tar.gz
[apple/mdnsresponder.git] / mDNSMacOSX / dnssec_v2 / dnssec_v2_structs.h
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