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