2 * validator/val_kentry.c - validator key entry definition.
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
6 * This software is open source.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
39 * This file contains functions for dealing with validator key entries.
42 #include <ldns/ldns.h>
43 #include "validator/val_kentry.h"
44 #include "util/data/packed_rrset.h"
45 #include "util/data/dname.h"
46 #include "util/storage/lookup3.h"
47 #include "util/regional.h"
48 #include "util/net_help.h"
51 key_entry_sizefunc(void* key, void* data)
53 struct key_entry_key* kk = (struct key_entry_key*)key;
54 struct key_entry_data* kd = (struct key_entry_data*)data;
55 size_t s = sizeof(*kk) + kk->namelen;
56 s += sizeof(*kd) + lock_get_mem(&kk->entry.lock);
58 s += packed_rrset_sizeof(kd->rrset_data);
60 s += strlen(kd->reason)+1;
62 s += strlen((char*)kd->algo)+1;
67 key_entry_compfunc(void* k1, void* k2)
69 struct key_entry_key* n1 = (struct key_entry_key*)k1;
70 struct key_entry_key* n2 = (struct key_entry_key*)k2;
71 if(n1->key_class != n2->key_class) {
72 if(n1->key_class < n2->key_class)
76 return query_dname_compare(n1->name, n2->name);
80 key_entry_delkeyfunc(void* key, void* ATTR_UNUSED(userarg))
82 struct key_entry_key* kk = (struct key_entry_key*)key;
85 lock_rw_destroy(&kk->entry.lock);
91 key_entry_deldatafunc(void* data, void* ATTR_UNUSED(userarg))
93 struct key_entry_data* kd = (struct key_entry_data*)data;
101 key_entry_hash(struct key_entry_key* kk)
103 kk->entry.hash = 0x654;
104 kk->entry.hash = hashlittle(&kk->key_class, sizeof(kk->key_class),
106 kk->entry.hash = dname_query_hash(kk->name, kk->entry.hash);
109 struct key_entry_key*
110 key_entry_copy_toregion(struct key_entry_key* kkey, struct regional* region)
112 struct key_entry_key* newk;
113 newk = regional_alloc_init(region, kkey, sizeof(*kkey));
116 newk->name = regional_alloc_init(region, kkey->name, kkey->namelen);
119 newk->entry.key = newk;
120 if(newk->entry.data) {
121 /* copy data element */
122 struct key_entry_data *d = (struct key_entry_data*)
124 struct key_entry_data *newd;
125 newd = regional_alloc_init(region, d, sizeof(*d));
130 newd->rrset_data = regional_alloc_init(region,
132 packed_rrset_sizeof(d->rrset_data));
133 if(!newd->rrset_data)
135 packed_rrset_ptr_fixup(newd->rrset_data);
138 newd->reason = regional_strdup(region, d->reason);
143 newd->algo = (uint8_t*)regional_strdup(region,
148 newk->entry.data = newd;
153 struct key_entry_key*
154 key_entry_copy(struct key_entry_key* kkey)
156 struct key_entry_key* newk;
159 newk = memdup(kkey, sizeof(*kkey));
162 newk->name = memdup(kkey->name, kkey->namelen);
167 lock_rw_init(&newk->entry.lock);
168 newk->entry.key = newk;
169 if(newk->entry.data) {
170 /* copy data element */
171 struct key_entry_data *d = (struct key_entry_data*)
173 struct key_entry_data *newd;
174 newd = memdup(d, sizeof(*d));
182 newd->rrset_data = memdup(d->rrset_data,
183 packed_rrset_sizeof(d->rrset_data));
184 if(!newd->rrset_data) {
190 packed_rrset_ptr_fixup(newd->rrset_data);
193 newd->reason = strdup(d->reason);
195 free(newd->rrset_data);
203 newd->algo = (uint8_t*)strdup((char*)d->algo);
205 free(newd->rrset_data);
213 newk->entry.data = newd;
219 key_entry_isnull(struct key_entry_key* kkey)
221 struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
222 return (!d->isbad && d->rrset_data == NULL);
226 key_entry_isgood(struct key_entry_key* kkey)
228 struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
229 return (!d->isbad && d->rrset_data != NULL);
233 key_entry_isbad(struct key_entry_key* kkey)
235 struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
236 return (int)(d->isbad);
240 key_entry_set_reason(struct key_entry_key* kkey, char* reason)
242 struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
247 key_entry_get_reason(struct key_entry_key* kkey)
249 struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
253 /** setup key entry in region */
255 key_entry_setup(struct regional* region,
256 uint8_t* name, size_t namelen, uint16_t dclass,
257 struct key_entry_key** k, struct key_entry_data** d)
259 *k = regional_alloc(region, sizeof(**k));
262 memset(*k, 0, sizeof(**k));
263 (*k)->entry.key = *k;
264 (*k)->name = regional_alloc_init(region, name, namelen);
267 (*k)->namelen = namelen;
268 (*k)->key_class = dclass;
269 *d = regional_alloc(region, sizeof(**d));
272 (*k)->entry.data = *d;
276 struct key_entry_key*
277 key_entry_create_null(struct regional* region,
278 uint8_t* name, size_t namelen, uint16_t dclass, uint32_t ttl,
281 struct key_entry_key* k;
282 struct key_entry_data* d;
283 if(!key_entry_setup(region, name, namelen, dclass, &k, &d))
288 d->rrset_type = LDNS_RR_TYPE_DNSKEY;
289 d->rrset_data = NULL;
294 struct key_entry_key*
295 key_entry_create_rrset(struct regional* region,
296 uint8_t* name, size_t namelen, uint16_t dclass,
297 struct ub_packed_rrset_key* rrset, uint8_t* sigalg, uint32_t now)
299 struct key_entry_key* k;
300 struct key_entry_data* d;
301 struct packed_rrset_data* rd = (struct packed_rrset_data*)
303 if(!key_entry_setup(region, name, namelen, dclass, &k, &d))
305 d->ttl = rd->ttl + now;
308 d->rrset_type = ntohs(rrset->rk.type);
309 d->rrset_data = (struct packed_rrset_data*)regional_alloc_init(region,
310 rd, packed_rrset_sizeof(rd));
314 d->algo = (uint8_t*)regional_strdup(region, (char*)sigalg);
317 } else d->algo = NULL;
318 packed_rrset_ptr_fixup(d->rrset_data);
322 struct key_entry_key*
323 key_entry_create_bad(struct regional* region,
324 uint8_t* name, size_t namelen, uint16_t dclass, uint32_t ttl,
327 struct key_entry_key* k;
328 struct key_entry_data* d;
329 if(!key_entry_setup(region, name, namelen, dclass, &k, &d))
334 d->rrset_type = LDNS_RR_TYPE_DNSKEY;
335 d->rrset_data = NULL;
340 struct ub_packed_rrset_key*
341 key_entry_get_rrset(struct key_entry_key* kkey, struct regional* region)
343 struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
344 struct ub_packed_rrset_key* rrk;
345 struct packed_rrset_data* rrd;
346 if(!d || !d->rrset_data)
348 rrk = regional_alloc(region, sizeof(*rrk));
351 memset(rrk, 0, sizeof(*rrk));
352 rrk->rk.dname = regional_alloc_init(region, kkey->name, kkey->namelen);
355 rrk->rk.dname_len = kkey->namelen;
356 rrk->rk.type = htons(d->rrset_type);
357 rrk->rk.rrset_class = htons(kkey->key_class);
358 rrk->entry.key = rrk;
359 rrd = regional_alloc_init(region, d->rrset_data,
360 packed_rrset_sizeof(d->rrset_data));
363 rrk->entry.data = rrd;
364 packed_rrset_ptr_fixup(rrd);
368 /** Get size of key in keyset */
370 dnskey_get_keysize(struct packed_rrset_data* data, size_t idx)
373 unsigned int pklen = 0;
375 if(data->rr_len[idx] < 2+5)
377 algo = (int)data->rr_data[idx][2+3];
378 pk = (unsigned char*)data->rr_data[idx]+2+4;
379 pklen = (unsigned)data->rr_len[idx]-2-4;
380 return ldns_rr_dnskey_key_size_raw(pk, pklen, algo);
383 /** get dnskey flags from data */
385 kd_get_flags(struct packed_rrset_data* data, size_t idx)
388 if(data->rr_len[idx] < 2+2)
390 memmove(&f, data->rr_data[idx]+2, 2);
396 key_entry_keysize(struct key_entry_key* kkey)
398 struct packed_rrset_data* d;
399 /* compute size of smallest ZSK key in the rrset */
402 if(!key_entry_isgood(kkey))
404 d = ((struct key_entry_data*)kkey->entry.data)->rrset_data;
405 for(i=0; i<d->count; i++) {
406 if(!(kd_get_flags(d, i) & DNSKEY_BIT_ZSK))
408 if(i==0 || dnskey_get_keysize(d, i) < bits)
409 bits = dnskey_get_keysize(d, i);