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