xref: /freebsd/contrib/unbound/validator/val_kentry.c (revision b7579f77d18196a58ff700756c84dc9a302a7f67)
1*b7579f77SDag-Erling Smørgrav /*
2*b7579f77SDag-Erling Smørgrav  * validator/val_kentry.c - validator key entry definition.
3*b7579f77SDag-Erling Smørgrav  *
4*b7579f77SDag-Erling Smørgrav  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5*b7579f77SDag-Erling Smørgrav  *
6*b7579f77SDag-Erling Smørgrav  * This software is open source.
7*b7579f77SDag-Erling Smørgrav  *
8*b7579f77SDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
9*b7579f77SDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
10*b7579f77SDag-Erling Smørgrav  * are met:
11*b7579f77SDag-Erling Smørgrav  *
12*b7579f77SDag-Erling Smørgrav  * Redistributions of source code must retain the above copyright notice,
13*b7579f77SDag-Erling Smørgrav  * this list of conditions and the following disclaimer.
14*b7579f77SDag-Erling Smørgrav  *
15*b7579f77SDag-Erling Smørgrav  * Redistributions in binary form must reproduce the above copyright notice,
16*b7579f77SDag-Erling Smørgrav  * this list of conditions and the following disclaimer in the documentation
17*b7579f77SDag-Erling Smørgrav  * and/or other materials provided with the distribution.
18*b7579f77SDag-Erling Smørgrav  *
19*b7579f77SDag-Erling Smørgrav  * Neither the name of the NLNET LABS nor the names of its contributors may
20*b7579f77SDag-Erling Smørgrav  * be used to endorse or promote products derived from this software without
21*b7579f77SDag-Erling Smørgrav  * specific prior written permission.
22*b7579f77SDag-Erling Smørgrav  *
23*b7579f77SDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24*b7579f77SDag-Erling Smørgrav  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25*b7579f77SDag-Erling Smørgrav  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26*b7579f77SDag-Erling Smørgrav  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
27*b7579f77SDag-Erling Smørgrav  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28*b7579f77SDag-Erling Smørgrav  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29*b7579f77SDag-Erling Smørgrav  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30*b7579f77SDag-Erling Smørgrav  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31*b7579f77SDag-Erling Smørgrav  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32*b7579f77SDag-Erling Smørgrav  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33*b7579f77SDag-Erling Smørgrav  * POSSIBILITY OF SUCH DAMAGE.
34*b7579f77SDag-Erling Smørgrav  */
35*b7579f77SDag-Erling Smørgrav 
36*b7579f77SDag-Erling Smørgrav /**
37*b7579f77SDag-Erling Smørgrav  * \file
38*b7579f77SDag-Erling Smørgrav  *
39*b7579f77SDag-Erling Smørgrav  * This file contains functions for dealing with validator key entries.
40*b7579f77SDag-Erling Smørgrav  */
41*b7579f77SDag-Erling Smørgrav #include "config.h"
42*b7579f77SDag-Erling Smørgrav #include <ldns/ldns.h>
43*b7579f77SDag-Erling Smørgrav #include "validator/val_kentry.h"
44*b7579f77SDag-Erling Smørgrav #include "util/data/packed_rrset.h"
45*b7579f77SDag-Erling Smørgrav #include "util/data/dname.h"
46*b7579f77SDag-Erling Smørgrav #include "util/storage/lookup3.h"
47*b7579f77SDag-Erling Smørgrav #include "util/regional.h"
48*b7579f77SDag-Erling Smørgrav #include "util/net_help.h"
49*b7579f77SDag-Erling Smørgrav 
50*b7579f77SDag-Erling Smørgrav size_t
51*b7579f77SDag-Erling Smørgrav key_entry_sizefunc(void* key, void* data)
52*b7579f77SDag-Erling Smørgrav {
53*b7579f77SDag-Erling Smørgrav 	struct key_entry_key* kk = (struct key_entry_key*)key;
54*b7579f77SDag-Erling Smørgrav 	struct key_entry_data* kd = (struct key_entry_data*)data;
55*b7579f77SDag-Erling Smørgrav 	size_t s = sizeof(*kk) + kk->namelen;
56*b7579f77SDag-Erling Smørgrav 	s += sizeof(*kd) + lock_get_mem(&kk->entry.lock);
57*b7579f77SDag-Erling Smørgrav 	if(kd->rrset_data)
58*b7579f77SDag-Erling Smørgrav 		s += packed_rrset_sizeof(kd->rrset_data);
59*b7579f77SDag-Erling Smørgrav 	if(kd->reason)
60*b7579f77SDag-Erling Smørgrav 		s += strlen(kd->reason)+1;
61*b7579f77SDag-Erling Smørgrav 	if(kd->algo)
62*b7579f77SDag-Erling Smørgrav 		s += strlen((char*)kd->algo)+1;
63*b7579f77SDag-Erling Smørgrav 	return s;
64*b7579f77SDag-Erling Smørgrav }
65*b7579f77SDag-Erling Smørgrav 
66*b7579f77SDag-Erling Smørgrav int
67*b7579f77SDag-Erling Smørgrav key_entry_compfunc(void* k1, void* k2)
68*b7579f77SDag-Erling Smørgrav {
69*b7579f77SDag-Erling Smørgrav 	struct key_entry_key* n1 = (struct key_entry_key*)k1;
70*b7579f77SDag-Erling Smørgrav 	struct key_entry_key* n2 = (struct key_entry_key*)k2;
71*b7579f77SDag-Erling Smørgrav 	if(n1->key_class != n2->key_class) {
72*b7579f77SDag-Erling Smørgrav 		if(n1->key_class < n2->key_class)
73*b7579f77SDag-Erling Smørgrav 			return -1;
74*b7579f77SDag-Erling Smørgrav 		return 1;
75*b7579f77SDag-Erling Smørgrav 	}
76*b7579f77SDag-Erling Smørgrav 	return query_dname_compare(n1->name, n2->name);
77*b7579f77SDag-Erling Smørgrav }
78*b7579f77SDag-Erling Smørgrav 
79*b7579f77SDag-Erling Smørgrav void
80*b7579f77SDag-Erling Smørgrav key_entry_delkeyfunc(void* key, void* ATTR_UNUSED(userarg))
81*b7579f77SDag-Erling Smørgrav {
82*b7579f77SDag-Erling Smørgrav 	struct key_entry_key* kk = (struct key_entry_key*)key;
83*b7579f77SDag-Erling Smørgrav 	if(!key)
84*b7579f77SDag-Erling Smørgrav 		return;
85*b7579f77SDag-Erling Smørgrav 	lock_rw_destroy(&kk->entry.lock);
86*b7579f77SDag-Erling Smørgrav 	free(kk->name);
87*b7579f77SDag-Erling Smørgrav 	free(kk);
88*b7579f77SDag-Erling Smørgrav }
89*b7579f77SDag-Erling Smørgrav 
90*b7579f77SDag-Erling Smørgrav void
91*b7579f77SDag-Erling Smørgrav key_entry_deldatafunc(void* data, void* ATTR_UNUSED(userarg))
92*b7579f77SDag-Erling Smørgrav {
93*b7579f77SDag-Erling Smørgrav 	struct key_entry_data* kd = (struct key_entry_data*)data;
94*b7579f77SDag-Erling Smørgrav 	free(kd->reason);
95*b7579f77SDag-Erling Smørgrav 	free(kd->rrset_data);
96*b7579f77SDag-Erling Smørgrav 	free(kd->algo);
97*b7579f77SDag-Erling Smørgrav 	free(kd);
98*b7579f77SDag-Erling Smørgrav }
99*b7579f77SDag-Erling Smørgrav 
100*b7579f77SDag-Erling Smørgrav void
101*b7579f77SDag-Erling Smørgrav key_entry_hash(struct key_entry_key* kk)
102*b7579f77SDag-Erling Smørgrav {
103*b7579f77SDag-Erling Smørgrav 	kk->entry.hash = 0x654;
104*b7579f77SDag-Erling Smørgrav 	kk->entry.hash = hashlittle(&kk->key_class, sizeof(kk->key_class),
105*b7579f77SDag-Erling Smørgrav 		kk->entry.hash);
106*b7579f77SDag-Erling Smørgrav 	kk->entry.hash = dname_query_hash(kk->name, kk->entry.hash);
107*b7579f77SDag-Erling Smørgrav }
108*b7579f77SDag-Erling Smørgrav 
109*b7579f77SDag-Erling Smørgrav struct key_entry_key*
110*b7579f77SDag-Erling Smørgrav key_entry_copy_toregion(struct key_entry_key* kkey, struct regional* region)
111*b7579f77SDag-Erling Smørgrav {
112*b7579f77SDag-Erling Smørgrav 	struct key_entry_key* newk;
113*b7579f77SDag-Erling Smørgrav 	newk = regional_alloc_init(region, kkey, sizeof(*kkey));
114*b7579f77SDag-Erling Smørgrav 	if(!newk)
115*b7579f77SDag-Erling Smørgrav 		return NULL;
116*b7579f77SDag-Erling Smørgrav 	newk->name = regional_alloc_init(region, kkey->name, kkey->namelen);
117*b7579f77SDag-Erling Smørgrav 	if(!newk->name)
118*b7579f77SDag-Erling Smørgrav 		return NULL;
119*b7579f77SDag-Erling Smørgrav 	newk->entry.key = newk;
120*b7579f77SDag-Erling Smørgrav 	if(newk->entry.data) {
121*b7579f77SDag-Erling Smørgrav 		/* copy data element */
122*b7579f77SDag-Erling Smørgrav 		struct key_entry_data *d = (struct key_entry_data*)
123*b7579f77SDag-Erling Smørgrav 			kkey->entry.data;
124*b7579f77SDag-Erling Smørgrav 		struct key_entry_data *newd;
125*b7579f77SDag-Erling Smørgrav 		newd = regional_alloc_init(region, d, sizeof(*d));
126*b7579f77SDag-Erling Smørgrav 		if(!newd)
127*b7579f77SDag-Erling Smørgrav 			return NULL;
128*b7579f77SDag-Erling Smørgrav 		/* copy rrset */
129*b7579f77SDag-Erling Smørgrav 		if(d->rrset_data) {
130*b7579f77SDag-Erling Smørgrav 			newd->rrset_data = regional_alloc_init(region,
131*b7579f77SDag-Erling Smørgrav 				d->rrset_data,
132*b7579f77SDag-Erling Smørgrav 				packed_rrset_sizeof(d->rrset_data));
133*b7579f77SDag-Erling Smørgrav 			if(!newd->rrset_data)
134*b7579f77SDag-Erling Smørgrav 				return NULL;
135*b7579f77SDag-Erling Smørgrav 			packed_rrset_ptr_fixup(newd->rrset_data);
136*b7579f77SDag-Erling Smørgrav 		}
137*b7579f77SDag-Erling Smørgrav 		if(d->reason) {
138*b7579f77SDag-Erling Smørgrav 			newd->reason = regional_strdup(region, d->reason);
139*b7579f77SDag-Erling Smørgrav 			if(!newd->reason)
140*b7579f77SDag-Erling Smørgrav 				return NULL;
141*b7579f77SDag-Erling Smørgrav 		}
142*b7579f77SDag-Erling Smørgrav 		if(d->algo) {
143*b7579f77SDag-Erling Smørgrav 			newd->algo = (uint8_t*)regional_strdup(region,
144*b7579f77SDag-Erling Smørgrav 				(char*)d->algo);
145*b7579f77SDag-Erling Smørgrav 			if(!newd->algo)
146*b7579f77SDag-Erling Smørgrav 				return NULL;
147*b7579f77SDag-Erling Smørgrav 		}
148*b7579f77SDag-Erling Smørgrav 		newk->entry.data = newd;
149*b7579f77SDag-Erling Smørgrav 	}
150*b7579f77SDag-Erling Smørgrav 	return newk;
151*b7579f77SDag-Erling Smørgrav }
152*b7579f77SDag-Erling Smørgrav 
153*b7579f77SDag-Erling Smørgrav struct key_entry_key*
154*b7579f77SDag-Erling Smørgrav key_entry_copy(struct key_entry_key* kkey)
155*b7579f77SDag-Erling Smørgrav {
156*b7579f77SDag-Erling Smørgrav 	struct key_entry_key* newk;
157*b7579f77SDag-Erling Smørgrav 	if(!kkey)
158*b7579f77SDag-Erling Smørgrav 		return NULL;
159*b7579f77SDag-Erling Smørgrav 	newk = memdup(kkey, sizeof(*kkey));
160*b7579f77SDag-Erling Smørgrav 	if(!newk)
161*b7579f77SDag-Erling Smørgrav 		return NULL;
162*b7579f77SDag-Erling Smørgrav 	newk->name = memdup(kkey->name, kkey->namelen);
163*b7579f77SDag-Erling Smørgrav 	if(!newk->name) {
164*b7579f77SDag-Erling Smørgrav 		free(newk);
165*b7579f77SDag-Erling Smørgrav 		return NULL;
166*b7579f77SDag-Erling Smørgrav 	}
167*b7579f77SDag-Erling Smørgrav 	lock_rw_init(&newk->entry.lock);
168*b7579f77SDag-Erling Smørgrav 	newk->entry.key = newk;
169*b7579f77SDag-Erling Smørgrav 	if(newk->entry.data) {
170*b7579f77SDag-Erling Smørgrav 		/* copy data element */
171*b7579f77SDag-Erling Smørgrav 		struct key_entry_data *d = (struct key_entry_data*)
172*b7579f77SDag-Erling Smørgrav 			kkey->entry.data;
173*b7579f77SDag-Erling Smørgrav 		struct key_entry_data *newd;
174*b7579f77SDag-Erling Smørgrav 		newd = memdup(d, sizeof(*d));
175*b7579f77SDag-Erling Smørgrav 		if(!newd) {
176*b7579f77SDag-Erling Smørgrav 			free(newk->name);
177*b7579f77SDag-Erling Smørgrav 			free(newk);
178*b7579f77SDag-Erling Smørgrav 			return NULL;
179*b7579f77SDag-Erling Smørgrav 		}
180*b7579f77SDag-Erling Smørgrav 		/* copy rrset */
181*b7579f77SDag-Erling Smørgrav 		if(d->rrset_data) {
182*b7579f77SDag-Erling Smørgrav 			newd->rrset_data = memdup(d->rrset_data,
183*b7579f77SDag-Erling Smørgrav 				packed_rrset_sizeof(d->rrset_data));
184*b7579f77SDag-Erling Smørgrav 			if(!newd->rrset_data) {
185*b7579f77SDag-Erling Smørgrav 				free(newd);
186*b7579f77SDag-Erling Smørgrav 				free(newk->name);
187*b7579f77SDag-Erling Smørgrav 				free(newk);
188*b7579f77SDag-Erling Smørgrav 				return NULL;
189*b7579f77SDag-Erling Smørgrav 			}
190*b7579f77SDag-Erling Smørgrav 			packed_rrset_ptr_fixup(newd->rrset_data);
191*b7579f77SDag-Erling Smørgrav 		}
192*b7579f77SDag-Erling Smørgrav 		if(d->reason) {
193*b7579f77SDag-Erling Smørgrav 			newd->reason = strdup(d->reason);
194*b7579f77SDag-Erling Smørgrav 			if(!newd->reason) {
195*b7579f77SDag-Erling Smørgrav 				free(newd->rrset_data);
196*b7579f77SDag-Erling Smørgrav 				free(newd);
197*b7579f77SDag-Erling Smørgrav 				free(newk->name);
198*b7579f77SDag-Erling Smørgrav 				free(newk);
199*b7579f77SDag-Erling Smørgrav 				return NULL;
200*b7579f77SDag-Erling Smørgrav 			}
201*b7579f77SDag-Erling Smørgrav 		}
202*b7579f77SDag-Erling Smørgrav 		if(d->algo) {
203*b7579f77SDag-Erling Smørgrav 			newd->algo = (uint8_t*)strdup((char*)d->algo);
204*b7579f77SDag-Erling Smørgrav 			if(!newd->algo) {
205*b7579f77SDag-Erling Smørgrav 				free(newd->rrset_data);
206*b7579f77SDag-Erling Smørgrav 				free(newd->reason);
207*b7579f77SDag-Erling Smørgrav 				free(newd);
208*b7579f77SDag-Erling Smørgrav 				free(newk->name);
209*b7579f77SDag-Erling Smørgrav 				free(newk);
210*b7579f77SDag-Erling Smørgrav 				return NULL;
211*b7579f77SDag-Erling Smørgrav 			}
212*b7579f77SDag-Erling Smørgrav 		}
213*b7579f77SDag-Erling Smørgrav 		newk->entry.data = newd;
214*b7579f77SDag-Erling Smørgrav 	}
215*b7579f77SDag-Erling Smørgrav 	return newk;
216*b7579f77SDag-Erling Smørgrav }
217*b7579f77SDag-Erling Smørgrav 
218*b7579f77SDag-Erling Smørgrav int
219*b7579f77SDag-Erling Smørgrav key_entry_isnull(struct key_entry_key* kkey)
220*b7579f77SDag-Erling Smørgrav {
221*b7579f77SDag-Erling Smørgrav 	struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
222*b7579f77SDag-Erling Smørgrav 	return (!d->isbad && d->rrset_data == NULL);
223*b7579f77SDag-Erling Smørgrav }
224*b7579f77SDag-Erling Smørgrav 
225*b7579f77SDag-Erling Smørgrav int
226*b7579f77SDag-Erling Smørgrav key_entry_isgood(struct key_entry_key* kkey)
227*b7579f77SDag-Erling Smørgrav {
228*b7579f77SDag-Erling Smørgrav 	struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
229*b7579f77SDag-Erling Smørgrav 	return (!d->isbad && d->rrset_data != NULL);
230*b7579f77SDag-Erling Smørgrav }
231*b7579f77SDag-Erling Smørgrav 
232*b7579f77SDag-Erling Smørgrav int
233*b7579f77SDag-Erling Smørgrav key_entry_isbad(struct key_entry_key* kkey)
234*b7579f77SDag-Erling Smørgrav {
235*b7579f77SDag-Erling Smørgrav 	struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
236*b7579f77SDag-Erling Smørgrav 	return (int)(d->isbad);
237*b7579f77SDag-Erling Smørgrav }
238*b7579f77SDag-Erling Smørgrav 
239*b7579f77SDag-Erling Smørgrav void
240*b7579f77SDag-Erling Smørgrav key_entry_set_reason(struct key_entry_key* kkey, char* reason)
241*b7579f77SDag-Erling Smørgrav {
242*b7579f77SDag-Erling Smørgrav 	struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
243*b7579f77SDag-Erling Smørgrav 	d->reason = reason;
244*b7579f77SDag-Erling Smørgrav }
245*b7579f77SDag-Erling Smørgrav 
246*b7579f77SDag-Erling Smørgrav char*
247*b7579f77SDag-Erling Smørgrav key_entry_get_reason(struct key_entry_key* kkey)
248*b7579f77SDag-Erling Smørgrav {
249*b7579f77SDag-Erling Smørgrav 	struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
250*b7579f77SDag-Erling Smørgrav 	return d->reason;
251*b7579f77SDag-Erling Smørgrav }
252*b7579f77SDag-Erling Smørgrav 
253*b7579f77SDag-Erling Smørgrav /** setup key entry in region */
254*b7579f77SDag-Erling Smørgrav static int
255*b7579f77SDag-Erling Smørgrav key_entry_setup(struct regional* region,
256*b7579f77SDag-Erling Smørgrav 	uint8_t* name, size_t namelen, uint16_t dclass,
257*b7579f77SDag-Erling Smørgrav 	struct key_entry_key** k, struct key_entry_data** d)
258*b7579f77SDag-Erling Smørgrav {
259*b7579f77SDag-Erling Smørgrav 	*k = regional_alloc(region, sizeof(**k));
260*b7579f77SDag-Erling Smørgrav 	if(!*k)
261*b7579f77SDag-Erling Smørgrav 		return 0;
262*b7579f77SDag-Erling Smørgrav 	memset(*k, 0, sizeof(**k));
263*b7579f77SDag-Erling Smørgrav 	(*k)->entry.key = *k;
264*b7579f77SDag-Erling Smørgrav 	(*k)->name = regional_alloc_init(region, name, namelen);
265*b7579f77SDag-Erling Smørgrav 	if(!(*k)->name)
266*b7579f77SDag-Erling Smørgrav 		return 0;
267*b7579f77SDag-Erling Smørgrav 	(*k)->namelen = namelen;
268*b7579f77SDag-Erling Smørgrav 	(*k)->key_class = dclass;
269*b7579f77SDag-Erling Smørgrav 	*d = regional_alloc(region, sizeof(**d));
270*b7579f77SDag-Erling Smørgrav 	if(!*d)
271*b7579f77SDag-Erling Smørgrav 		return 0;
272*b7579f77SDag-Erling Smørgrav 	(*k)->entry.data = *d;
273*b7579f77SDag-Erling Smørgrav 	return 1;
274*b7579f77SDag-Erling Smørgrav }
275*b7579f77SDag-Erling Smørgrav 
276*b7579f77SDag-Erling Smørgrav struct key_entry_key*
277*b7579f77SDag-Erling Smørgrav key_entry_create_null(struct regional* region,
278*b7579f77SDag-Erling Smørgrav 	uint8_t* name, size_t namelen, uint16_t dclass, uint32_t ttl,
279*b7579f77SDag-Erling Smørgrav 	uint32_t now)
280*b7579f77SDag-Erling Smørgrav {
281*b7579f77SDag-Erling Smørgrav 	struct key_entry_key* k;
282*b7579f77SDag-Erling Smørgrav 	struct key_entry_data* d;
283*b7579f77SDag-Erling Smørgrav 	if(!key_entry_setup(region, name, namelen, dclass, &k, &d))
284*b7579f77SDag-Erling Smørgrav 		return NULL;
285*b7579f77SDag-Erling Smørgrav 	d->ttl = now + ttl;
286*b7579f77SDag-Erling Smørgrav 	d->isbad = 0;
287*b7579f77SDag-Erling Smørgrav 	d->reason = NULL;
288*b7579f77SDag-Erling Smørgrav 	d->rrset_type = LDNS_RR_TYPE_DNSKEY;
289*b7579f77SDag-Erling Smørgrav 	d->rrset_data = NULL;
290*b7579f77SDag-Erling Smørgrav 	d->algo = NULL;
291*b7579f77SDag-Erling Smørgrav 	return k;
292*b7579f77SDag-Erling Smørgrav }
293*b7579f77SDag-Erling Smørgrav 
294*b7579f77SDag-Erling Smørgrav struct key_entry_key*
295*b7579f77SDag-Erling Smørgrav key_entry_create_rrset(struct regional* region,
296*b7579f77SDag-Erling Smørgrav 	uint8_t* name, size_t namelen, uint16_t dclass,
297*b7579f77SDag-Erling Smørgrav 	struct ub_packed_rrset_key* rrset, uint8_t* sigalg, uint32_t now)
298*b7579f77SDag-Erling Smørgrav {
299*b7579f77SDag-Erling Smørgrav 	struct key_entry_key* k;
300*b7579f77SDag-Erling Smørgrav 	struct key_entry_data* d;
301*b7579f77SDag-Erling Smørgrav 	struct packed_rrset_data* rd = (struct packed_rrset_data*)
302*b7579f77SDag-Erling Smørgrav 		rrset->entry.data;
303*b7579f77SDag-Erling Smørgrav 	if(!key_entry_setup(region, name, namelen, dclass, &k, &d))
304*b7579f77SDag-Erling Smørgrav 		return NULL;
305*b7579f77SDag-Erling Smørgrav 	d->ttl = rd->ttl + now;
306*b7579f77SDag-Erling Smørgrav 	d->isbad = 0;
307*b7579f77SDag-Erling Smørgrav 	d->reason = NULL;
308*b7579f77SDag-Erling Smørgrav 	d->rrset_type = ntohs(rrset->rk.type);
309*b7579f77SDag-Erling Smørgrav 	d->rrset_data = (struct packed_rrset_data*)regional_alloc_init(region,
310*b7579f77SDag-Erling Smørgrav 		rd, packed_rrset_sizeof(rd));
311*b7579f77SDag-Erling Smørgrav 	if(!d->rrset_data)
312*b7579f77SDag-Erling Smørgrav 		return NULL;
313*b7579f77SDag-Erling Smørgrav 	if(sigalg) {
314*b7579f77SDag-Erling Smørgrav 		d->algo = (uint8_t*)regional_strdup(region, (char*)sigalg);
315*b7579f77SDag-Erling Smørgrav 		if(!d->algo)
316*b7579f77SDag-Erling Smørgrav 			return NULL;
317*b7579f77SDag-Erling Smørgrav 	} else d->algo = NULL;
318*b7579f77SDag-Erling Smørgrav 	packed_rrset_ptr_fixup(d->rrset_data);
319*b7579f77SDag-Erling Smørgrav 	return k;
320*b7579f77SDag-Erling Smørgrav }
321*b7579f77SDag-Erling Smørgrav 
322*b7579f77SDag-Erling Smørgrav struct key_entry_key*
323*b7579f77SDag-Erling Smørgrav key_entry_create_bad(struct regional* region,
324*b7579f77SDag-Erling Smørgrav 	uint8_t* name, size_t namelen, uint16_t dclass, uint32_t ttl,
325*b7579f77SDag-Erling Smørgrav 	uint32_t now)
326*b7579f77SDag-Erling Smørgrav {
327*b7579f77SDag-Erling Smørgrav 	struct key_entry_key* k;
328*b7579f77SDag-Erling Smørgrav 	struct key_entry_data* d;
329*b7579f77SDag-Erling Smørgrav 	if(!key_entry_setup(region, name, namelen, dclass, &k, &d))
330*b7579f77SDag-Erling Smørgrav 		return NULL;
331*b7579f77SDag-Erling Smørgrav 	d->ttl = now + ttl;
332*b7579f77SDag-Erling Smørgrav 	d->isbad = 1;
333*b7579f77SDag-Erling Smørgrav 	d->reason = NULL;
334*b7579f77SDag-Erling Smørgrav 	d->rrset_type = LDNS_RR_TYPE_DNSKEY;
335*b7579f77SDag-Erling Smørgrav 	d->rrset_data = NULL;
336*b7579f77SDag-Erling Smørgrav 	d->algo = NULL;
337*b7579f77SDag-Erling Smørgrav 	return k;
338*b7579f77SDag-Erling Smørgrav }
339*b7579f77SDag-Erling Smørgrav 
340*b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key*
341*b7579f77SDag-Erling Smørgrav key_entry_get_rrset(struct key_entry_key* kkey, struct regional* region)
342*b7579f77SDag-Erling Smørgrav {
343*b7579f77SDag-Erling Smørgrav 	struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
344*b7579f77SDag-Erling Smørgrav 	struct ub_packed_rrset_key* rrk;
345*b7579f77SDag-Erling Smørgrav 	struct packed_rrset_data* rrd;
346*b7579f77SDag-Erling Smørgrav 	if(!d || !d->rrset_data)
347*b7579f77SDag-Erling Smørgrav 		return NULL;
348*b7579f77SDag-Erling Smørgrav 	rrk = regional_alloc(region, sizeof(*rrk));
349*b7579f77SDag-Erling Smørgrav 	if(!rrk)
350*b7579f77SDag-Erling Smørgrav 		return NULL;
351*b7579f77SDag-Erling Smørgrav 	memset(rrk, 0, sizeof(*rrk));
352*b7579f77SDag-Erling Smørgrav 	rrk->rk.dname = regional_alloc_init(region, kkey->name, kkey->namelen);
353*b7579f77SDag-Erling Smørgrav 	if(!rrk->rk.dname)
354*b7579f77SDag-Erling Smørgrav 		return NULL;
355*b7579f77SDag-Erling Smørgrav 	rrk->rk.dname_len = kkey->namelen;
356*b7579f77SDag-Erling Smørgrav 	rrk->rk.type = htons(d->rrset_type);
357*b7579f77SDag-Erling Smørgrav 	rrk->rk.rrset_class = htons(kkey->key_class);
358*b7579f77SDag-Erling Smørgrav 	rrk->entry.key = rrk;
359*b7579f77SDag-Erling Smørgrav 	rrd = regional_alloc_init(region, d->rrset_data,
360*b7579f77SDag-Erling Smørgrav 		packed_rrset_sizeof(d->rrset_data));
361*b7579f77SDag-Erling Smørgrav 	if(!rrd)
362*b7579f77SDag-Erling Smørgrav 		return NULL;
363*b7579f77SDag-Erling Smørgrav 	rrk->entry.data = rrd;
364*b7579f77SDag-Erling Smørgrav 	packed_rrset_ptr_fixup(rrd);
365*b7579f77SDag-Erling Smørgrav 	return rrk;
366*b7579f77SDag-Erling Smørgrav }
367*b7579f77SDag-Erling Smørgrav 
368*b7579f77SDag-Erling Smørgrav /** Get size of key in keyset */
369*b7579f77SDag-Erling Smørgrav static size_t
370*b7579f77SDag-Erling Smørgrav dnskey_get_keysize(struct packed_rrset_data* data, size_t idx)
371*b7579f77SDag-Erling Smørgrav {
372*b7579f77SDag-Erling Smørgrav 	unsigned char* pk;
373*b7579f77SDag-Erling Smørgrav 	unsigned int pklen = 0;
374*b7579f77SDag-Erling Smørgrav 	int algo;
375*b7579f77SDag-Erling Smørgrav 	if(data->rr_len[idx] < 2+5)
376*b7579f77SDag-Erling Smørgrav 		return 0;
377*b7579f77SDag-Erling Smørgrav 	algo = (int)data->rr_data[idx][2+3];
378*b7579f77SDag-Erling Smørgrav 	pk = (unsigned char*)data->rr_data[idx]+2+4;
379*b7579f77SDag-Erling Smørgrav 	pklen = (unsigned)data->rr_len[idx]-2-4;
380*b7579f77SDag-Erling Smørgrav 	return ldns_rr_dnskey_key_size_raw(pk, pklen, algo);
381*b7579f77SDag-Erling Smørgrav }
382*b7579f77SDag-Erling Smørgrav 
383*b7579f77SDag-Erling Smørgrav /** get dnskey flags from data */
384*b7579f77SDag-Erling Smørgrav static uint16_t
385*b7579f77SDag-Erling Smørgrav kd_get_flags(struct packed_rrset_data* data, size_t idx)
386*b7579f77SDag-Erling Smørgrav {
387*b7579f77SDag-Erling Smørgrav 	uint16_t f;
388*b7579f77SDag-Erling Smørgrav 	if(data->rr_len[idx] < 2+2)
389*b7579f77SDag-Erling Smørgrav 		return 0;
390*b7579f77SDag-Erling Smørgrav 	memmove(&f, data->rr_data[idx]+2, 2);
391*b7579f77SDag-Erling Smørgrav 	f = ntohs(f);
392*b7579f77SDag-Erling Smørgrav 	return f;
393*b7579f77SDag-Erling Smørgrav }
394*b7579f77SDag-Erling Smørgrav 
395*b7579f77SDag-Erling Smørgrav size_t
396*b7579f77SDag-Erling Smørgrav key_entry_keysize(struct key_entry_key* kkey)
397*b7579f77SDag-Erling Smørgrav {
398*b7579f77SDag-Erling Smørgrav 	struct packed_rrset_data* d;
399*b7579f77SDag-Erling Smørgrav 	/* compute size of smallest ZSK key in the rrset */
400*b7579f77SDag-Erling Smørgrav 	size_t i;
401*b7579f77SDag-Erling Smørgrav 	size_t bits = 0;
402*b7579f77SDag-Erling Smørgrav 	if(!key_entry_isgood(kkey))
403*b7579f77SDag-Erling Smørgrav 		return 0;
404*b7579f77SDag-Erling Smørgrav 	d = ((struct key_entry_data*)kkey->entry.data)->rrset_data;
405*b7579f77SDag-Erling Smørgrav 	for(i=0; i<d->count; i++) {
406*b7579f77SDag-Erling Smørgrav 		if(!(kd_get_flags(d, i) & DNSKEY_BIT_ZSK))
407*b7579f77SDag-Erling Smørgrav 			continue;
408*b7579f77SDag-Erling Smørgrav 		if(i==0 || dnskey_get_keysize(d, i) < bits)
409*b7579f77SDag-Erling Smørgrav 			bits = dnskey_get_keysize(d, i);
410*b7579f77SDag-Erling Smørgrav 	}
411*b7579f77SDag-Erling Smørgrav 	return bits;
412*b7579f77SDag-Erling Smørgrav }
413