5 // Copyright (c) 2020 Apple Inc. All rights reserved.
8 #pragma mark - Includes
9 #include "mDNSEmbeddedAPI.h"
10 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2)
11 #include "dnssec_v2_helper.h"
12 #include "dnssec_v2_log.h"
13 #include "dnssec_v2_crypto.h"
15 #include <AssertMacros.h>
17 #pragma mark - Functions
21 #pragma mark - deep_copy_resource_record
23 deep_copy_resource_record(ResourceRecord
* const _Nonnull dst
, const ResourceRecord
* const _Nonnull src
) {
24 mStatus error
= mStatus_NoError
;
26 RData
* new_rdata
= mDNSNULL
;
30 require_action(dst
!= mDNSNULL
, exit
, error
= mStatus_Invalid
; log_fault("ResourceRecord dst is NULL, unable to copy to"));
31 memcpy(dst
, src
, sizeof(ResourceRecord
));
34 dst
->rdata
= mDNSNULL
;
37 name_length
= DOMAIN_NAME_LENGTH(src
->name
);
38 dst
->name
= malloc(name_length
);
39 require_action(dst
->name
!= mDNSNULL
, exit
, error
= mStatus_NoMemoryErr
;
40 log_fault("malloc failed; error_description='%s'", strerror(errno
)));
41 memcpy((void *)dst
->name
, (void *)src
->name
, name_length
);
44 rdata_size
= MAX(src
->rdlength
, sizeof(RDataBody
));
45 new_rdata
= malloc(sizeof(RData
) - sizeof(RDataBody
) + rdata_size
);
46 require_action(new_rdata
!= mDNSNULL
, exit
, error
= mStatus_NoMemoryErr
;
47 log_fault("malloc failed; error_description='%s'", strerror(errno
)));
48 new_rdata
->MaxRDLength
= rdata_size
;
49 memcpy(new_rdata
->u
.data
, src
->rdata
->u
.data
, rdata_size
);
50 dst
->rdata
= new_rdata
;
53 if (error
!= mStatus_NoError
) {
54 if (dst
!= mDNSNULL
) {
55 if (dst
->name
!= mDNSNULL
) free((void *)dst
->name
);
56 if (dst
->rdata
!= mDNSNULL
) free(dst
->rdata
);
62 #pragma mark - free_resource_record_deep_copied
64 free_resource_record_deep_copied(ResourceRecord
* const _Nonnull rr
) {
65 if (rr
->name
!= mDNSNULL
) {
66 free((void *)rr
->name
);
69 if (rr
->rdata
!= mDNSNULL
) {
74 #pragma mark - is_root_domain
76 is_root_domain(const mDNSu8
* const _Nonnull domain_name
) {
77 return *domain_name
== 0;
81 #pragma mark - is_a_subdomain_of_b
83 is_a_subdomain_of_b(const mDNSu8
* const a_name
, const mDNSu8
* const b_name
) {
84 const mDNSu16 a_length
= DOMAIN_NAME_LENGTH(a_name
);
85 const mDNSu16 b_length
= DOMAIN_NAME_LENGTH(b_name
);
87 return memcmp(a_name
+ (a_length
- b_length
), b_name
, b_length
) == 0;
90 #pragma mark - resource_records_equal
92 resource_records_equal(
93 const mDNSu16 rr_type_0
, const mDNSu16 rr_type_1
,
94 const mDNSu16 rr_class_0
, const mDNSu16 rr_clasee_1
,
95 const mDNSu16 rdata_length_0
, const mDNSu16 rdata_length_1
,
96 const mDNSu32 name_hash_0
, const mDNSu32 name_hash_1
,
97 const mDNSu32 rdata_hash_0
, const mDNSu32 rdata_hash_1
,
98 const mDNSu8
* const _Nonnull name_0
, const mDNSu8
* const _Nonnull name_1
,
99 const mDNSu8
* const _Nonnull rdata_0
, const mDNSu8
* const _Nonnull rdata_1
) {
101 if (rr_type_0
!= rr_type_1
) return mDNSfalse
;
102 if (rr_class_0
!= rr_clasee_1
) return mDNSfalse
;
103 if (rdata_length_0
!= rdata_length_1
) return mDNSfalse
;
104 if (name_hash_0
!= name_hash_1
) return mDNSfalse
;
105 if (rdata_hash_0
!= rdata_hash_1
) return mDNSfalse
;
106 if (!DOMAIN_NAME_EQUALS(name_0
, name_1
)) return mDNSfalse
;
107 if (memcmp(rdata_0
, rdata_1
, rdata_length_0
) != 0) return mDNSfalse
;
112 #pragma mark - dnssec_algorithm_value_to_string
113 mDNSexport
const char * _Nonnull
114 dnssec_algorithm_value_to_string(const mDNSu8 algorithm
) {
115 const char *dnskey_algorithm_desp
= mDNSNULL
;
117 case DNSKEY_ALGORITHM_DELETE
:
118 dnskey_algorithm_desp
= "DELETE";
120 case DNSKEY_ALGORITHM_RSAMD5
:
121 dnskey_algorithm_desp
= "RSAMD5";
123 case DNSKEY_ALGORITHM_DH
:
124 dnskey_algorithm_desp
= "DH";
126 case DNSKEY_ALGORITHM_DSA
:
127 dnskey_algorithm_desp
= "DSA";
129 case DNSKEY_ALGORITHM_RSASHA1
:
130 dnskey_algorithm_desp
= "DSA";
132 case DNSKEY_ALGORITHM_DSA_NSEC3_SHA1
:
133 dnskey_algorithm_desp
= "DSA_NSEC3_SHA1";
135 case DNSKEY_ALGORITHM_RSASHA1_NSEC3_SHA1
:
136 dnskey_algorithm_desp
= "RSASHA1_NSEC3_SHA1";
138 case DNSKEY_ALGORITHM_RSASHA256
:
139 dnskey_algorithm_desp
= "RSASHA256";
141 case DNSKEY_ALGORITHM_RSASHA512
:
142 dnskey_algorithm_desp
= "RSASHA512";
144 case DNSKEY_ALGORITHM_ECC_GOST
:
145 dnskey_algorithm_desp
= "ECC_GOST";
147 case DNSKEY_ALGORITHM_ECDSAP256SHA256
:
148 dnskey_algorithm_desp
= "ECDSAP256SHA256";
150 case DNSKEY_ALGORITHM_ECDSAP384SHA384
:
151 dnskey_algorithm_desp
= "ECDSAP384SHA384";
153 case DNSKEK_ALGORITHM_ED25519
:
154 dnskey_algorithm_desp
= "ED25519";
156 case DNSKEY_ALGORITHM_ED448
:
157 dnskey_algorithm_desp
= "ED448";
159 case DNSKEY_ALGORITHM_INDIRECT
:
160 dnskey_algorithm_desp
= "INDIRECT";
162 case DNSKEY_ALGORITHM_PRIVATEDNS
:
163 dnskey_algorithm_desp
= "PRIVATEDNS";
165 case DNSKEY_ALGORITHM_PRIVATEOID
:
166 dnskey_algorithm_desp
= "PRIVATEOID";
169 dnskey_algorithm_desp
= "UNKNOWN";
173 return dnskey_algorithm_desp
;
176 #pragma mark - dnssec_digest_type_value_to_string
177 mDNSexport
const char * _Nonnull
178 dnssec_digest_type_value_to_string(const mDNSu8 digest_type
) {
179 const char * ds_digest_type_desp
= mDNSNULL
;
180 switch (digest_type
) {
181 case DS_DIGEST_SHA_1
:
182 ds_digest_type_desp
= "SHA_1";
184 case DS_DIGEST_SHA_256
:
185 ds_digest_type_desp
= "SHA_256";
187 case DS_DIGEST_GOST_R_34_11_94
:
188 ds_digest_type_desp
= "GOST_R_34_11_94";
190 case DS_DIGEST_SHA_384
:
191 ds_digest_type_desp
= "SHA_384";
194 ds_digest_type_desp
= "UNKNOWN";
197 return ds_digest_type_desp
;
200 #pragma mark - dnssec_dnskey_flags_to_string
201 mDNSexport
const char * _Nonnull
202 dnssec_dnskey_flags_to_string(const mDNSu16 flags
, char * const _Nonnull buffer
, const mDNSu32 buffer_size
) {
204 char * limit
= ptr
+ buffer_size
;
205 int num_of_char_write
;
207 if ((flags
& 0x100) != 0) { // bit 8
208 num_of_char_write
= snprintf(ptr
, limit
- ptr
, "ZONE ");
209 require(num_of_char_write
+ ptr
< limit
, exit
);
210 ptr
+= num_of_char_write
;
213 if ((flags
& 0x80) != 0) { // bit 7
214 num_of_char_write
= snprintf(ptr
, limit
- ptr
, "REVOKE ");
215 require(num_of_char_write
+ ptr
< limit
, exit
);
216 ptr
+= num_of_char_write
;
219 if ((flags
& 0x1) != 0) { // bit 15
220 num_of_char_write
= snprintf(ptr
, limit
- ptr
, "Secure_Entry_Point ");
221 require(num_of_char_write
+ ptr
< limit
, exit
);
222 ptr
+= num_of_char_write
;
233 #pragma mark - dnssec_epoch_time_to_date_string
234 mDNSexport
const char * _Nonnull
235 dnssec_epoch_time_to_date_string(const mDNSu32 epoch
, char * const _Nonnull buffer
, const mDNSu32 buffer_size
) {
237 struct tm local_time
;
239 localtime_r(&t
, &local_time
);
240 strftime(buffer
, buffer_size
, "%F %T%z", &local_time
);
245 #pragma mark - dnssec_nsec3_flags_to_string
246 mDNSexport
const char * _Nonnull
247 dnssec_nsec3_flags_to_string(const mDNSu8 flags
, char * const _Nonnull buffer
, const mDNSu32 buffer_size
) {
249 char * limit
= buffer
+ buffer_size
;
250 int num_of_char_write
;
252 if ((flags
& 0x1) != 0) { // bit 0
253 num_of_char_write
= snprintf(ptr
, limit
- ptr
, "Opt-Out ");
254 require(num_of_char_write
+ ptr
< limit
, exit
);
255 ptr
+= num_of_char_write
;
266 #pragma mark - get_number_of_labels
268 get_number_of_labels(const mDNSu8
* _Nonnull name
) {
279 #pragma mark - to_lowercase_if_char
281 to_lowercase_if_char(const mDNSu8 ch
) {
282 return IS_UPPER_CASE(ch
) ? TO_LOWER_CASE(ch
) : ch
;
285 #endif // MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2)