]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/dnssec_v2/dnssec_v2_helper.c
mDNSResponder-1310.40.42.tar.gz
[apple/mdnsresponder.git] / mDNSMacOSX / dnssec_v2 / dnssec_v2_helper.c
1 //
2 // dnssec_v2_helper.c
3 // mDNSResponder
4 //
5 // Copyright (c) 2020 Apple Inc. All rights reserved.
6 //
7
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"
14 #include <errno.h>
15 #include <AssertMacros.h>
16
17 #pragma mark - Functions
18
19
20
21 #pragma mark - deep_copy_resource_record
22 mDNSexport mStatus
23 deep_copy_resource_record(ResourceRecord * const _Nonnull dst, const ResourceRecord * const _Nonnull src) {
24 mStatus error = mStatus_NoError;
25
26 RData * new_rdata = mDNSNULL;
27 mDNSu16 name_length;
28 mDNSu32 rdata_size;
29
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));
32
33 dst->name = mDNSNULL;
34 dst->rdata = mDNSNULL;
35
36 // copy name
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);
42
43 // copy rdata
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;
51
52 exit:
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);
57 }
58 }
59 return error;
60 }
61
62 #pragma mark - free_resource_record_deep_copied
63 mDNSexport void
64 free_resource_record_deep_copied(ResourceRecord * const _Nonnull rr) {
65 if (rr->name != mDNSNULL) {
66 free((void *)rr->name);
67 }
68
69 if (rr->rdata != mDNSNULL) {
70 free(rr->rdata);
71 }
72 }
73
74 #pragma mark - is_root_domain
75 mDNSexport mDNSBool
76 is_root_domain(const mDNSu8 * const _Nonnull domain_name) {
77 return *domain_name == 0;
78 }
79
80
81 #pragma mark - is_a_subdomain_of_b
82 mDNSexport mDNSBool
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);
86
87 return memcmp(a_name + (a_length - b_length), b_name, b_length) == 0;
88 }
89
90 #pragma mark - resource_records_equal
91 mDNSexport mDNSBool
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) {
100
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;
108
109 return mDNStrue;
110 }
111
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;
116 switch (algorithm) {
117 case DNSKEY_ALGORITHM_DELETE:
118 dnskey_algorithm_desp = "DELETE";
119 break;
120 case DNSKEY_ALGORITHM_RSAMD5:
121 dnskey_algorithm_desp = "RSAMD5";
122 break;
123 case DNSKEY_ALGORITHM_DH:
124 dnskey_algorithm_desp = "DH";
125 break;
126 case DNSKEY_ALGORITHM_DSA:
127 dnskey_algorithm_desp = "DSA";
128 break;
129 case DNSKEY_ALGORITHM_RSASHA1:
130 dnskey_algorithm_desp = "DSA";
131 break;
132 case DNSKEY_ALGORITHM_DSA_NSEC3_SHA1:
133 dnskey_algorithm_desp = "DSA_NSEC3_SHA1";
134 break;
135 case DNSKEY_ALGORITHM_RSASHA1_NSEC3_SHA1:
136 dnskey_algorithm_desp = "RSASHA1_NSEC3_SHA1";
137 break;
138 case DNSKEY_ALGORITHM_RSASHA256:
139 dnskey_algorithm_desp = "RSASHA256";
140 break;
141 case DNSKEY_ALGORITHM_RSASHA512:
142 dnskey_algorithm_desp = "RSASHA512";
143 break;
144 case DNSKEY_ALGORITHM_ECC_GOST:
145 dnskey_algorithm_desp = "ECC_GOST";
146 break;
147 case DNSKEY_ALGORITHM_ECDSAP256SHA256:
148 dnskey_algorithm_desp = "ECDSAP256SHA256";
149 break;
150 case DNSKEY_ALGORITHM_ECDSAP384SHA384:
151 dnskey_algorithm_desp = "ECDSAP384SHA384";
152 break;
153 case DNSKEK_ALGORITHM_ED25519:
154 dnskey_algorithm_desp = "ED25519";
155 break;
156 case DNSKEY_ALGORITHM_ED448:
157 dnskey_algorithm_desp = "ED448";
158 break;
159 case DNSKEY_ALGORITHM_INDIRECT:
160 dnskey_algorithm_desp = "INDIRECT";
161 break;
162 case DNSKEY_ALGORITHM_PRIVATEDNS:
163 dnskey_algorithm_desp = "PRIVATEDNS";
164 break;
165 case DNSKEY_ALGORITHM_PRIVATEOID:
166 dnskey_algorithm_desp = "PRIVATEOID";
167 break;
168 default:
169 dnskey_algorithm_desp = "UNKNOWN";
170 break;
171 }
172
173 return dnskey_algorithm_desp;
174 }
175
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";
183 break;
184 case DS_DIGEST_SHA_256:
185 ds_digest_type_desp = "SHA_256";
186 break;
187 case DS_DIGEST_GOST_R_34_11_94:
188 ds_digest_type_desp = "GOST_R_34_11_94";
189 break;
190 case DS_DIGEST_SHA_384:
191 ds_digest_type_desp = "SHA_384";
192 break;
193 default:
194 ds_digest_type_desp = "UNKNOWN";
195 break;
196 }
197 return ds_digest_type_desp;
198 }
199
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) {
203 char * ptr = buffer;
204 char * limit = ptr + buffer_size;
205 int num_of_char_write;
206
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;
211 }
212
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;
217 }
218
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;
223 }
224
225 exit:
226 if (ptr > buffer) {
227 ptr--;
228 *ptr = '\0';
229 }
230 return buffer;
231 }
232
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) {
236 time_t t = epoch;
237 struct tm local_time;
238
239 localtime_r(&t, &local_time);
240 strftime(buffer, buffer_size, "%F %T%z", &local_time);
241
242 return buffer;
243 }
244
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) {
248 char * ptr = buffer;
249 char * limit = buffer + buffer_size;
250 int num_of_char_write;
251
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;
256 }
257
258 exit:
259 if (ptr > buffer) {
260 ptr--;
261 *ptr = '\0';
262 }
263 return buffer;
264 }
265
266 #pragma mark - get_number_of_labels
267 mDNSexport mDNSu8
268 get_number_of_labels(const mDNSu8 * _Nonnull name) {
269 mDNSu8 count = 0;
270
271 while (*name != 0) {
272 count++;
273 name += *name + 1;
274 }
275
276 return count;
277 }
278
279 #pragma mark - to_lowercase_if_char
280 mDNSexport mDNSu8
281 to_lowercase_if_char(const mDNSu8 ch) {
282 return IS_UPPER_CASE(ch) ? TO_LOWER_CASE(ch) : ch;
283 }
284
285 #endif // MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2)