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