1 //
2 //	dnssec_v2_structs.c
3 //	mDNSResponder
4 //
5 //	Copyright (c) 2020 Apple Inc. All rights reserved.
6 //
7 
8 #include "mDNSEmbeddedAPI.h"
9 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2)
10 #include <string.h>					// for strerror
11 #include <errno.h>					// for errno
12 #include "DNSCommon.h"
13 #include "dnssec_v2_helper.h"
14 #include "dnssec_v2_structs.h"
15 #include "dnssec_v2_log.h"
16 #include "dnssec_v2_validation.h"
17 #include "dnssec_v2_trust_anchor.h"
18 #include "base_n.h"
19 
20 //======================================================================================================================
21 //	Local functions
22 //======================================================================================================================
23 
24 mDNSlocal char *
25 type_bit_map_to_cstring(
26 	const mDNSu8 * const _Nonnull	bit_map,
27 	const mDNSu16					map_length,
28 	char *							buffer,
29 	mDNSu32							buffer_length);
30 
31 //======================================================================================================================
32 //	functions
33 //======================================================================================================================
34 
35 //======================================================================================================================
36 //	dns_type_*_t parse functions
37 //======================================================================================================================
38 
39 mDNSexport void
parsse_dns_type_cname_t(const void * const _Nonnull rdata,mDNSu8 * _Nullable * const _Nonnull out_cname)40 parsse_dns_type_cname_t(const void * const _Nonnull rdata, mDNSu8 * _Nullable * const _Nonnull out_cname) {
41 	// rdata != mDNSNULL
42 	dns_type_cname_t *cname_struct = (dns_type_cname_t *)rdata;
43 
44 	if (out_cname != mDNSNULL) *out_cname = cname_struct->cname;
45 }
46 
47 mDNSexport mDNSBool
parse_dns_type_ds_t(const void * const _Nonnull rdata,const mDNSu16 rdata_length,mDNSu16 * const _Nullable out_key_tag,mDNSu8 * const _Nullable out_algorithm,mDNSu8 * const _Nullable out_digest_type,mDNSu16 * const _Nullable out_digest_length,const mDNSu8 * _Nonnull * const _Nullable out_digest)48 parse_dns_type_ds_t(
49 	const void * const	_Nonnull	rdata,
50 	const mDNSu16					rdata_length,
51 	mDNSu16 * const		_Nullable	out_key_tag,
52 	mDNSu8 * const		_Nullable	out_algorithm,
53 	mDNSu8 * const		_Nullable	out_digest_type,
54 	mDNSu16 * const		_Nullable	out_digest_length,
55 	const mDNSu8 * _Nonnull * const _Nullable	out_digest) {
56 
57 	mDNSBool is_valid = mDNSfalse;
58 	dns_type_ds_t *ds = (dns_type_ds_t *)rdata;
59 
60 	require_action_quiet(rdata_length > offsetof(dns_type_ds_t, digest), exit, is_valid = mDNSfalse;
61 		log_debug("DS record parsing failed because of incorrect rdata length - rdata length: %u", rdata_length));
62 
63 	if (out_key_tag != mDNSNULL)		*out_key_tag		= ntohs(ds->key_tag);
64 	if (out_algorithm != mDNSNULL)		*out_algorithm		= ds->algorithm;
65 	if (out_digest_type != mDNSNULL)	*out_digest_type	= ds->digest_type;
66 	if (out_digest != mDNSNULL)			*out_digest			= ds->digest;
67 	if (out_digest_length != mDNSNULL)	*out_digest_length	= rdata_length - offsetof(dns_type_ds_t, digest);
68 
69 	is_valid = mDNStrue;
70 exit:
71 	return is_valid;
72 }
73 
74 mDNSexport mDNSBool
parse_dns_type_dnskey_t(const void * const _Nonnull rdata,const mDNSu16 rdata_length,mDNSu16 * const _Nullable out_flags,mDNSu8 * const _Nullable out_protocol,mDNSu8 * const _Nullable out_algorithm,mDNSu16 * const _Nullable out_public_key_length,mDNSu8 * _Nonnull * const _Nullable out_public_key)75 parse_dns_type_dnskey_t(
76 	const void * const	_Nonnull	rdata,
77 	const mDNSu16					rdata_length,
78 	mDNSu16 * const		_Nullable	out_flags,
79 	mDNSu8 * const		_Nullable	out_protocol,
80 	mDNSu8 * const		_Nullable	out_algorithm,
81 	mDNSu16 * const		_Nullable	out_public_key_length,
82 	mDNSu8 * _Nonnull * const _Nullable out_public_key) {
83 
84 	mDNSBool is_valid = mDNSfalse;
85 	dns_type_dnskey_t *dnskey = (dns_type_dnskey_t *)rdata;
86 	require_action_quiet(rdata_length > offsetof(dns_type_dnskey_t, public_key), exit, is_valid = mDNSfalse;
87 		log_debug("DNSKEY record parsing failed because of incorrect rdata length - rdata length: %u", rdata_length));
88 
89 	if (out_flags != mDNSNULL)				*out_flags				= ntohs(dnskey->flags);
90 	if (out_protocol != mDNSNULL)			*out_protocol			= dnskey->protocol;
91 	if (out_algorithm != mDNSNULL)			*out_algorithm			= dnskey->algorithm;
92 	if (out_public_key != mDNSNULL)			*out_public_key			= dnskey->public_key;
93 	if (out_public_key_length != mDNSNULL)	*out_public_key_length	= rdata_length - offsetof(dns_type_dnskey_t, public_key);
94 
95 	is_valid = mDNStrue;
96 exit:
97 	return is_valid;
98 }
99 
100 mDNSexport mDNSBool
parse_dns_type_rrsig_t(const void * const _Nonnull rdata,const mDNSu16 rdata_length,mDNSu16 * const _Nullable out_type_covered,mDNSu8 * const _Nullable out_algorithm,mDNSu8 * const _Nullable out_labels,mDNSu32 * const _Nullable out_original_ttl,mDNSu32 * const _Nullable out_signature_expiration,mDNSu32 * const _Nullable out_signature_inception,mDNSu16 * const _Nullable out_key_tag,mDNSu16 * const _Nullable out_signature_length,mDNSu8 * _Nonnull * const _Nullable out_signer_name,mDNSu8 * _Nonnull * const _Nullable out_signature)101 parse_dns_type_rrsig_t(
102 	const void * const	_Nonnull	rdata,
103 	const mDNSu16					rdata_length,
104 	mDNSu16 * const		_Nullable	out_type_covered,
105 	mDNSu8 * const		_Nullable	out_algorithm,
106 	mDNSu8 * const		_Nullable	out_labels,
107 	mDNSu32 * const		_Nullable	out_original_ttl,
108 	mDNSu32 * const		_Nullable	out_signature_expiration,
109 	mDNSu32 * const		_Nullable	out_signature_inception,
110 	mDNSu16 * const		_Nullable	out_key_tag,
111 	mDNSu16 * const		_Nullable	out_signature_length,
112 	mDNSu8 * _Nonnull * const _Nullable out_signer_name,
113 	mDNSu8 * _Nonnull * const _Nullable out_signature) {
114 
115 	mDNSBool 			is_valid 			= mDNSfalse;
116 	dns_type_rrsig_t *	rrsig				= (dns_type_rrsig_t *)rdata;
117 	mDNSu16				signer_name_length	= DomainNameLengthLimit((const domainname *)rrsig->signer_name, rdata + rdata_length);
118 	require_action_quiet(signer_name_length != MAX_DOMAIN_NAME + 1, exit, is_valid = mDNSfalse;
119 		log_debug("RRSIG record parsing failed, because the signer name length goes out of RRSIG rdata"));
120 	require_action_quiet(rdata_length > offsetof(dns_type_rrsig_t, signer_name) + signer_name_length, exit,
121 		is_valid = mDNSfalse;
122 		log_debug("RRSIG record parsing failed because of incorrect rdata length - rdata length: %u", rdata_length));
123 
124 	if (out_type_covered != mDNSNULL)			*out_type_covered			= ntohs(rrsig->type_covered);
125 	if (out_algorithm != mDNSNULL)				*out_algorithm				= rrsig->algorithm;
126 	if (out_labels != mDNSNULL)					*out_labels					= rrsig->labels;
127 	if (out_original_ttl != mDNSNULL)			*out_original_ttl			= ntohl(rrsig->original_TTL);
128 	if (out_signature_expiration != mDNSNULL)	*out_signature_expiration	= ntohl(rrsig->signature_expiration);
129 	if (out_signature_inception != mDNSNULL)	*out_signature_inception	= ntohl(rrsig->signature_inception);
130 	if (out_key_tag != mDNSNULL)				*out_key_tag				= ntohs(rrsig->key_tag);
131 	if (out_signer_name != mDNSNULL)			*out_signer_name			= rrsig->signer_name;
132 	if (out_signature != mDNSNULL)				*out_signature				= (mDNSu8 * const)rdata + offsetof(dns_type_rrsig_t, signer_name) + signer_name_length;
133 	if (out_signature_length != mDNSNULL)		*out_signature_length		= rdata_length - offsetof(dns_type_rrsig_t, signer_name) - signer_name_length;
134 
135 	is_valid = mDNStrue;
136 exit:
137 	return is_valid;
138 }
139 
140 mDNSexport mDNSBool
parse_dns_type_nsec_t(const void * const _Nonnull rdata,const mDNSu16 rdata_length,mDNSu16 * const _Nonnull out_type_bit_maps_length,mDNSu8 * _Nonnull * const _Nullable out_next_domain_name,mDNSu8 * _Nonnull * const _Nullable out_type_bit_maps)141 parse_dns_type_nsec_t(
142 	const void * const	_Nonnull	rdata,
143 	const mDNSu16					rdata_length,
144 	mDNSu16 * const		_Nonnull	out_type_bit_maps_length,
145 	mDNSu8 * _Nonnull * const _Nullable out_next_domain_name,
146 	mDNSu8 * _Nonnull * const _Nullable out_type_bit_maps) {
147 
148 	mDNSBool is_valid 				= mDNSfalse;
149 	dns_type_nsec_t *nsec			= (dns_type_nsec_t *)rdata;
150 	mDNSu16 next_domain_name_length = DomainNameLengthLimit((const domainname *)nsec->next_domain_name, rdata + rdata_length);
151 	require_action_quiet(next_domain_name_length != MAX_DOMAIN_NAME + 1 && rdata_length > next_domain_name_length, exit,
152 		is_valid = mDNSfalse;
153 		log_debug("NSEC record parsing failed because of incorrect rdata length - rdata length: %u", rdata_length));
154 
155 	if (out_next_domain_name != mDNSNULL)		*out_next_domain_name		= nsec->next_domain_name;
156 	if (out_type_bit_maps != mDNSNULL)			*out_type_bit_maps			= (mDNSu8 *)rdata + next_domain_name_length;
157 	if (out_type_bit_maps_length != mDNSNULL)	*out_type_bit_maps_length	= rdata_length - next_domain_name_length;
158 
159 	is_valid = mDNStrue;
160 exit:
161 	return is_valid;
162 }
163 
164 mDNSexport mDNSBool
parse_dns_type_nsec3_t(const void * const _Nonnull rdata,const mDNSu16 rdata_length,mDNSu8 * const _Nullable out_hash_algorithm,mDNSu8 * const _Nullable out_flags,mDNSu16 * const _Nullable out_iterations,mDNSu8 * const _Nullable out_salt_length,mDNSu8 * const _Nullable out_hash_length,mDNSu16 * const _Nullable out_type_bit_maps_length,mDNSu8 * _Nonnull * const _Nullable out_salt,mDNSu8 * _Nonnull * const _Nullable out_next_hashed_owner_name,mDNSu8 * _Nonnull * const _Nullable out_type_bit_maps)165 parse_dns_type_nsec3_t(
166 	const void * const	_Nonnull	rdata,
167 	const mDNSu16					rdata_length,
168 	mDNSu8 * const		_Nullable	out_hash_algorithm,
169 	mDNSu8 * const		_Nullable	out_flags,
170 	mDNSu16 * const		_Nullable	out_iterations,
171 	mDNSu8 * const		_Nullable	out_salt_length,
172 	mDNSu8 * const		_Nullable	out_hash_length,
173 	mDNSu16 * const		_Nullable	out_type_bit_maps_length,
174 	mDNSu8 * _Nonnull * const _Nullable out_salt,
175 	mDNSu8 * _Nonnull * const _Nullable out_next_hashed_owner_name,
176 	mDNSu8 * _Nonnull * const _Nullable out_type_bit_maps) {
177 
178 	mDNSBool is_valid = mDNSfalse;
179 
180 	dns_type_nsec3_t *nsec3 = (dns_type_nsec3_t *)rdata;
181 
182 	if (out_hash_algorithm != mDNSNULL)			*out_hash_algorithm			= nsec3->hash_algorithm;
183 	if (out_flags != mDNSNULL)					*out_flags					= nsec3->flags;
184 	if (out_iterations != mDNSNULL)				*out_iterations				= ntohs(nsec3->iterations);
185 	if (out_salt_length != mDNSNULL)			*out_salt_length			= nsec3->salt_length;
186 	if (out_salt != mDNSNULL)					*out_salt					= nsec3->salt;
187 	require_action_quiet(rdata_length > offsetof(dns_type_nsec3_t, salt) + nsec3->salt_length, exit, is_valid = mDNSfalse);
188 	if (out_hash_length != mDNSNULL)			*out_hash_length			= *((mDNSu8 *)rdata + offsetof(dns_type_nsec3_t, salt) + nsec3->salt_length);
189 	require_action_quiet(rdata_length > offsetof(dns_type_nsec3_t, salt) + nsec3->salt_length + *out_hash_length + 1, exit, is_valid = mDNSfalse);
190 	if (out_next_hashed_owner_name != mDNSNULL) *out_next_hashed_owner_name = (mDNSu8 *)rdata + offsetof(dns_type_nsec3_t, salt) + nsec3->salt_length + 1;
191 	if (out_type_bit_maps_length != mDNSNULL)	*out_type_bit_maps_length	= rdata_length - (offsetof(dns_type_nsec3_t, salt) + nsec3->salt_length + *out_hash_length + 1);
192 	if (out_type_bit_maps != mDNSNULL)			*out_type_bit_maps			= (mDNSu8 *)rdata + offsetof(dns_type_nsec3_t, salt) + nsec3->salt_length + *out_hash_length + 1;
193 
194 	is_valid = mDNStrue;
195 exit:
196 	if (!is_valid) {
197 		log_debug("NSEC3 record parsing failed because of incorrect rdata length - rdata length: %u", rdata_length);
198 	}
199 	return is_valid;
200 }
201 
202 mDNSexport mDNSu16
get_covered_type_of_dns_type_rrsig_t(const void * const _Nonnull rdata)203 get_covered_type_of_dns_type_rrsig_t(const void * const _Nonnull rdata) {
204 	mDNSu16 type_covered = ntohs(((dns_type_rrsig_t *)rdata)->type_covered);
205 	return type_covered;
206 }
207 
208 //======================================================================================================================
209 //	dnssec_rr_t parse functions
210 //======================================================================================================================
211 
212 //======================================================================================================================
213 //	initialize_dnssec_rr_t
214 //======================================================================================================================
215 
216 mDNSexport void
initialize_dnssec_rr_t(dnssec_rr_t * const _Nonnull dnssec_rr,ResourceRecord * const _Nonnull rr)217 initialize_dnssec_rr_t(dnssec_rr_t * const _Nonnull dnssec_rr, ResourceRecord * const _Nonnull rr) {
218 	dnssec_rr->rr_type		= rr->rrtype;
219 	dnssec_rr->rr_class		= rr->rrclass;
220 	dnssec_rr->rdata_length = rr->rdlength;
221 	dnssec_rr->name_hash	= rr->namehash;
222 	dnssec_rr->rdata_hash	= rr->rdatahash;
223 
224 	memcpy(dnssec_rr->name.c, rr->name->c, DomainNameLength(rr->name));
225 
226 	dnssec_rr->rdata = rr->rdata->u.data;
227 	dnssec_rr->rr = rr;
228 }
229 
230 //======================================================================================================================
231 //	unintialize_dnssec_rr_t
232 //======================================================================================================================
233 
234 mDNSexport void
uninitialize_dnssec_rr_t(dnssec_rr_t * const _Nonnull dnssec_rr)235 uninitialize_dnssec_rr_t(dnssec_rr_t * const _Nonnull dnssec_rr) {
236 	(void)dnssec_rr;
237 }
238 
239 //======================================================================================================================
240 //	equal_dnssec_rr_t
241 //======================================================================================================================
242 
243 mDNSexport mDNSBool
equal_dnssec_rr_t(const dnssec_rr_t * const _Nonnull left,const dnssec_rr_t * const _Nonnull right)244 equal_dnssec_rr_t(const dnssec_rr_t * const _Nonnull left, const dnssec_rr_t * const _Nonnull right) {
245 	return resource_records_equal(left->rr_type, right->rr_type, left->rr_class, right->rr_class,
246 				left->rdata_length, right->rdata_length, left->name_hash, right->name_hash, left->rdata_hash, right->rdata_hash,
247 				left->name.c, right->name.c, left->rdata, right->rdata);
248 }
249 
250 //======================================================================================================================
251 //	print_dnssec_rr_t
252 //======================================================================================================================
253 
254 mDNSexport void
print_dnssec_rr_t(const dnssec_rr_t * const _Nonnull dnssec_rr,mDNSu8 num_of_tabs)255 print_dnssec_rr_t(const dnssec_rr_t * const _Nonnull dnssec_rr, mDNSu8 num_of_tabs) {
256 	char *	rdata_base64	= mDNSNULL;
257 
258 	log_debug(TAB_STR PRI_DM_NAME " " PUB_S ":", TAB_PARAM(num_of_tabs),
259 		DM_NAME_PARAM(&dnssec_rr->name), DNS_TYPE_STR(dnssec_rr->rr_type));
260 
261 	num_of_tabs += 1;
262 	rdata_base64 = base_n_encode(DNSSEC_BASE_64, dnssec_rr->rdata, dnssec_rr->rdata_length);
263 
264 	log_debug(TAB_STR "Name Hash: %u, Rdata Hash: %u, Rdata Length: %u, Rdata: " BASE64_STR, TAB_PARAM(num_of_tabs),
265 		dnssec_rr->name_hash, dnssec_rr->rdata_hash, dnssec_rr->rdata_length, BASE64_PARAM(rdata_base64));
266 
267 	free(rdata_base64);
268 }
269 
270 //======================================================================================================================
271 //	dnssec_original_t functions
272 //======================================================================================================================
273 
274 //======================================================================================================================
275 //	initialize_dnssec_original_t
276 //======================================================================================================================
277 
278 mDNSexport void
initialize_dnssec_original_t(dnssec_original_t * const _Nonnull original,ResourceRecord * const _Nonnull rr,const mDNSBool answer_from_cache,const DNSServiceErrorType dns_error,const QC_result qc_result)279 initialize_dnssec_original_t(
280 	dnssec_original_t * const		_Nonnull	original,
281 	ResourceRecord * const			_Nonnull	rr,
282 	const mDNSBool								answer_from_cache,
283 	const DNSServiceErrorType					dns_error,
284 	const QC_result								qc_result) {
285 
286 	initialize_dnssec_rr_t(&original->dnssec_rr, rr);
287 
288 	original->answer_from_cache = answer_from_cache;
289 	original->dns_error			= dns_error;
290 	original->qc_result			= qc_result;
291 }
292 
293 //======================================================================================================================
294 //	uninitialize_dnssec_original_t
295 //======================================================================================================================
296 
297 mDNSexport void
uninitialize_dnssec_original_t(dnssec_original_t * const _Nonnull original)298 uninitialize_dnssec_original_t(dnssec_original_t * const _Nonnull original) {
299 	uninitialize_dnssec_rr_t(&original->dnssec_rr);
300 }
301 
302 //======================================================================================================================
303 //	print_dnssec_original_t
304 //======================================================================================================================
305 
306 mDNSexport void
print_dnssec_original_t(const dnssec_original_t * const _Nonnull original,mDNSu8 num_of_tabs)307 print_dnssec_original_t(const dnssec_original_t * const _Nonnull original, mDNSu8 num_of_tabs) {
308 	log_debug(TAB_STR PUB_S
309 		"DNS Error: " PUB_S
310 		", QC Result: %u",
311 		TAB_PARAM(num_of_tabs),
312 		original->answer_from_cache ? "Answer from cache, " : "",
313 		mStatusDescription(original->dns_error),
314 		original->qc_result);
315 
316 	print_dnssec_rr_t(&original->dnssec_rr, num_of_tabs);
317 }
318 
319 //======================================================================================================================
320 //	dnssec_ds_t functions
321 //======================================================================================================================
322 
323 //======================================================================================================================
324 //	initialize_dnssec_cname_t
325 //======================================================================================================================
326 
327 mDNSexport void
initialize_dnssec_cname_t(dnssec_cname_t * const _Nonnull cname,ResourceRecord * const _Nonnull rr)328 initialize_dnssec_cname_t(dnssec_cname_t * const _Nonnull cname, ResourceRecord * const _Nonnull rr) {
329 	initialize_dnssec_rr_t(&cname->dnssec_rr, rr);
330 	parsse_dns_type_cname_t(rr->rdata->u.data, &cname->cname);
331 }
332 
333 //======================================================================================================================
334 //	uninitialize_dnssec_cname_t
335 //======================================================================================================================
336 
337 mDNSexport void
uninitialize_dnssec_cname_t(dnssec_cname_t * const _Nonnull cname)338 uninitialize_dnssec_cname_t(dnssec_cname_t * const _Nonnull cname) {
339 	uninitialize_dnssec_rr_t(&cname->dnssec_rr);
340 }
341 
342 //======================================================================================================================
343 //	print_dnssec_cname_t
344 //======================================================================================================================
345 
346 mDNSexport void
print_dnssec_cname_t(const dnssec_cname_t * const _Nonnull cname,mDNSu8 num_of_tabs)347 print_dnssec_cname_t(const dnssec_cname_t * const _Nonnull cname, mDNSu8 num_of_tabs) {
348 	log_debug(TAB_STR "CNAME: " PRI_DM_NAME, TAB_PARAM(num_of_tabs), DM_NAME_PARAM((domainname *)cname->cname));
349 }
350 
351 //======================================================================================================================
352 //	dnssec_ds_t functions
353 //======================================================================================================================
354 
355 //======================================================================================================================
356 //	initialize_dnssec_ds_t
357 //======================================================================================================================
358 
359 mDNSexport mDNSBool
initialize_dnssec_ds_t(dnssec_ds_t * const _Nonnull ds,ResourceRecord * const _Nonnull rr)360 initialize_dnssec_ds_t(dnssec_ds_t * const _Nonnull ds, ResourceRecord * const _Nonnull rr) {
361 	mDNSBool is_valid = mDNSfalse;
362 
363 	initialize_dnssec_rr_t(&ds->dnssec_rr, rr);
364 	is_valid = parse_dns_type_ds_t(ds->dnssec_rr.rdata, ds->dnssec_rr.rdata_length, &ds->key_tag, &ds->algorithm, &ds->digest_type,
365 		&ds->digest_length, &ds->digest);
366 
367 	return is_valid;
368 }
369 
370 //======================================================================================================================
371 //	initialize_dnssec_ds_t
372 //======================================================================================================================
373 mDNSexport mDNSBool
equals_dnssec_ds_t(const dnssec_ds_t * const left,const dnssec_ds_t * const right)374 equals_dnssec_ds_t(const dnssec_ds_t * const left, const dnssec_ds_t * const right) {
375 	if (left->key_tag		!= right->key_tag)			return mDNSfalse;
376 	if (left->algorithm		!= right->algorithm)		return mDNSfalse;
377 	if (left->digest_type	!= right->digest_type)		return mDNSfalse;
378 	if (left->digest_length != right->digest_length)	return mDNSfalse;
379 	if (memcmp(left->digest, right->digest, left->digest_length) != 0) return mDNSfalse;
380 
381 	return mDNStrue;
382 }
383 
384 //======================================================================================================================
385 //	uninitialize_dnssec_ds_t
386 //======================================================================================================================
387 
388 mDNSexport void
uninitialize_dnssec_ds_t(dnssec_ds_t * const _Nonnull ds)389 uninitialize_dnssec_ds_t(dnssec_ds_t * const _Nonnull ds) {
390 	uninitialize_dnssec_rr_t(&ds->dnssec_rr);
391 }
392 
393 //======================================================================================================================
394 //	print_dnssec_ds_t
395 //======================================================================================================================
396 
397 mDNSexport void
print_dnssec_ds_t(const dnssec_ds_t * const _Nonnull ds,mDNSu8 num_of_tabs)398 print_dnssec_ds_t(const dnssec_ds_t * const _Nonnull ds, mDNSu8 num_of_tabs) {
399 	char *digest_base64 = base_n_encode(DNSSEC_BASE_64, ds->digest, ds->digest_length);
400 
401 	log_debug(TAB_STR "Key Tag: %u, Algorithm: " PUB_S ", Digest Type: " PUB_S ", Digest Length: %u, Digest: " BASE64_STR, TAB_PARAM(num_of_tabs),
402 		ds->key_tag,
403 		dnssec_algorithm_value_to_string(ds->algorithm),
404 		dnssec_digest_type_value_to_string(ds->digest_type),
405 		ds->digest_length,
406 		BASE64_PARAM(digest_base64));
407 
408 	free(digest_base64);
409 }
410 
411 //======================================================================================================================
412 //	dnssec_dnskey_t functions
413 //======================================================================================================================
414 
415 //======================================================================================================================
416 //	initialize_dnssec_dnskey_t
417 //======================================================================================================================
418 
419 mDNSexport mDNSBool
initialize_dnssec_dnskey_t(dnssec_dnskey_t * const _Nonnull dnskey,ResourceRecord * const _Nonnull rr)420 initialize_dnssec_dnskey_t(dnssec_dnskey_t * const _Nonnull dnskey, ResourceRecord * const _Nonnull rr) {
421 	mDNSBool is_valid = mDNSfalse;
422 
423 	initialize_dnssec_rr_t(&dnskey->dnssec_rr, rr);
424 
425 	is_valid = parse_dns_type_dnskey_t(dnskey->dnssec_rr.rdata, dnskey->dnssec_rr.rdata_length, &dnskey->flags,
426 		&dnskey->protocol, &dnskey->algorithm, &dnskey->public_key_length, &dnskey->public_key);
427 	require_quiet(is_valid, exit);
428 
429 	dnskey->key_tag = calculate_key_tag(dnskey->dnssec_rr.rdata, dnskey->dnssec_rr.rdata_length, dnskey->algorithm);
430 
431 	is_valid = mDNStrue;
432 exit:
433 	return is_valid;
434 }
435 
436 //======================================================================================================================
437 //	uninitialize_dnssec_dnskey_t
438 //======================================================================================================================
439 
440 mDNSexport void
uninitialize_dnssec_dnskey_t(dnssec_dnskey_t * const _Nonnull dnskey)441 uninitialize_dnssec_dnskey_t(dnssec_dnskey_t * const _Nonnull dnskey) {
442 	uninitialize_dnssec_rr_t(&dnskey->dnssec_rr);
443 }
444 
445 //======================================================================================================================
446 //	uninitialize_dnssec_dnskey_t
447 //======================================================================================================================
448 
449 mDNSexport mDNSBool
equals_dnssec_dnskey_t(const dnssec_dnskey_t * const left,const dnssec_dnskey_t * const right)450 equals_dnssec_dnskey_t(const dnssec_dnskey_t * const left, const dnssec_dnskey_t * const right) {
451 	if (left->flags				!= right->flags)				return mDNSfalse;
452 	if (left->protocol			!= right->protocol)				return mDNSfalse;
453 	if (left->algorithm			!= right->algorithm)			return mDNSfalse;
454 	if (left->key_tag			!= right->key_tag)				return mDNSfalse;
455 	if (left->public_key_length != right->public_key_length)	return mDNSfalse;
456 	if (memcmp(left->public_key, right->public_key, left->public_key_length) != 0)	return mDNSfalse;
457 
458 	return mDNStrue;
459 }
460 
461 //======================================================================================================================
462 //	print_dnssec_dnskey_t
463 //======================================================================================================================
464 
465 mDNSexport void
print_dnssec_dnskey_t(const dnssec_dnskey_t * const _Nonnull dnskey,mDNSu8 num_of_tabs)466 print_dnssec_dnskey_t(const dnssec_dnskey_t * const _Nonnull dnskey, mDNSu8 num_of_tabs) {
467 	char *public_key_base64 = base_n_encode(DNSSEC_BASE_64, dnskey->public_key, dnskey->public_key_length);
468 	char flags_string[64]; // 64 is big enough to hold all flags
469 
470 	log_debug(TAB_STR "Flags: " PUB_S ", Protocol: %u, Algorithm: " PUB_S ", Ket Tag: %u" ", Public Key Length: %u, Public Key: " BASE64_STR , TAB_PARAM(num_of_tabs),
471 		dnssec_dnskey_flags_to_string(dnskey->flags, flags_string, sizeof(flags_string)), dnskey->protocol,
472 		dnssec_algorithm_value_to_string(dnskey->algorithm), dnskey->key_tag, dnskey->public_key_length, BASE64_PARAM(public_key_base64));
473 
474 	free(public_key_base64);
475 }
476 
477 //======================================================================================================================
478 //	dnssec_rrsig_t functions
479 //======================================================================================================================
480 
481 //======================================================================================================================
482 //	initialize_dnssec_rrsig_t
483 //======================================================================================================================
484 
485 mDNSexport mDNSBool
initialize_dnssec_rrsig_t(dnssec_rrsig_t * const _Nonnull rrsig,ResourceRecord * const _Nonnull rr)486 initialize_dnssec_rrsig_t(dnssec_rrsig_t * const _Nonnull rrsig, ResourceRecord * const _Nonnull rr) {
487 	mDNSBool is_valid = mDNSfalse;
488 
489 	initialize_dnssec_rr_t(&rrsig->dnssec_rr, rr);
490 	is_valid = parse_dns_type_rrsig_t(rrsig->dnssec_rr.rdata, rrsig->dnssec_rr.rdata_length, &rrsig->type_covered,
491 		&rrsig->algorithm, &rrsig->labels, &rrsig->original_TTL, &rrsig->signature_expiration,
492 		&rrsig->signature_inception, &rrsig->key_tag, &rrsig->signature_length, &rrsig->signer_name, &rrsig->signature);
493 
494 	return is_valid;
495 }
496 
497 //======================================================================================================================
498 //	uninitialize_dnssec_rrsig_t
499 //======================================================================================================================
500 
501 mDNSexport void
uninitialize_dnssec_rrsig_t(dnssec_rrsig_t * const _Nonnull rrsig)502 uninitialize_dnssec_rrsig_t(dnssec_rrsig_t * const _Nonnull rrsig) {
503 	// rrsig != mDNSNULL;
504 	uninitialize_dnssec_rr_t(&rrsig->dnssec_rr);
505 }
506 
507 //======================================================================================================================
508 //	print_dnssec_rrsig_t
509 //======================================================================================================================
510 
511 mDNSexport void
print_dnssec_rrsig_t(const dnssec_rrsig_t * const _Nonnull rrsig,mDNSu8 num_of_tabs)512 print_dnssec_rrsig_t(const dnssec_rrsig_t * const _Nonnull rrsig, mDNSu8 num_of_tabs) {
513 	char	expiration_date_string[32]; // 32 is big enough to hold "1970-01-01 00:00:00-0800"
514 	char	inception_date_string[32];
515 	char *	signature_base64 = base_n_encode(DNSSEC_BASE_64, rrsig->signature, rrsig->signature_length);
516 
517 	log_debug(TAB_STR
518 		"Type Covered: " PUB_S
519 		", Algorithm: " PUB_S
520 		", Labels: %u"
521 		", Original TTL: %u"
522 		", Signature Expiration: " PRI_S
523 		", Signature Inception: " PRI_S
524 		", Key Tag: %u"
525 		", Signature Length: %u"
526 		", Signer Name: " PRI_DM_NAME
527 		", Signature: " BASE64_STR,
528 		TAB_PARAM(num_of_tabs),
529 		DNS_TYPE_STR(rrsig->type_covered),
530 		dnssec_algorithm_value_to_string(rrsig->algorithm),
531 		rrsig->labels,
532 		rrsig->original_TTL,
533 		dnssec_epoch_time_to_date_string(rrsig->signature_expiration, expiration_date_string, sizeof(expiration_date_string)),
534 		dnssec_epoch_time_to_date_string(rrsig->signature_inception, inception_date_string, sizeof(inception_date_string)),
535 		rrsig->key_tag,
536 		rrsig->signature_length,
537 		DM_NAME_PARAM((domainname *)rrsig->signer_name),
538 		BASE64_PARAM(signature_base64));
539 
540 	free(signature_base64);
541 }
542 
543 //======================================================================================================================
544 //	dnssec_nsec_t functions
545 //======================================================================================================================
546 
547 //======================================================================================================================
548 //	initialize_dnssec_nsec_t
549 //======================================================================================================================
550 
551 mDNSexport mDNSBool
initialize_dnssec_nsec_t(dnssec_nsec_t * const _Nonnull nsec,ResourceRecord * const _Nonnull rr)552 initialize_dnssec_nsec_t(dnssec_nsec_t * const _Nonnull nsec, ResourceRecord * const _Nonnull rr) {
553 	mDNSBool is_valid = mDNSfalse;
554 
555 	initialize_dnssec_rr_t(&nsec->dnssec_rr, rr);
556 	is_valid = parse_dns_type_nsec_t(nsec->dnssec_rr.rdata, nsec->dnssec_rr.rdata_length, &nsec->type_bit_maps_length, &nsec->next_domain_name, &nsec->type_bit_maps);
557 	require_quiet(is_valid, exit);
558 	nsec->exist_domain_name = nsec->dnssec_rr.name.c;
559 
560 	is_valid = mDNStrue;
561 exit:
562 	return is_valid;
563 }
564 
565 //======================================================================================================================
566 //	uninitialize_dnssec_nsec_t
567 //======================================================================================================================
568 
569 mDNSexport void
uninitialize_dnssec_nsec_t(dnssec_nsec_t * const _Nonnull nsec)570 uninitialize_dnssec_nsec_t(dnssec_nsec_t * const _Nonnull nsec) {
571 	uninitialize_dnssec_rr_t(&nsec->dnssec_rr);
572 }
573 
574 //======================================================================================================================
575 //	print_dnssec_nsec_t
576 //======================================================================================================================
577 
578 mDNSexport void
print_dnssec_nsec_t(const dnssec_nsec_t * const _Nonnull nsec,mDNSu8 num_of_tabs)579 print_dnssec_nsec_t(const dnssec_nsec_t * const _Nonnull nsec, mDNSu8 num_of_tabs) {
580 	char string_buffer[1024];
581 
582 	log_debug(TAB_STR
583 		"Domain Name: " PRI_DM_NAME
584 		", Next Domain Name: " PRI_DM_NAME
585 		", Type Bit Maps Length: %u"
586 		", Type Bit Maps: " PUB_S,
587 		TAB_PARAM(num_of_tabs),
588 		DM_NAME_PARAM((domainname *)nsec->exist_domain_name),
589 		DM_NAME_PARAM((domainname *)nsec->next_domain_name),
590 		nsec->type_bit_maps_length,
591 		type_bit_map_to_cstring(nsec->type_bit_maps, nsec->type_bit_maps_length, string_buffer, sizeof(string_buffer)));
592 }
593 
594 mDNSlocal char *
type_bit_map_to_cstring(const mDNSu8 * const _Nonnull bit_map,const mDNSu16 map_length,char * buffer,mDNSu32 buffer_length)595 type_bit_map_to_cstring(
596 	const mDNSu8 * const _Nonnull	bit_map,
597 	const mDNSu16					map_length,
598 	char *							buffer,
599 	mDNSu32							buffer_length) {
600 
601 	const mDNSu8 *			ptr						= bit_map;
602 	const mDNSu8 * const	ptr_limit				= ptr + map_length;
603 	char *					buffer_ptr				= buffer;
604 	const char * const		buffer_limit			= buffer + buffer_length - 4;
605 
606 	for (; ptr < ptr_limit; ptr += 2 + *(ptr + 1)) {
607 		const mDNSu8	window_index			= *ptr;
608 		const mDNSu8	block_bit_map_length	= *(ptr + 1);
609 		const mDNSu32	bit_count				= block_bit_map_length * 8;
610 		const mDNSu8 *	current_block			= ptr + 2;
611 
612 		for (mDNSu32 i = 0; i < bit_count; i++) {
613 			const mDNSu8 mask	= 1 << (7 - (i % 8));
614 			mDNSBool bit_set	= (current_block[i / 8] & mask) != 0;
615 			if (bit_set) {
616 				const char * const dns_type_cstring = DNS_TYPE_STR(window_index * 256 + i);
617 				const mDNSs32 bytes_will_be_written = snprintf(buffer_ptr, buffer_limit - buffer_ptr, "%s ", dns_type_cstring);
618 				if (bytes_will_be_written + buffer_ptr >= buffer_limit) {
619 					snprintf(buffer_ptr, buffer_limit - buffer_ptr + 4, "...");
620 					return buffer;
621 				}
622 				buffer_ptr += bytes_will_be_written;
623 			}
624 		}
625 	}
626 
627 	return buffer;
628 }
629 
630 //======================================================================================================================
631 //	dnssec_nsec3_t functions
632 //======================================================================================================================
633 
634 //======================================================================================================================
635 //	initialize_dnssec_nsec3_t
636 //======================================================================================================================
637 
638 mDNSexport mDNSBool
initialize_dnssec_nsec3_t(dnssec_nsec3_t * const _Nonnull nsec3,ResourceRecord * const _Nonnull rr)639 initialize_dnssec_nsec3_t(dnssec_nsec3_t * const _Nonnull nsec3, ResourceRecord * const _Nonnull rr) {
640 	mDNSBool is_valid = mDNSfalse;
641 
642 	initialize_dnssec_rr_t(&nsec3->dnssec_rr, rr);
643 	is_valid = parse_dns_type_nsec3_t(nsec3->dnssec_rr.rdata, nsec3->dnssec_rr.rdata_length, &nsec3->hash_algorithm, &nsec3->flags, &nsec3->iterations,
644 		&nsec3->salt_length, &nsec3->hash_length, &nsec3->type_bit_maps_length, &nsec3->salt,
645 		&nsec3->next_hashed_owner_name, &nsec3->type_bit_maps);
646 	require_action_quiet(is_valid, exit, is_valid = mDNSfalse);
647 
648 	nsec3->next_hashed_owner_name_b32 = base_n_encode(DNSSEC_BASE_32_HEX, nsec3->next_hashed_owner_name, nsec3->hash_length);
649 	nsec3->next_hashed_owner_name_b32_length = strlen(nsec3->next_hashed_owner_name_b32);
650 
651 	is_valid = mDNStrue;
652 exit:
653 	return is_valid;
654 }
655 
656 //======================================================================================================================
657 //	uninitialize_dnssec_nsec3_t
658 //======================================================================================================================
659 
660 mDNSexport void
uninitialize_dnssec_nsec3_t(dnssec_nsec3_t * const _Nonnull nsec3)661 uninitialize_dnssec_nsec3_t(dnssec_nsec3_t * const _Nonnull nsec3) {
662 	uninitialize_dnssec_rr_t(&nsec3->dnssec_rr);
663 	free(nsec3->next_hashed_owner_name_b32);
664 }
665 
666 //======================================================================================================================
667 //	print_dnssec_nsec3_t
668 //======================================================================================================================
669 
670 mDNSexport void
print_dnssec_nsec3_t(const dnssec_nsec3_t * const _Nonnull nsec3,mDNSu8 num_of_tabs)671 print_dnssec_nsec3_t(const dnssec_nsec3_t * const _Nonnull nsec3, mDNSu8 num_of_tabs) {
672 	char	flags_string[32]; // 32 is big enough to hold the flag string
673 	char *	salt_base64 = base_n_encode(DNSSEC_BASE_64, nsec3->salt, nsec3->salt_length);
674 	char	string_buffer[1024];
675 
676 	log_debug(TAB_STR
677 		"Hash Algorithm: " PUB_S
678 		", Flags: " PUB_S
679 		", Iterations: %u"
680 		", Salt Length: %u"
681 		", Hash Length: %u"
682 		", Type Bit Maps Length: %u"
683 		", Salt: " BASE64_STR
684 		", Next Hash Owner Name: " PRI_S
685 		", Type Bit Maps: " PUB_S,
686 		TAB_PARAM(num_of_tabs),
687 		dnssec_algorithm_value_to_string(nsec3->hash_algorithm),
688 		dnssec_nsec3_flags_to_string(nsec3->flags, flags_string, sizeof(flags_string)),
689 		nsec3->iterations,
690 		nsec3->salt_length,
691 		nsec3->hash_length,
692 		nsec3->type_bit_maps_length,
693 		BASE64_PARAM(salt_base64),
694 		nsec3->next_hashed_owner_name_b32,
695 		type_bit_map_to_cstring(nsec3->type_bit_maps, nsec3->type_bit_maps_length, string_buffer, sizeof(string_buffer)));
696 
697 	free(salt_base64);
698 }
699 
700 //======================================================================================================================
701 //	nsecs_with_rrsig_t functions
702 //======================================================================================================================
703 
704 //======================================================================================================================
705 //	initialize_nsecs_with_rrsig_t
706 //======================================================================================================================
707 
708 mDNSexport mStatus
initialize_nsecs_with_rrsig_t(nsecs_with_rrsig_t * const _Nonnull nsecs)709 initialize_nsecs_with_rrsig_t(nsecs_with_rrsig_t * const _Nonnull nsecs) {
710 	list_init(&nsecs->nsec_and_rrsigs_same_name, sizeof(one_nsec_with_rrsigs_t));
711 	list_init(&nsecs->wildcard_answers, sizeof(dnssec_rr_t));
712 	list_init(&nsecs->wildcard_rrsigs, sizeof(dnssec_rrsig_t));
713 	nsecs->negative_rr = mDNSNULL;
714 
715 	return mStatus_NoError;
716 }
717 
718 //======================================================================================================================
719 //	uninitialize_nsecs_with_rrsig_t
720 //======================================================================================================================
721 
722 mDNSexport void
uninitialize_nsecs_with_rrsig_t(nsecs_with_rrsig_t * const _Nonnull nsecs)723 uninitialize_nsecs_with_rrsig_t(nsecs_with_rrsig_t * const _Nonnull nsecs) {
724 	for (list_node_t * one_nsec_with_rrsigs_node = list_get_first(&nsecs->nsec_and_rrsigs_same_name);
725 		 !list_has_ended(&nsecs->nsec_and_rrsigs_same_name, one_nsec_with_rrsigs_node);
726 		 one_nsec_with_rrsigs_node = list_next(one_nsec_with_rrsigs_node)) {
727 
728 		one_nsec_with_rrsigs_t * one_nsec_with_rrsigs = (one_nsec_with_rrsigs_t *)one_nsec_with_rrsigs_node->data;
729 		uninitialize_one_nsec_with_rrsigs_t(one_nsec_with_rrsigs);
730 	}
731 	list_uninit(&nsecs->nsec_and_rrsigs_same_name);
732 	for (list_node_t * dnssec_rr_node = list_get_first(&nsecs->wildcard_answers);
733 		 !list_has_ended(&nsecs->wildcard_answers, dnssec_rr_node);
734 		 dnssec_rr_node = list_next(dnssec_rr_node)) {
735 
736 		dnssec_rr_t * dnssec_rr = (dnssec_rr_t *)dnssec_rr_node->data;
737 		uninitialize_dnssec_rr_t(dnssec_rr);
738 	}
739 	list_uninit(&nsecs->wildcard_answers);
740 	for (list_node_t * dnssec_rrsig_node = list_get_first(&nsecs->wildcard_rrsigs);
741 		 !list_has_ended(&nsecs->wildcard_rrsigs, dnssec_rrsig_node);
742 		 dnssec_rrsig_node = list_next(dnssec_rrsig_node)) {
743 
744 		dnssec_rrsig_t * dnssec_rrsig = (dnssec_rrsig_t *)dnssec_rrsig_node->data;
745 		uninitialize_dnssec_rrsig_t(dnssec_rrsig);
746 	}
747 	list_uninit(&nsecs->wildcard_rrsigs);
748 	nsecs->negative_rr = mDNSNULL;
749 }
750 
751 //======================================================================================================================
752 //	print_nsecs_with_rrsig_t
753 //======================================================================================================================
754 
755 mDNSexport void
print_nsecs_with_rrsig_t(const nsecs_with_rrsig_t * const _Nonnull nsecs,mDNSu8 num_of_tabs)756 print_nsecs_with_rrsig_t(const nsecs_with_rrsig_t * const _Nonnull nsecs, mDNSu8 num_of_tabs) {
757 
758 	const list_t * list_ptr;
759 
760 	list_ptr = &nsecs->wildcard_answers;
761 	log_debug(TAB_STR "Wildcard:", TAB_PARAM(num_of_tabs));
762 	for (list_node_t *node = list_get_first(list_ptr); !list_has_ended(list_ptr, node); node = list_next(node)) {
763 		const dnssec_rr_t * const dnssec_rr = (dnssec_rr_t *) node->data;
764 		print_dnssec_rr_t(dnssec_rr, num_of_tabs + 1);
765 	}
766 
767 	list_ptr = &nsecs->wildcard_rrsigs;
768 	log_debug(TAB_STR "RRSIG:", TAB_PARAM(num_of_tabs));
769 	for (list_node_t *node = list_get_first(list_ptr); !list_has_ended(list_ptr, node); node = list_next(node)) {
770 		const dnssec_rrsig_t * const dnssec_rrsig = (dnssec_rrsig_t *) node->data;
771 		print_dnssec_rrsig_t(dnssec_rrsig, num_of_tabs + 1);
772 	}
773 
774 	list_ptr = &nsecs->nsec_and_rrsigs_same_name;
775 	for (list_node_t *node = list_get_first(list_ptr); !list_has_ended(list_ptr, node); node = list_next(node)) {
776 		const one_nsec_with_rrsigs_t * const one_nsec = (const one_nsec_with_rrsigs_t * const)node->data;
777 		log_debug(TAB_STR "Owner Name:" PRI_DM_NAME, TAB_PARAM(num_of_tabs), DM_NAME_PARAM((const domainname *)one_nsec->owner_name));
778 
779 		log_debug(TAB_STR "NSEC:", TAB_PARAM(num_of_tabs));
780 		print_dnssec_nsec_t(&one_nsec->nsec_record, num_of_tabs + 1);
781 
782 		log_debug(TAB_STR "RRSIG:", TAB_PARAM(num_of_tabs));
783 		for (list_node_t *rrsig_node = list_get_first(&one_nsec->rrsig_records);
784 			 !list_has_ended(&one_nsec->rrsig_records, rrsig_node);
785 			 rrsig_node = list_next(rrsig_node)) {
786 			const dnssec_rrsig_t * const rrsig = (const dnssec_rrsig_t * const)rrsig_node->data;
787 			print_dnssec_rrsig_t(rrsig, num_of_tabs + 1);
788 		}
789 	}
790 }
791 
792 # pragma mark - one_nsec_with_rrsigs_t functions
793 
794 
795 
796 # pragma mark initialize_one_nsec_with_rrsigs_t
797 mDNSexport mDNSBool
initialize_one_nsec_with_rrsigs_t(one_nsec_with_rrsigs_t * const one_nsec_with_rrsigs,ResourceRecord * const rr)798 initialize_one_nsec_with_rrsigs_t(one_nsec_with_rrsigs_t * const one_nsec_with_rrsigs, ResourceRecord * const rr) {
799 	mDNSBool is_valid = mDNSfalse;
800 
801 	is_valid = initialize_dnssec_nsec_t(&one_nsec_with_rrsigs->nsec_record, rr);
802 	require_quiet(is_valid, exit);
803 	one_nsec_with_rrsigs->owner_name = one_nsec_with_rrsigs->nsec_record.dnssec_rr.name.c;
804 	list_init(&one_nsec_with_rrsigs->rrsig_records, sizeof(dnssec_rrsig_t));
805 
806 	is_valid = mDNStrue;
807 exit:
808 	return is_valid;
809 }
810 
811 # pragma mark uninitialize_one_nsec_with_rrsigs_t
812 mDNSexport void
uninitialize_one_nsec_with_rrsigs_t(one_nsec_with_rrsigs_t * const _Nonnull one_nsec_with_rrsigs)813 uninitialize_one_nsec_with_rrsigs_t(one_nsec_with_rrsigs_t * const	_Nonnull one_nsec_with_rrsigs) {
814 	for (list_node_t * dnssec_rrsig_node = list_get_first(&one_nsec_with_rrsigs->rrsig_records);
815 		 !list_has_ended(&one_nsec_with_rrsigs->rrsig_records, dnssec_rrsig_node);
816 		 dnssec_rrsig_node = list_next(dnssec_rrsig_node)) {
817 
818 		dnssec_rrsig_t * dnssec_rrsig = (dnssec_rrsig_t *)dnssec_rrsig_node->data;
819 		uninitialize_dnssec_rrsig_t(dnssec_rrsig);
820 	}
821 	list_uninit(&one_nsec_with_rrsigs->rrsig_records);
822 	uninitialize_dnssec_nsec_t(&one_nsec_with_rrsigs->nsec_record);
823 }
824 //======================================================================================================================
825 //	nsec3s_with_rrsig_t functions
826 //======================================================================================================================
827 
828 //======================================================================================================================
829 //	initialize_nsec3s_with_rrsig_t
830 //======================================================================================================================
831 
832 mDNSexport mStatus
initialize_nsec3s_with_rrsig_t(nsec3s_with_rrsig_t * const _Nonnull nsec3s)833 initialize_nsec3s_with_rrsig_t(nsec3s_with_rrsig_t * const _Nonnull nsec3s) {
834 	list_init(&nsec3s->nsec3_and_rrsigs_same_name, sizeof(one_nsec3_with_rrsigs_t));
835 	list_init(&nsec3s->wildcard_answers, sizeof(dnssec_rr_t));
836 	list_init(&nsec3s->wildcard_rrsigs, sizeof(dnssec_rrsig_t));
837 	nsec3s->negative_rr = mDNSNULL;
838 
839 	return mStatus_NoError;
840 }
841 
842 //======================================================================================================================
843 //	uninitialize_nsec3s_with_rrsig_t
844 //======================================================================================================================
845 
846 mDNSexport void
uninitialize_nsec3s_with_rrsig_t(nsec3s_with_rrsig_t * const _Nonnull nsec3s)847 uninitialize_nsec3s_with_rrsig_t(nsec3s_with_rrsig_t * const _Nonnull nsec3s) {
848 	for (list_node_t * one_nsec3_with_rrsigs_node = list_get_first(&nsec3s->nsec3_and_rrsigs_same_name);
849 		 !list_has_ended(&nsec3s->nsec3_and_rrsigs_same_name, one_nsec3_with_rrsigs_node);
850 		 one_nsec3_with_rrsigs_node = list_next(one_nsec3_with_rrsigs_node)) {
851 
852 		one_nsec3_with_rrsigs_t * one_nsec3_with_rrsigs = (one_nsec3_with_rrsigs_t *)one_nsec3_with_rrsigs_node->data;
853 		uninitialize_one_nsec3_with_rrsigs_t(one_nsec3_with_rrsigs);
854 	}
855 	list_uninit(&nsec3s->nsec3_and_rrsigs_same_name);
856 	for (list_node_t * dnssec_rr_node = list_get_first(&nsec3s->wildcard_answers);
857 		 !list_has_ended(&nsec3s->wildcard_answers, dnssec_rr_node);
858 		 dnssec_rr_node = list_next(dnssec_rr_node)) {
859 
860 		dnssec_rr_t * dnssec_rr = (dnssec_rr_t *)dnssec_rr_node->data;
861 		uninitialize_dnssec_rr_t(dnssec_rr);
862 	}
863 	list_uninit(&nsec3s->wildcard_answers);
864 	for (list_node_t * dnssec_rrsig_node = list_get_first(&nsec3s->wildcard_rrsigs);
865 		 !list_has_ended(&nsec3s->wildcard_rrsigs, dnssec_rrsig_node);
866 		 dnssec_rrsig_node = list_next(dnssec_rrsig_node)) {
867 
868 		dnssec_rrsig_t * dnssec_rrsig = (dnssec_rrsig_t *)dnssec_rrsig_node->data;
869 		uninitialize_dnssec_rrsig_t(dnssec_rrsig);
870 	}
871 	list_uninit(&nsec3s->wildcard_rrsigs);
872 	nsec3s->negative_rr = mDNSNULL;
873 }
874 
875 //======================================================================================================================
876 //	print_nsec3s_with_rrsig_t
877 //======================================================================================================================
878 
879 mDNSexport void
print_nsec3s_with_rrsig_t(const nsec3s_with_rrsig_t * const _Nonnull nsec3s,mDNSu8 num_of_tabs)880 print_nsec3s_with_rrsig_t(const nsec3s_with_rrsig_t * const _Nonnull nsec3s, mDNSu8 num_of_tabs) {
881 	const list_t * list_ptr;
882 
883 	list_ptr = &nsec3s->wildcard_answers;
884 	log_debug(TAB_STR "Wildcard:", TAB_PARAM(num_of_tabs));
885 	for (list_node_t *node = list_get_first(list_ptr); !list_has_ended(list_ptr, node); node = list_next(node)) {
886 		const dnssec_rr_t * const dnssec_rr = (dnssec_rr_t *) node->data;
887 		print_dnssec_rr_t(dnssec_rr, num_of_tabs + 1);
888 	}
889 
890 	list_ptr = &nsec3s->wildcard_rrsigs;
891 	log_debug(TAB_STR "RRSIG:", TAB_PARAM(num_of_tabs));
892 	for (list_node_t *node = list_get_first(list_ptr); !list_has_ended(list_ptr, node); node = list_next(node)) {
893 		const dnssec_rrsig_t * const dnssec_rrsig = (dnssec_rrsig_t *) node->data;
894 		print_dnssec_rrsig_t(dnssec_rrsig, num_of_tabs + 1);
895 	}
896 
897 	list_ptr = &nsec3s->nsec3_and_rrsigs_same_name;
898 	for (list_node_t *node = list_get_first(list_ptr); !list_has_ended(list_ptr, node); node = list_next(node)) {
899 		const one_nsec3_with_rrsigs_t * const one_nsec3 = (const one_nsec3_with_rrsigs_t * const)node->data;
900 		log_debug(TAB_STR "Owner Name:" PRI_DM_NAME, TAB_PARAM(num_of_tabs), DM_NAME_PARAM((const domainname *)one_nsec3->owner_name));
901 
902 		log_debug(TAB_STR "NSEC3:", TAB_PARAM(num_of_tabs));
903 		print_dnssec_nsec3_t(&one_nsec3->nsec3_record, num_of_tabs + 1);
904 
905 		log_debug(TAB_STR "RRSIG:", TAB_PARAM(num_of_tabs));
906 		for (list_node_t *rrsig_node = list_get_first(&one_nsec3->rrsig_records);
907 			 !list_has_ended(&one_nsec3->rrsig_records, rrsig_node);
908 			 rrsig_node = list_next(rrsig_node)) {
909 			const dnssec_rrsig_t * const rrsig = (const dnssec_rrsig_t * const)rrsig_node->data;
910 			print_dnssec_rrsig_t(rrsig, num_of_tabs + 1);
911 		}
912 	}
913 }
914 
915 # pragma mark - one_nsec_with_rrsigs_t functions
916 
917 
918 
919 # pragma mark initialize_one_nsec3_with_rrsigs_t
920 mDNSexport mDNSBool
initialize_one_nsec3_with_rrsigs_t(one_nsec3_with_rrsigs_t * const _Nonnull one_nsec3_with_rrsigs,ResourceRecord * const _Nonnull rr)921 initialize_one_nsec3_with_rrsigs_t(
922 	one_nsec3_with_rrsigs_t * const _Nonnull	one_nsec3_with_rrsigs,
923 	ResourceRecord * const 			_Nonnull	rr) {
924 
925 	mDNSBool is_valid = mDNSfalse;
926 
927 	is_valid = initialize_dnssec_nsec3_t(&one_nsec3_with_rrsigs->nsec3_record, rr);
928 	require_action_quiet(is_valid, exit, is_valid = mDNSfalse);
929 	one_nsec3_with_rrsigs->owner_name = one_nsec3_with_rrsigs->nsec3_record.dnssec_rr.name.c;
930 	list_init(&one_nsec3_with_rrsigs->rrsig_records, sizeof(dnssec_rrsig_t));
931 
932 	is_valid = mDNStrue;
933 exit:
934 	return is_valid;
935 }
936 
937 # pragma mark uninitialize_one_nsec3_with_rrsigs_t
938 mDNSexport void
uninitialize_one_nsec3_with_rrsigs_t(one_nsec3_with_rrsigs_t * const _Nonnull one_nsec3_with_rrsigs)939 uninitialize_one_nsec3_with_rrsigs_t(one_nsec3_with_rrsigs_t * const _Nonnull one_nsec3_with_rrsigs) {
940 	for (list_node_t * dnssec_rrsig_node = list_get_first(&one_nsec3_with_rrsigs->rrsig_records);
941 		 !list_has_ended(&one_nsec3_with_rrsigs->rrsig_records, dnssec_rrsig_node);
942 		 dnssec_rrsig_node = list_next(dnssec_rrsig_node)) {
943 
944 		dnssec_rrsig_t * dnssec_rrsig = (dnssec_rrsig_t *)dnssec_rrsig_node->data;
945 		uninitialize_dnssec_rrsig_t(dnssec_rrsig);
946 	}
947 	list_uninit(&one_nsec3_with_rrsigs->rrsig_records);
948 	uninitialize_dnssec_nsec3_t(&one_nsec3_with_rrsigs->nsec3_record);
949 }
950 
951 //======================================================================================================================
952 //	cnames_with_rrsig_t functions
953 //======================================================================================================================
954 
955 //======================================================================================================================
956 //	initialize_cname_with_rrsig_t
957 //======================================================================================================================
958 
959 mDNSexport void
initialize_cname_with_rrsig_t(cnames_with_rrsig_t * const _Nonnull cname)960 initialize_cname_with_rrsig_t(cnames_with_rrsig_t * const _Nonnull cname) {
961 	list_init(&cname->cname_records, sizeof(dnssec_cname_t));
962 	list_init(&cname->rrsig_records, sizeof(dnssec_rrsig_t));
963 }
964 
965 //======================================================================================================================
966 //	uninitialize_cname_with_rrsig_t
967 //======================================================================================================================
968 
969 mDNSexport void
uninitialize_cname_with_rrsig_t(cnames_with_rrsig_t * const _Nonnull cname)970 uninitialize_cname_with_rrsig_t(cnames_with_rrsig_t * const _Nonnull cname) {
971 	for (list_node_t * dnssec_cname_node = list_get_first(&cname->cname_records);
972 		 !list_has_ended(&cname->cname_records, dnssec_cname_node);
973 		 dnssec_cname_node = list_next(dnssec_cname_node)) {
974 
975 		dnssec_cname_t * dnssec_cname = (dnssec_cname_t *)dnssec_cname_node->data;
976 		uninitialize_dnssec_cname_t(dnssec_cname);
977 	}
978 	list_uninit(&cname->cname_records);
979 	for (list_node_t *dnssec_rrsig_node = list_get_first(&cname->rrsig_records);
980 		 !list_has_ended(&cname->rrsig_records, dnssec_rrsig_node);
981 		 dnssec_rrsig_node = list_next(dnssec_rrsig_node)) {
982 
983 		dnssec_rrsig_t * dnssec_rrsig = (dnssec_rrsig_t *)dnssec_rrsig_node->data;
984 		uninitialize_dnssec_rrsig_t(dnssec_rrsig);
985 	}
986 	list_uninit(&cname->rrsig_records);
987 }
988 
989 //======================================================================================================================
990 //	print_cname_with_rrsig_t
991 //======================================================================================================================
992 
993 mDNSexport void
print_cname_with_rrsig_t(const cnames_with_rrsig_t * const _Nonnull cnames,mDNSu8 num_of_tabs)994 print_cname_with_rrsig_t(const cnames_with_rrsig_t * const _Nonnull cnames, mDNSu8 num_of_tabs) {
995 	const list_t * const cname_records = &cnames->cname_records;
996 	const list_t * const rrsig_records = &cnames->rrsig_records;
997 
998 
999 	log_debug(TAB_STR "CNAME:", TAB_PARAM(num_of_tabs));
1000 	for (list_node_t *node = list_get_first(cname_records); !list_has_ended(cname_records, node); node = list_next(node)) {
1001 		dnssec_cname_t *cname = (dnssec_cname_t *)node->data;
1002 		print_dnssec_cname_t(cname, num_of_tabs + 1);
1003 	}
1004 
1005 	log_debug(TAB_STR "RRSIG:", TAB_PARAM(num_of_tabs));
1006 	for (list_node_t *node = list_get_first(rrsig_records); !list_has_ended(rrsig_records, node); node = list_next(node)) {
1007 		dnssec_rrsig_t *rrsig = (dnssec_rrsig_t *)node->data;
1008 		print_dnssec_rrsig_t(rrsig, num_of_tabs + 1);
1009 	}
1010 }
1011 
1012 //======================================================================================================================
1013 //	response_type_t functions
1014 //======================================================================================================================
1015 
1016 mDNSexport const char * _Nonnull
response_type_value_to_string(response_type_t type)1017 response_type_value_to_string(response_type_t type) {
1018 	static const char * const string_table[] =
1019 	{
1020 		"Unknown Response",		// 0
1021 		"Original Response",	// 1
1022 		"CNAME Response",		// 2
1023 		"NSEC Response",		// 3
1024 		"NSEC3 Response"		// 4
1025 	};
1026 	if (type >= sizeof(string_table) / sizeof(char *)) {
1027 		type = 0;
1028 	}
1029 
1030 	return string_table[type];
1031 }
1032 
1033 //======================================================================================================================
1034 //	originals_with_rrsig_t functions
1035 //======================================================================================================================
1036 
1037 //======================================================================================================================
1038 //	initialize_originals_with_rrsig_t
1039 //======================================================================================================================
1040 
1041 mDNSexport void
initialize_originals_with_rrsig_t(originals_with_rrsig_t * const _Nonnull original,const response_type_t type)1042 initialize_originals_with_rrsig_t(originals_with_rrsig_t * const _Nonnull original, const response_type_t type) {
1043 	original->type			= type;
1044 
1045 	switch (type) {
1046 		case original_response:
1047 			list_init(&original->u.original.original_records, sizeof(dnssec_original_t));
1048 			list_init(&original->u.original.rrsig_records, sizeof(dnssec_rrsig_t));
1049 			original->u.original.negative_rr = mDNSNULL;
1050 			original->u.original.suppressed_response = mDNSfalse;
1051 			break;
1052 		case cname_response:
1053 			initialize_cname_with_rrsig_t(&original->u.cname_with_rrsig);
1054 			break;
1055 		case nsec_response:
1056 			initialize_nsecs_with_rrsig_t(&original->u.nsecs_with_rrsig);
1057 			break;
1058 		case nsec3_response:
1059 			initialize_nsec3s_with_rrsig_t(&original->u.nsec3s_with_rrsig);
1060 			break;
1061 		default:
1062 			verify(mDNSfalse);
1063 	}
1064 }
1065 
1066 //======================================================================================================================
1067 //	uninitialize_originals_with_rrsig_t
1068 //======================================================================================================================
1069 
1070 mDNSexport void
uninitialize_originals_with_rrsig_t(originals_with_rrsig_t * const _Nonnull original)1071 uninitialize_originals_with_rrsig_t(originals_with_rrsig_t * const _Nonnull original) {
1072 	switch (original->type) {
1073 		case original_response:
1074 			for (list_node_t * dnssec_original_node = list_get_first(&original->u.original.original_records);
1075 				 !list_has_ended(&original->u.original.original_records, dnssec_original_node);
1076 				 dnssec_original_node = list_next(dnssec_original_node)) {
1077 
1078 				dnssec_original_t * dnssec_original = (dnssec_original_t *)dnssec_original_node->data;
1079 				uninitialize_dnssec_original_t(dnssec_original);
1080 			}
1081 			list_uninit(&original->u.original.original_records);
1082 			for (list_node_t * dnssec_rrsig_node = list_get_first(&original->u.original.rrsig_records);
1083 				 !list_has_ended(&original->u.original.rrsig_records, dnssec_rrsig_node);
1084 				 dnssec_rrsig_node = list_next(dnssec_rrsig_node)) {
1085 
1086 				dnssec_rrsig_t * dnssec_rrsig = (dnssec_rrsig_t *)dnssec_rrsig_node->data;
1087 				uninitialize_dnssec_rrsig_t(dnssec_rrsig);
1088 			}
1089 			list_uninit(&original->u.original.rrsig_records);
1090 			original->u.original.negative_rr			= mDNSNULL;
1091 			original->u.original.suppressed_response	= mDNSfalse;
1092 			break;
1093 		case cname_response:
1094 			uninitialize_cname_with_rrsig_t(&original->u.cname_with_rrsig);
1095 			break;
1096 		case nsec_response:
1097 			uninitialize_nsecs_with_rrsig_t(&original->u.nsecs_with_rrsig);
1098 			break;
1099 		case nsec3_response:
1100 			uninitialize_nsec3s_with_rrsig_t(&original->u.nsec3s_with_rrsig);
1101 			break;
1102 		default:
1103 			// it is possible that the DNSSEC rquest is stopped we receive any response
1104 			break;
1105 	}
1106 	original->type			= unknown_response;
1107 }
1108 
1109 //======================================================================================================================
1110 //	contains_rrsig_in_nsecs_with_rrsig_t
1111 //======================================================================================================================
1112 
1113 mDNSlocal mDNSBool
contains_rrsig_in_nsecs_with_rrsig_t(const nsecs_with_rrsig_t * const _Nonnull nsecs)1114 contains_rrsig_in_nsecs_with_rrsig_t(const nsecs_with_rrsig_t * const _Nonnull nsecs) {
1115 	const list_t * const nsec_list = &nsecs->nsec_and_rrsigs_same_name;
1116 	mDNSBool contains_non_empty_rrsig_list = mDNSfalse;
1117 	for (list_node_t *nsec_node = list_get_first(nsec_list);
1118 		 !list_has_ended(nsec_list, nsec_node);
1119 		 nsec_node = list_next(nsec_node)) {
1120 		const one_nsec_with_rrsigs_t * const	one_nsec	= (const one_nsec_with_rrsigs_t * const)nsec_node->data;
1121 		const list_t * const					rrsig_list	= &one_nsec->rrsig_records;
1122 		if (!list_empty(rrsig_list)) {
1123 			contains_non_empty_rrsig_list = mDNStrue;
1124 			break;
1125 		}
1126 	}
1127 	if (!contains_non_empty_rrsig_list) {
1128 		return mDNSfalse;
1129 	}
1130 
1131 	return mDNStrue;
1132 }
1133 
1134 //======================================================================================================================
1135 //	contains_rrsig_in_nsecs_with_rrsig_t
1136 //======================================================================================================================
1137 
1138 mDNSlocal mDNSBool
contains_rrsig_in_nsec3s_with_rrsig_t(const nsec3s_with_rrsig_t * const _Nonnull nsec3s)1139 contains_rrsig_in_nsec3s_with_rrsig_t(const nsec3s_with_rrsig_t * const _Nonnull nsec3s) {
1140 	const list_t * const nsec3_list = &nsec3s->nsec3_and_rrsigs_same_name;
1141 	mDNSBool contains_non_empty_rrsig_list = mDNSfalse;
1142 	for (list_node_t *nsec3_node = list_get_first(nsec3_list);
1143 		 !list_has_ended(nsec3_list, nsec3_node);
1144 		 nsec3_node = list_next(nsec3_node)) {
1145 		const one_nsec3_with_rrsigs_t * const	one_nsec3	= (const one_nsec3_with_rrsigs_t * const)nsec3_node->data;
1146 		const list_t * const					rrsig_list	= &one_nsec3->rrsig_records;
1147 		if (!list_empty(rrsig_list)) {
1148 			contains_non_empty_rrsig_list = mDNStrue;
1149 			break;
1150 		}
1151 	}
1152 	if (!contains_non_empty_rrsig_list) {
1153 		return mDNSfalse;
1154 	}
1155 
1156 	return mDNStrue;
1157 }
1158 
1159 //======================================================================================================================
1160 //	contains_rrsig_in_originals_with_rrsig_t
1161 //======================================================================================================================
1162 
1163 mDNSexport mDNSBool
contains_rrsig_in_originals_with_rrsig_t(const originals_with_rrsig_t * const _Nonnull original)1164 contains_rrsig_in_originals_with_rrsig_t(const originals_with_rrsig_t * const _Nonnull original) {
1165 	const list_t *rrsig_list;
1166 	const response_type_t type = original->type;
1167 
1168 	if (type == original_response || type == cname_response) {
1169 		if (type == original_response) {
1170 			rrsig_list = &original->u.original.rrsig_records;
1171 		} else { // type == cname_response
1172 			rrsig_list = &original->u.cname_with_rrsig.rrsig_records;
1173 		}
1174 
1175 		if (rrsig_list == mDNSNULL) {
1176 			log_error("originals_with_rrsig_t has unknown response, it should never heppen");
1177 			return mDNSfalse;
1178 		}
1179 
1180 		if (list_empty(rrsig_list)) {
1181 			return mDNSfalse;
1182 		}
1183 	} else if (type == nsec_response) {
1184 		if (!contains_rrsig_in_nsecs_with_rrsig_t(&original->u.nsecs_with_rrsig)) {
1185 			return mDNSfalse;
1186 		}
1187 	} else if (type == nsec3_response) {
1188 		if (!contains_rrsig_in_nsec3s_with_rrsig_t(&original->u.nsec3s_with_rrsig)) {
1189 			return mDNStrue;
1190 		}
1191 	} else {
1192 		log_error("originals_with_rrsig_t has unknown response, it should never heppen");
1193 		return mDNSfalse;
1194 	}
1195 
1196 	return mDNStrue;
1197 }
1198 
1199 //======================================================================================================================
1200 //	print_originals_with_rrsig_t
1201 //======================================================================================================================
1202 
1203 mDNSexport void
print_originals_with_rrsig_t(const originals_with_rrsig_t * const _Nonnull original,mDNSu8 num_of_tabs)1204 print_originals_with_rrsig_t(const originals_with_rrsig_t * const _Nonnull original, mDNSu8 num_of_tabs) {
1205 	log_debug(TAB_STR "Response Type: " PUB_S, TAB_PARAM(num_of_tabs),
1206 			  response_type_value_to_string(original->type));
1207 
1208 	switch (original->type) {
1209 		case original_response: {
1210 			const list_t * const original_records	= &original->u.original.original_records;
1211 			const list_t * const rrsig_records		= &original->u.original.rrsig_records;
1212 
1213 			log_debug(TAB_STR "Original:", TAB_PARAM(num_of_tabs));
1214 			for (list_node_t *node = list_get_first(original_records); !list_has_ended(original_records, node); node = list_next(node)) {
1215 				dnssec_original_t *dnssec_original = (dnssec_original_t *)node->data;
1216 				print_dnssec_original_t(dnssec_original, num_of_tabs + 1);
1217 			}
1218 
1219 			log_debug(TAB_STR "RRSIG:", TAB_PARAM(num_of_tabs));
1220 			for (list_node_t *node = list_get_first(rrsig_records); !list_has_ended(rrsig_records, node); node = list_next(node)) {
1221 				dnssec_rrsig_t *dnssec_rrsig = (dnssec_rrsig_t *)node->data;
1222 				print_dnssec_rrsig_t(dnssec_rrsig, num_of_tabs + 1);
1223 			}
1224 		}
1225 			break;
1226 		case cname_response:
1227 			print_cname_with_rrsig_t(&original->u.cname_with_rrsig, num_of_tabs + 1);
1228 			break;
1229 		case nsec_response:
1230 			print_nsecs_with_rrsig_t(&original->u.nsecs_with_rrsig, num_of_tabs + 1);
1231 			break;
1232 		case nsec3_response:
1233 			print_nsec3s_with_rrsig_t(&original->u.nsec3s_with_rrsig, num_of_tabs + 1);
1234 			break;
1235 		case unknown_response:
1236 			log_debug(TAB_STR "Unknown Response", TAB_PARAM(num_of_tabs));
1237 			break;
1238 		default:
1239 			log_debug(TAB_STR "Invalid", TAB_PARAM(num_of_tabs));
1240 			break;
1241 	}
1242 }
1243 
1244 //======================================================================================================================
1245 //	dses_with_rrsig_t functions
1246 //======================================================================================================================
1247 
1248 //======================================================================================================================
1249 //	initialize_dses_with_rrsig_t
1250 //======================================================================================================================
1251 
1252 mDNSexport void
initialize_dses_with_rrsig_t(dses_with_rrsig_t * const _Nonnull ds,const response_type_t type)1253 initialize_dses_with_rrsig_t(dses_with_rrsig_t * const _Nonnull ds, const response_type_t type) {
1254 	ds->type			= type;
1255 	ds->set_completed	= mDNSfalse;
1256 
1257 	switch (type) {
1258 		case original_response:
1259 			list_init(&ds->u.original.ds_records, sizeof(dnssec_ds_t));
1260 			list_init(&ds->u.original.rrsig_records, sizeof(dnssec_rrsig_t));
1261 			break;
1262 		case nsec_response:
1263 			initialize_nsecs_with_rrsig_t(&ds->u.nsecs_with_rrsig);
1264 			break;
1265 		case nsec3_response:
1266 			initialize_nsec3s_with_rrsig_t(&ds->u.nsec3s_with_rrsig);
1267 			break;
1268 		default:
1269 			break;
1270 	}
1271 }
1272 
1273 //======================================================================================================================
1274 //	uninitialize_dses_with_rrsig_t
1275 //======================================================================================================================
1276 
1277 mDNSexport void
uninitialize_dses_with_rrsig_t(dses_with_rrsig_t * const _Nonnull ds)1278 uninitialize_dses_with_rrsig_t(dses_with_rrsig_t * const _Nonnull ds) {
1279 	switch (ds->type) {
1280 		case original_response: {
1281 			list_t * ds_records 	= &ds->u.original.ds_records;
1282 			list_t * rrsig_records	= &ds->u.original.rrsig_records;
1283 			for (list_node_t * dnssec_ds_node = list_get_first(ds_records);
1284 				 !list_has_ended(ds_records, dnssec_ds_node);
1285 				 dnssec_ds_node = list_next(dnssec_ds_node)) {
1286 
1287 				dnssec_ds_t * dnssec_ds = (dnssec_ds_t *)dnssec_ds_node->data;
1288 				uninitialize_dnssec_ds_t(dnssec_ds);
1289 			}
1290 			list_uninit(ds_records);
1291 			for (list_node_t * dnssec_rrsig_node = list_get_first(rrsig_records);
1292 				 !list_has_ended(rrsig_records, dnssec_rrsig_node);
1293 				 dnssec_rrsig_node = list_next(dnssec_rrsig_node)) {
1294 
1295 				dnssec_rrsig_t * dnssec_rrsig = (dnssec_rrsig_t *)dnssec_rrsig_node->data;
1296 				uninitialize_dnssec_rrsig_t(dnssec_rrsig);
1297 			}
1298 			list_uninit(rrsig_records);
1299 			break;
1300 		}
1301 		case nsec_response:
1302 			uninitialize_nsecs_with_rrsig_t(&ds->u.nsecs_with_rrsig);
1303 			break;
1304 		case nsec3_response:
1305 			uninitialize_nsec3s_with_rrsig_t(&ds->u.nsec3s_with_rrsig);
1306 			break;
1307 		default:
1308 			break;
1309 	}
1310 
1311 	ds->type			= unknown_response;
1312 	ds->set_completed	= mDNSfalse;
1313 }
1314 
1315 //======================================================================================================================
1316 //	contains_rrsig_in_dses_with_rrsig_t
1317 //======================================================================================================================
1318 
1319 mDNSexport mDNSBool
contains_rrsig_in_dses_with_rrsig_t(const dses_with_rrsig_t * const _Nonnull ds)1320 contains_rrsig_in_dses_with_rrsig_t(const dses_with_rrsig_t * const _Nonnull ds) {
1321 	const response_type_t type = ds->type;
1322 	mDNSBool contains = mDNStrue;
1323 
1324 	if (!ds->set_completed) {
1325 		log_error("contains_rrsig_in_dses_with_rrsig_t called with incompleted ds records set");
1326 		contains = mDNSfalse;
1327 		goto exit;
1328 	}
1329 
1330 	if (type == original_response) {
1331 		if (list_empty(&ds->u.original.rrsig_records)) {
1332 			contains = mDNSfalse;
1333 			goto exit;
1334 		}
1335 	} else if (type == nsec_response) {
1336 		if (!contains_rrsig_in_nsecs_with_rrsig_t(&ds->u.nsecs_with_rrsig)) {
1337 			contains = mDNSfalse;
1338 			goto exit;
1339 		}
1340 	} else if (type == nsec3_response) {
1341 		if (!contains_rrsig_in_nsec3s_with_rrsig_t(&ds->u.nsec3s_with_rrsig)) {
1342 			contains = mDNSfalse;
1343 			goto exit;
1344 		}
1345 	} else {
1346 		log_error("dses_with_rrsig_t has unknown response, it should never heppen");
1347 		contains = mDNSfalse;
1348 		goto exit;
1349 	}
1350 
1351 exit:
1352 	return contains;
1353 }
1354 
1355 //======================================================================================================================
1356 //	print_dses_with_rrsig_t
1357 //======================================================================================================================
1358 
1359 mDNSexport void
print_dses_with_rrsig_t(const dses_with_rrsig_t * const _Nonnull ds,mDNSu8 num_of_tabs)1360 print_dses_with_rrsig_t(const dses_with_rrsig_t * const _Nonnull ds, mDNSu8 num_of_tabs) {
1361 	log_debug(TAB_STR "Response Type: " PUB_S PUB_S, TAB_PARAM(num_of_tabs),
1362 			  response_type_value_to_string(ds->type), ds->set_completed ? ", Set Completed" : "");
1363 
1364 	switch (ds->type) {
1365 		case original_response: {
1366 			const list_t * const ds_records		= &ds->u.original.ds_records;
1367 			const list_t * const rrsig_records	= &ds->u.original.rrsig_records;
1368 
1369 			log_debug(TAB_STR "DS:", TAB_PARAM(num_of_tabs));
1370 			for (list_node_t *node = list_get_first(ds_records); !list_has_ended(ds_records, node); node = list_next(node)) {
1371 				dnssec_ds_t *dnssec_ds = (dnssec_ds_t *)node->data;
1372 				print_dnssec_ds_t(dnssec_ds, num_of_tabs + 1);
1373 			}
1374 
1375 			log_debug(TAB_STR "RRSIG:", TAB_PARAM(num_of_tabs));
1376 			for (list_node_t *node = list_get_first(rrsig_records); !list_has_ended(rrsig_records, node); node = list_next(node)) {
1377 				dnssec_rrsig_t *dnssec_rrsig = (dnssec_rrsig_t *)node->data;
1378 				print_dnssec_rrsig_t(dnssec_rrsig, num_of_tabs + 1);
1379 			}
1380 		}
1381 			break;
1382 		case nsec_response:
1383 			print_nsecs_with_rrsig_t(&ds->u.nsecs_with_rrsig, num_of_tabs + 1);
1384 			break;
1385 		case nsec3_response:
1386 			print_nsec3s_with_rrsig_t(&ds->u.nsec3s_with_rrsig, num_of_tabs + 1);
1387 			break;
1388 		case unknown_response:
1389 			log_debug(TAB_STR "Unknown Response", TAB_PARAM(num_of_tabs));
1390 			break;
1391 		default:
1392 			log_debug(TAB_STR "Invalid", TAB_PARAM(num_of_tabs));
1393 			break;
1394 	}
1395 }
1396 
1397 //======================================================================================================================
1398 //	dnskeys_with_rrsig_t functions
1399 //======================================================================================================================
1400 
1401 //======================================================================================================================
1402 //	initialize_dnskeys_with_rrsig_t
1403 //======================================================================================================================
1404 
1405 mDNSexport void
initialize_dnskeys_with_rrsig_t(dnskeys_with_rrsig_t * const _Nonnull dnskey)1406 initialize_dnskeys_with_rrsig_t(dnskeys_with_rrsig_t * const _Nonnull dnskey) {
1407 	dnskey->set_completed = mDNSfalse;
1408 
1409 	list_init(&dnskey->dnskey_records, sizeof(dnssec_dnskey_t));
1410 	list_init(&dnskey->rrsig_records, sizeof(dnssec_rrsig_t));
1411 }
1412 
1413 //======================================================================================================================
1414 //	uninitialize_dnskeys_with_rrsig_t
1415 //======================================================================================================================
1416 
1417 mDNSexport void
uninitialize_dnskeys_with_rrsig_t(dnskeys_with_rrsig_t * const _Nonnull dnskey)1418 uninitialize_dnskeys_with_rrsig_t(dnskeys_with_rrsig_t * const _Nonnull dnskey) {
1419 	for (list_node_t * dnssec_dnskey_node = list_get_first(&dnskey->dnskey_records);
1420 		 !list_has_ended(&dnskey->dnskey_records, dnssec_dnskey_node);
1421 		 dnssec_dnskey_node = list_next(dnssec_dnskey_node)) {
1422 
1423 		dnssec_dnskey_t * dnssec_dnskey = (dnssec_dnskey_t *)dnssec_dnskey_node->data;
1424 		uninitialize_dnssec_dnskey_t(dnssec_dnskey);
1425 	}
1426 	list_uninit(&dnskey->dnskey_records);
1427 	for (list_node_t * dnssec_rrsig_node = list_get_first(&dnskey->rrsig_records);
1428 		 !list_has_ended(&dnskey->rrsig_records, dnssec_rrsig_node);
1429 		 dnssec_rrsig_node = list_next(dnssec_rrsig_node)) {
1430 
1431 		dnssec_rrsig_t * dnssec_rrsig = (dnssec_rrsig_t *)dnssec_rrsig_node->data;
1432 		uninitialize_dnssec_rrsig_t(dnssec_rrsig);
1433 	}
1434 	list_uninit(&dnskey->rrsig_records);
1435 	dnskey->set_completed = mDNSfalse;
1436 }
1437 
1438 //======================================================================================================================
1439 //	contains_rrsig_in_dnskeys_with_rrsig_t
1440 //======================================================================================================================
1441 
1442 mDNSexport mDNSBool
contains_rrsig_in_dnskeys_with_rrsig_t(const dnskeys_with_rrsig_t * const _Nonnull dnskey)1443 contains_rrsig_in_dnskeys_with_rrsig_t(const dnskeys_with_rrsig_t * const _Nonnull dnskey) {
1444 	mDNSBool		contains	= mDNSfalse;
1445 
1446 	verify_action(dnskey->set_completed,
1447 		log_error("contains_rrsig_in_dnskeys_with_rrsig_t called with incompleted dnskey records set"); return mDNSfalse);
1448 
1449 	if (list_empty(&dnskey->rrsig_records)) {
1450 		goto exit;
1451 	}
1452 
1453 	contains = mDNStrue;
1454 exit:
1455 	return contains;
1456 }
1457 
1458 //======================================================================================================================
1459 //	print_dnskeys_with_rrsig_t
1460 //======================================================================================================================
1461 
1462 mDNSexport void
print_dnskeys_with_rrsig_t(const dnskeys_with_rrsig_t * const _Nonnull dnskey,mDNSu8 num_of_tabs)1463 print_dnskeys_with_rrsig_t(const dnskeys_with_rrsig_t * const _Nonnull dnskey, mDNSu8 num_of_tabs) {
1464 	log_debug(TAB_STR PUB_S, TAB_PARAM(num_of_tabs),
1465 		dnskey->set_completed ? "Set Completed" : "");
1466 
1467 	const list_t * const dnskey_records	= &dnskey->dnskey_records;
1468 	const list_t * const rrsig_records	= &dnskey->rrsig_records;
1469 
1470 	log_debug(TAB_STR "DNSKEY:", TAB_PARAM(num_of_tabs));
1471 	for (list_node_t *node = list_get_first(dnskey_records); !list_has_ended(dnskey_records, node); node = list_next(node)) {
1472 		dnssec_dnskey_t *dnssec_dnskey = (dnssec_dnskey_t *)node->data;
1473 		print_dnssec_dnskey_t(dnssec_dnskey, num_of_tabs + 1);
1474 	}
1475 
1476 	log_debug(TAB_STR "RRSIG:", TAB_PARAM(num_of_tabs));
1477 	for (list_node_t *node = list_get_first(rrsig_records); !list_has_ended(rrsig_records, node); node = list_next(node)) {
1478 		dnssec_rrsig_t *dnssec_rrsig = (dnssec_rrsig_t *)node->data;
1479 		print_dnssec_rrsig_t(dnssec_rrsig, num_of_tabs + 1);
1480 	}
1481 }
1482 
1483 //======================================================================================================================
1484 //	original_request_parameters_t functions
1485 //======================================================================================================================
1486 
1487 //======================================================================================================================
1488 //	print_original_request_parameters_t
1489 //======================================================================================================================
1490 
1491 mDNSexport void
print_original_request_parameters_t(const original_request_parameters_t * const _Nonnull parameters,mDNSu8 num_of_tabs)1492 print_original_request_parameters_t(const original_request_parameters_t * const _Nonnull parameters, mDNSu8 num_of_tabs) {
1493 	char uuid_hex[UUID_SIZE * 4];
1494 	char *ptr	= uuid_hex;
1495 	char *limit = ptr + sizeof(uuid_hex);
1496 
1497 	for (size_t i = 0 ; i < sizeof(parameters->uuid); i++) {
1498 		mDNSu32 num_of_char_write = snprintf(ptr, limit - ptr, "%x", parameters->uuid[i]);
1499 		if (num_of_char_write + ptr > limit) {
1500 			break;
1501 		}
1502 		ptr += num_of_char_write;
1503 	}
1504 
1505 	log_debug(TAB_STR "Original Parameters:", TAB_PARAM(num_of_tabs));
1506 	log_debug(TAB_STR
1507 		"Rquest ID: %u"
1508 		", Q Name: " PRI_DM_NAME
1509 		", Q Type: " PUB_S
1510 		", Q Class: %u"
1511 		", Interface ID: %p"
1512 		", Service ID: %d"
1513 		", Flags: %#04x"
1514 		PUB_S
1515 		", PID: %d"
1516 		", UUID: " PRI_S
1517 		", UID: %d"
1518 		", Handler: %p"
1519 		", Context: %p",
1520 		TAB_PARAM(num_of_tabs),
1521 		parameters->request_id,
1522 		DM_NAME_PARAM(&parameters->question_name),
1523 		DNS_TYPE_STR(parameters->question_type),
1524 		parameters->question_class,
1525 		parameters->interface_id,
1526 		parameters->service_id,
1527 		parameters->flags,
1528 		parameters->append_search_domains ? "Append Search Domains, " : "",
1529 		parameters->pid,
1530 		uuid_hex,
1531 		parameters->uid,
1532 		parameters->user_handler,
1533 		parameters->user_context);
1534 }
1535 
1536 //======================================================================================================================
1537 //	dnssec_zone_t functions
1538 //======================================================================================================================
1539 
1540 //======================================================================================================================
1541 //	initialize_dnssec_zone_t
1542 //======================================================================================================================
1543 
1544 mDNSexport void
initialize_dnssec_zone_t(dnssec_zone_t * const _Nonnull zone,const mDNSu8 * const _Nonnull domain_name)1545 initialize_dnssec_zone_t(
1546 	dnssec_zone_t * const	_Nonnull	zone,
1547 	const mDNSu8 * const	_Nonnull	domain_name) {
1548 
1549 	memcpy(zone->domain_name.c, domain_name, DOMAIN_NAME_LENGTH(domain_name));
1550 	zone->name_hash = DomainNameHashValue((domainname *)domain_name);
1551 
1552 	bzero(&zone->ds_request,		sizeof(QueryRecordClientRequest));
1553 	bzero(&zone->dnskey_request,	sizeof(QueryRecordClientRequest));
1554 	zone->ds_request_started		= mDNSfalse;
1555 	zone->dses_initialized			= mDNSfalse;
1556 	zone->last_time_ds_add			= INT_MIN;
1557 	zone->last_time_ds_rmv			= INT_MIN;
1558 	zone->dnskey_request_started	= mDNSfalse;
1559 	zone->last_time_dnskey_add		= INT_MIN;
1560 	zone->last_time_dnskey_rmv		= INT_MIN;
1561 	zone->trust_anchor				= get_trust_anchor_with_name(domain_name);
1562 
1563 	initialize_dnskeys_with_rrsig_t(&zone->dnskeys_with_rrsig);
1564 }
1565 
1566 //======================================================================================================================
1567 //	uninitialize_dnssec_zone_t
1568 //======================================================================================================================
1569 
1570 mDNSexport void
uninitialize_dnssec_zone_t(dnssec_zone_t * const _Nonnull zone)1571 uninitialize_dnssec_zone_t(dnssec_zone_t * const _Nonnull zone) {
1572 	if (zone->dses_initialized) {
1573 		uninitialize_dses_with_rrsig_t(&zone->dses_with_rrsig);
1574 	}
1575 	uninitialize_dnskeys_with_rrsig_t(&zone->dnskeys_with_rrsig);
1576 }
1577 
1578 mDNSexport void
stop_and_clean_dnssec_zone_t(dnssec_zone_t * const _Nonnull zone)1579 stop_and_clean_dnssec_zone_t(dnssec_zone_t * const _Nonnull zone) {
1580 	if (zone->dnskey_request_started) {
1581 		QueryRecordOpStopForClientRequest(&zone->dnskey_request.op);
1582 	}
1583 	if (zone->ds_request_started) {
1584 		QueryRecordOpStopForClientRequest(&zone->ds_request.op);
1585 	}
1586 
1587 	uninitialize_dnssec_zone_t(zone);
1588 }
1589 
1590 //======================================================================================================================
1591 //	print_dnssec_zone_t
1592 //======================================================================================================================
1593 
1594 mDNSexport void
print_dnssec_zone_t(const dnssec_zone_t * const _Nonnull zone,mDNSu8 num_of_tabs)1595 print_dnssec_zone_t(const dnssec_zone_t * const _Nonnull zone, mDNSu8 num_of_tabs) {
1596 	log_debug(TAB_STR
1597 		"Name: " PRI_DM_NAME
1598 		", Name Hash: %u"
1599 		,
1600 		TAB_PARAM(num_of_tabs),
1601 		DM_NAME_PARAM(&zone->domain_name),
1602 		zone->name_hash);
1603 
1604 	log_debug(TAB_STR "DNSKEYs:", TAB_PARAM(num_of_tabs));
1605 	print_dnskeys_with_rrsig_t(&zone->dnskeys_with_rrsig, num_of_tabs + 1);
1606 
1607 	if (zone->dses_initialized) {
1608 		log_debug(TAB_STR "DSs:", TAB_PARAM(num_of_tabs));
1609 		print_dses_with_rrsig_t(&zone->dses_with_rrsig, num_of_tabs + 1);
1610 	}
1611 
1612 	if (zone->trust_anchor != mDNSNULL) {
1613 		log_debug(TAB_STR "Trust Anchors:", TAB_PARAM(num_of_tabs));
1614 		print_trust_anchors_t(zone->trust_anchor, num_of_tabs + 1);
1615 	}
1616 
1617 	log_debug(TAB_STR "--------------------------------------------------", TAB_PARAM(num_of_tabs));
1618 }
1619 
1620 #pragma mark - returned_answers_t
1621 
1622 
1623 
1624 #pragma mark initialize_returned_answers_t
1625 mDNSexport void
initialize_returned_answers_t(returned_answers_t * const _Nonnull returned_answers,const dnssec_result_t dnssec_result,const DNSServiceErrorType error)1626 initialize_returned_answers_t(
1627 	returned_answers_t * const	_Nonnull	returned_answers,
1628 	const dnssec_result_t					dnssec_result,
1629 	const DNSServiceErrorType				error) {
1630 
1631 	list_init(&returned_answers->answers, sizeof(ResourceRecord *));
1632 	returned_answers->dnssec_result		= dnssec_result;
1633 	returned_answers->error				= error;
1634 }
1635 
1636 #pragma mark uninitialize_returned_answers_t
1637 mDNSexport void
uninitialize_returned_answers_t(returned_answers_t * const _Nonnull returned_answers)1638 uninitialize_returned_answers_t(returned_answers_t * const _Nonnull returned_answers) {
1639 	list_uninit(&returned_answers->answers);
1640 }
1641 
1642 #pragma mark print_returned_answers_t
1643 mDNSexport void
print_returned_answers_t(const returned_answers_t * const _Nonnull returned_answers,mDNSu8 num_of_tabs)1644 print_returned_answers_t(const returned_answers_t * const _Nonnull returned_answers, mDNSu8 num_of_tabs) {
1645 
1646 	log_debug(TAB_STR "dnssec_result:%d", TAB_PARAM(num_of_tabs), returned_answers->dnssec_result);
1647 	log_debug(TAB_STR "error:%d", TAB_PARAM(num_of_tabs), returned_answers->error);
1648 	log_debug(TAB_STR "type:%d", TAB_PARAM(num_of_tabs), returned_answers->type);
1649 
1650 	log_debug(TAB_STR "Resource Record:", TAB_PARAM(num_of_tabs));
1651 	dnssec_rr_t dnssec_rr;
1652 	const list_t * const answers = &returned_answers->answers;
1653 	for (list_node_t * rr_node = list_get_first(answers); !list_has_ended(answers, rr_node); rr_node = list_next(rr_node)) {
1654 		ResourceRecord **	rr_ptr	= (ResourceRecord **)rr_node->data;
1655 		ResourceRecord *	rr		= *rr_ptr;
1656 		initialize_dnssec_rr_t(&dnssec_rr, rr);
1657 		print_dnssec_rr_t(&dnssec_rr, num_of_tabs + 1);
1658 		uninitialize_dnssec_rr_t(&dnssec_rr);
1659 	}
1660 }
1661 
1662 
1663 #endif // MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2)
1664