Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / lib / dns / private.c
blob6c8b80c37425d1c03751eab1c1fd9841b54021c6
1 /* $NetBSD: private.c,v 1.7 2015/07/08 17:28:59 christos Exp $ */
3 /*
4 * Copyright (C) 2009, 2011, 2012, 2015 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
19 /* Id */
21 #include "config.h"
23 #include <isc/result.h>
24 #include <isc/string.h>
25 #include <isc/types.h>
26 #include <isc/base64.h>
28 #include <dns/nsec3.h>
29 #include <dns/private.h>
32 * We need to build the relevant chain if there exists a NSEC/NSEC3PARAM
33 * at the apex; normally only one or the other of NSEC/NSEC3PARAM will exist.
35 * If a NSEC3PARAM RRset exists then we will need to build a NSEC chain
36 * if all the NSEC3PARAM records (and associated chains) are slated for
37 * destruction and we have not been told to NOT build the NSEC chain.
39 * If the NSEC set exist then check to see if there is a request to create
40 * a NSEC3 chain.
42 * If neither NSEC/NSEC3PARAM RRsets exist at the origin and the private
43 * type exists then we need to examine it to determine if NSEC3 chain has
44 * been requested to be built otherwise a NSEC chain needs to be built.
47 #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
48 #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
49 #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
50 #define NONSEC(x) (((x) & DNS_NSEC3FLAG_NONSEC) != 0)
52 #define CHECK(x) do { \
53 result = (x); \
54 if (result != ISC_R_SUCCESS) \
55 goto failure; \
56 } while (/*CONSTCOND*/0)
59 * Work out if 'param' should be ignored or not (i.e. it is in the process
60 * of being removed).
62 * Note: we 'belt-and-braces' here by also checking for a CREATE private
63 * record and keep the param record in this case.
66 static isc_boolean_t
67 ignore(dns_rdata_t *param, dns_rdataset_t *privateset) {
68 isc_result_t result;
70 for (result = dns_rdataset_first(privateset);
71 result == ISC_R_SUCCESS;
72 result = dns_rdataset_next(privateset)) {
73 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
74 dns_rdata_t private = DNS_RDATA_INIT;
75 dns_rdata_t rdata = DNS_RDATA_INIT;
77 dns_rdataset_current(privateset, &private);
78 if (!dns_nsec3param_fromprivate(&private, &rdata,
79 buf, sizeof(buf)))
80 continue;
82 * We are going to create a new NSEC3 chain so it
83 * doesn't matter if we are removing this one.
85 if (CREATE(rdata.data[1]))
86 return (ISC_FALSE);
87 if (rdata.data[0] != param->data[0] ||
88 rdata.data[2] != param->data[2] ||
89 rdata.data[3] != param->data[3] ||
90 rdata.data[4] != param->data[4] ||
91 memcmp(&rdata.data[5], &param->data[5], param->data[4]))
92 continue;
94 * The removal of this NSEC3 chain does NOT cause a
95 * NSEC chain to be created so we don't need to tell
96 * the caller that it will be removed.
98 if (NONSEC(rdata.data[1]))
99 return (ISC_FALSE);
100 return (ISC_TRUE);
102 return (ISC_FALSE);
105 isc_result_t
106 dns_private_chains(dns_db_t *db, dns_dbversion_t *ver,
107 dns_rdatatype_t privatetype,
108 isc_boolean_t *build_nsec, isc_boolean_t *build_nsec3)
110 dns_dbnode_t *node;
111 dns_rdataset_t nsecset, nsec3paramset, privateset;
112 isc_boolean_t nsec3chain;
113 isc_boolean_t signing;
114 isc_result_t result;
115 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
116 unsigned int count;
118 node = NULL;
119 dns_rdataset_init(&nsecset);
120 dns_rdataset_init(&nsec3paramset);
121 dns_rdataset_init(&privateset);
123 CHECK(dns_db_getoriginnode(db, &node));
125 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
126 0, (isc_stdtime_t) 0, &nsecset, NULL);
128 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
129 goto failure;
131 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
132 0, (isc_stdtime_t) 0, &nsec3paramset,
133 NULL);
134 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
135 goto failure;
137 if (dns_rdataset_isassociated(&nsecset) &&
138 dns_rdataset_isassociated(&nsec3paramset)) {
139 if (build_nsec != NULL)
140 *build_nsec = ISC_TRUE;
141 if (build_nsec3 != NULL)
142 *build_nsec3 = ISC_TRUE;
143 goto success;
146 if (privatetype != (dns_rdatatype_t)0) {
147 result = dns_db_findrdataset(db, node, ver, privatetype,
148 0, (isc_stdtime_t) 0,
149 &privateset, NULL);
150 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
151 goto failure;
155 * Look to see if we also need to be creating a NSEC3 chain.
157 if (dns_rdataset_isassociated(&nsecset)) {
158 if (build_nsec != NULL)
159 *build_nsec = ISC_TRUE;
160 if (build_nsec3 != NULL)
161 *build_nsec3 = ISC_FALSE;
162 if (!dns_rdataset_isassociated(&privateset))
163 goto success;
164 for (result = dns_rdataset_first(&privateset);
165 result == ISC_R_SUCCESS;
166 result = dns_rdataset_next(&privateset)) {
167 dns_rdata_t private = DNS_RDATA_INIT;
168 dns_rdata_t rdata = DNS_RDATA_INIT;
170 dns_rdataset_current(&privateset, &private);
171 if (!dns_nsec3param_fromprivate(&private, &rdata,
172 buf, sizeof(buf)))
173 continue;
174 if (REMOVE(rdata.data[1]))
175 continue;
176 if (build_nsec3 != NULL)
177 *build_nsec3 = ISC_TRUE;
178 break;
180 goto success;
183 if (dns_rdataset_isassociated(&nsec3paramset)) {
184 if (build_nsec3 != NULL)
185 *build_nsec3 = ISC_TRUE;
186 if (build_nsec != NULL)
187 *build_nsec = ISC_FALSE;
188 if (!dns_rdataset_isassociated(&privateset))
189 goto success;
191 * If we are in the process of building a new NSEC3 chain
192 * then we don't need to build a NSEC chain.
194 for (result = dns_rdataset_first(&privateset);
195 result == ISC_R_SUCCESS;
196 result = dns_rdataset_next(&privateset)) {
197 dns_rdata_t private = DNS_RDATA_INIT;
198 dns_rdata_t rdata = DNS_RDATA_INIT;
200 dns_rdataset_current(&privateset, &private);
201 if (!dns_nsec3param_fromprivate(&private, &rdata,
202 buf, sizeof(buf)))
203 continue;
204 if (CREATE(rdata.data[1]))
205 goto success;
209 * Check to see if there will be a active NSEC3CHAIN once
210 * the changes queued complete.
212 count = 0;
213 for (result = dns_rdataset_first(&nsec3paramset);
214 result == ISC_R_SUCCESS;
215 result = dns_rdataset_next(&nsec3paramset)) {
216 dns_rdata_t rdata = DNS_RDATA_INIT;
219 * If there is more that one NSEC3 chain present then
220 * we don't need to construct a NSEC chain.
222 if (++count > 1)
223 goto success;
224 dns_rdataset_current(&nsec3paramset, &rdata);
225 if (ignore(&rdata, &privateset))
226 continue;
228 * We still have a good NSEC3 chain or we are
229 * not creating a NSEC chain as NONSEC is set.
231 goto success;
235 * The last NSEC3 chain is being removed and does not have
236 * have NONSEC set.
238 if (build_nsec != NULL)
239 *build_nsec = ISC_TRUE;
240 goto success;
243 if (build_nsec != NULL)
244 *build_nsec = ISC_FALSE;
245 if (build_nsec3 != NULL)
246 *build_nsec3 = ISC_FALSE;
247 if (!dns_rdataset_isassociated(&privateset))
248 goto success;
250 signing = ISC_FALSE;
251 nsec3chain = ISC_FALSE;
253 for (result = dns_rdataset_first(&privateset);
254 result == ISC_R_SUCCESS;
255 result = dns_rdataset_next(&privateset)) {
256 dns_rdata_t rdata = DNS_RDATA_INIT;
257 dns_rdata_t private = DNS_RDATA_INIT;
259 dns_rdataset_current(&privateset, &private);
260 if (!dns_nsec3param_fromprivate(&private, &rdata,
261 buf, sizeof(buf))) {
263 * Look for record that says we are signing the
264 * zone with a key.
266 if (private.length == 5 && private.data[0] != 0 &&
267 private.data[3] == 0 && private.data[4] == 0)
268 signing = ISC_TRUE;
269 } else {
270 if (CREATE(rdata.data[1]))
271 nsec3chain = ISC_TRUE;
275 if (signing) {
276 if (nsec3chain) {
277 if (build_nsec3 != NULL)
278 *build_nsec3 = ISC_TRUE;
279 } else {
280 if (build_nsec != NULL)
281 *build_nsec = ISC_TRUE;
285 success:
286 result = ISC_R_SUCCESS;
287 failure:
288 if (dns_rdataset_isassociated(&nsecset))
289 dns_rdataset_disassociate(&nsecset);
290 if (dns_rdataset_isassociated(&nsec3paramset))
291 dns_rdataset_disassociate(&nsec3paramset);
292 if (dns_rdataset_isassociated(&privateset))
293 dns_rdataset_disassociate(&privateset);
294 if (node != NULL)
295 dns_db_detachnode(db, &node);
296 return (result);
299 isc_result_t
300 dns_private_totext(dns_rdata_t *private, isc_buffer_t *buf) {
301 isc_result_t result;
303 if (private->length < 5)
304 return (ISC_R_NOTFOUND);
306 if (private->data[0] == 0) {
307 unsigned char nsec3buf[DNS_NSEC3PARAM_BUFFERSIZE];
308 unsigned char newbuf[DNS_NSEC3PARAM_BUFFERSIZE];
309 dns_rdata_t rdata = DNS_RDATA_INIT;
310 dns_rdata_nsec3param_t nsec3param;
311 isc_boolean_t remove, init, nonsec;
312 isc_buffer_t b;
314 if (!dns_nsec3param_fromprivate(private, &rdata, nsec3buf,
315 sizeof(nsec3buf)))
316 CHECK(ISC_R_FAILURE);
318 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
320 remove = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0);
321 init = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0);
322 nonsec = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_NONSEC) != 0);
324 nsec3param.flags &= ~(DNS_NSEC3FLAG_CREATE|
325 DNS_NSEC3FLAG_REMOVE|
326 DNS_NSEC3FLAG_INITIAL|
327 DNS_NSEC3FLAG_NONSEC);
329 if (init)
330 isc_buffer_putstr(buf, "Pending NSEC3 chain ");
331 else if (remove)
332 isc_buffer_putstr(buf, "Removing NSEC3 chain ");
333 else
334 isc_buffer_putstr(buf, "Creating NSEC3 chain ");
336 dns_rdata_reset(&rdata);
337 isc_buffer_init(&b, newbuf, sizeof(newbuf));
338 CHECK(dns_rdata_fromstruct(&rdata, dns_rdataclass_in,
339 dns_rdatatype_nsec3param,
340 &nsec3param, &b));
342 CHECK(dns_rdata_totext(&rdata, NULL, buf));
344 if (remove && !nonsec)
345 isc_buffer_putstr(buf, " / creating NSEC chain");
346 } else if (private->length == 5) {
347 unsigned char alg = private->data[0];
348 dns_keytag_t keyid = (private->data[2] | private->data[1] << 8);
349 char keybuf[BUFSIZ], algbuf[DNS_SECALG_FORMATSIZE];
350 isc_boolean_t remove = ISC_TF(private->data[3] != 0);
351 isc_boolean_t complete = ISC_TF(private->data[4] != 0);
353 if (remove && complete)
354 isc_buffer_putstr(buf, "Done removing signatures for ");
355 else if (remove)
356 isc_buffer_putstr(buf, "Removing signatures for ");
357 else if (complete)
358 isc_buffer_putstr(buf, "Done signing with ");
359 else
360 isc_buffer_putstr(buf, "Signing with ");
362 dns_secalg_format(alg, algbuf, sizeof(algbuf));
363 sprintf(keybuf, "key %d/%s", keyid, algbuf);
364 isc_buffer_putstr(buf, keybuf);
365 } else
366 return (ISC_R_NOTFOUND);
368 isc_buffer_putuint8(buf, 0);
369 result = ISC_R_SUCCESS;
370 failure:
371 return (result);