OpenDNSSEC-signer  1.3.9
keys.c
Go to the documentation of this file.
1 /*
2  * $Id: keys.c 6237 2012-04-03 09:38:16Z matthijs $
3  *
4  * Copyright (c) 2009 NLNet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "shared/allocator.h"
35 #include "shared/file.h"
36 #include "shared/log.h"
37 #include "shared/status.h"
38 #include "signer/backup.h"
39 #include "signer/keys.h"
40 
41 static const char* key_str = "keys";
42 
43 
48 key_type*
49 key_create(allocator_type* allocator, const char* locator, uint8_t algorithm,
50  uint32_t flags, int publish, int ksk, int zsk)
51 {
52  key_type* key;
53 
54  if (!allocator) {
55  ods_log_error("[%s] create key failed: no allocator available",
56  key_str);
57  return NULL;
58  }
59  ods_log_assert(allocator);
60 
61  if (!locator || !algorithm || !flags) {
62  ods_log_error("[%s] create failed: missing required elements",
63  key_str);
64  return NULL;
65  }
66  ods_log_assert(locator);
67  ods_log_assert(algorithm);
68  ods_log_assert(flags);
69 
70  key = (key_type*) allocator_alloc(allocator, sizeof(key_type));
71  if (!key) {
72  ods_log_error("[%s] create key failed: allocator failed",
73  key_str);
74  return NULL;
75  }
76  ods_log_assert(key);
77 
78  key->allocator = allocator;
79  key->locator = allocator_strdup(allocator, locator);
80  key->dnskey = NULL;
81  key->hsmkey = NULL;
82  key->params = NULL;
83  key->algorithm = algorithm;
84  key->flags = flags;
85  key->publish = publish;
86  key->ksk = ksk;
87  key->zsk = zsk;
88  key->next = NULL;
89  return key;
90 }
91 
92 
97 key_type*
98 key_recover(FILE* fd, allocator_type* allocator)
99 {
100  key_type* key = NULL;
101  const char* locator = NULL;
102  uint8_t algorithm = 0;
103  uint32_t flags = 0;
104  int publish = 0;
105  int ksk = 0;
106  int zsk = 0;
107  ldns_rr* rr = NULL;
108 
109  ods_log_assert(fd);
110 
111  if (!backup_read_check_str(fd, "locator") ||
112  !backup_read_str(fd, &locator) ||
113  !backup_read_check_str(fd, "algorithm") ||
114  !backup_read_uint8_t(fd, &algorithm) ||
115  !backup_read_check_str(fd, "flags") ||
116  !backup_read_uint32_t(fd, &flags) ||
117  !backup_read_check_str(fd, "publish") ||
118  !backup_read_int(fd, &publish) ||
119  !backup_read_check_str(fd, "ksk") ||
120  !backup_read_int(fd, &ksk) ||
121  !backup_read_check_str(fd, "zsk") ||
122  !backup_read_int(fd, &zsk)) {
123 
124  ods_log_error("[%s] key in backup corrupted", key_str);
125  if (locator) {
126  free((void*)locator);
127  locator = NULL;
128  }
129  return NULL;
130  }
131 
132  if (publish &&
133  ldns_rr_new_frm_fp(&rr, fd, NULL, NULL, NULL) != LDNS_STATUS_OK) {
134  ods_log_error("[%s] key in backup is published, but no rr found",
135  key_str);
136  if (locator) {
137  free((void*)locator);
138  locator = NULL;
139  }
140  return NULL;
141  }
142 
143  if (!backup_read_check_str(fd, ";;Keydone")) {
144  ods_log_error("[%s] key in backup corrupted", key_str);
145  if (locator) {
146  free((void*)locator);
147  locator = NULL;
148  }
149  if (rr) {
150  ldns_rr_free(rr);
151  rr = NULL;
152  }
153  return NULL;
154  }
155 
156  /* key ok */
157  key = (key_type*) allocator_alloc(allocator, sizeof(key_type));
158  if (!key) {
159  ods_log_error("[%s] unable to recover key: allocator failed",
160  key_str);
161  if (locator) {
162  free((void*)locator);
163  locator = NULL;
164  }
165  if (rr) {
166  ldns_rr_free(rr);
167  rr = NULL;
168  }
169  return NULL;
170  }
171  ods_log_assert(key);
172 
173  key->allocator = allocator;
174  key->locator = allocator_strdup(allocator, locator);
175  key->dnskey = rr;
176  key->hsmkey = NULL;
177  key->params = NULL;
178  key->algorithm = algorithm;
179  key->flags = flags;
180  key->publish = publish;
181  key->ksk = ksk;
182  key->zsk = zsk;
183  key->next = NULL;
184 
185  if (locator) {
186  free((void*)locator);
187  locator = NULL;
188  }
189  return key;
190 }
191 
192 
197 static void
198 key_print(FILE* fd, key_type* key)
199 {
200  if (!fd || !key) {
201  return;
202  }
203  fprintf(fd, "\t\t\t<Key>\n");
204  fprintf(fd, "\t\t\t\t<Flags>%u</Flags>\n", key->flags);
205  fprintf(fd, "\t\t\t\t<Algorithm>%u</Algorithm>\n", key->algorithm);
206  if (key->locator) {
207  fprintf(fd, "\t\t\t\t<Locator>%s</Locator>\n", key->locator);
208  }
209  if (key->ksk) {
210  fprintf(fd, "\t\t\t\t<KSK />\n");
211  }
212  if (key->zsk) {
213  fprintf(fd, "\t\t\t\t<ZSK />\n");
214  }
215  if (key->publish) {
216  fprintf(fd, "\t\t\t\t<Publish />\n");
217  }
218  fprintf(fd, "\t\t\t</Key>\n");
219  fprintf(fd, "\n");
220  return;
221 }
222 
223 
228 static void
229 key_backup(FILE* fd, key_type* key)
230 {
231  if (!fd || !key) {
232  return;
233  }
234 
235  fprintf(fd, ";;Key: locator %s algorithm %u flags %u publish %i ksk %i "
236  "zsk %i\n", key->locator, (unsigned) key->algorithm,
237  (unsigned) key->flags, key->publish, key->ksk, key->zsk);
238  if (key->dnskey) {
239  ldns_rr_print(fd, key->dnskey);
240  }
241  fprintf(fd, ";;Keydone\n");
242  return;
243 }
244 
245 
250 static void
251 key_log(key_type* key, const char* name)
252 {
253  if (!key) {
254  return;
255  }
256  ods_log_verbose("[%s] zone %s key: LOCATOR[%s] FLAGS[%u] ALGORITHM[%u] "
257  "KSK[%i] ZSK[%i] PUBLISH[%i]", key_str, name?name:"(null)", key->locator,
258  key->flags, key->algorithm, key->ksk, key->zsk, key->publish);
259  return;
260 }
261 
262 
269 {
270  keylist_type* kl;
271 
272  if (!allocator) {
273  ods_log_error("[%s] create list failed: no allocator available",
274  key_str);
275  return NULL;
276  }
277  ods_log_assert(allocator);
278 
279  kl = (keylist_type*) allocator_alloc(allocator, sizeof(keylist_type));
280  if (!kl) {
281  ods_log_error("[%s] create list failed: allocator failed",
282  key_str);
283  return NULL;
284  }
285  ods_log_assert(kl);
286 
287  kl->allocator = allocator;
288  kl->count = 0;
289  kl->first_key = NULL;
290  return kl;
291 }
292 
293 
300 {
301  key_type* walk = NULL;
302 
303  if (!kl || !key || !key->locator) {
304  ods_log_error("[%s] push failed: no list or no key", key_str);
305  return ODS_STATUS_ASSERT_ERR;
306  }
307  ods_log_assert(kl);
308  ods_log_assert(key);
309  ods_log_debug("[%s] add locator %s", key_str, key->locator);
310 
311  if (kl->count == 0) {
312  kl->first_key = key;
313  } else {
314  walk = kl->first_key;
315  while (walk->next) {
316  walk = walk->next;
317  }
318  walk->next = key;
319  }
320  kl->count += 1;
321  return ODS_STATUS_OK;
322 }
323 
324 
329 key_type*
330 keylist_lookup(keylist_type* list, const char* locator)
331 {
332  key_type* search = NULL;
333  size_t i = 0;
334 
335  if (!list || !locator) {
336  return NULL;
337  }
338 
339  search = list->first_key;
340  for (i=0; i < list->count; i++) {
341  if (search && search->locator) {
342  if (ods_strcmp(search->locator, locator) == 0) {
343  return search;
344  }
345  search = search->next;
346  } else {
347  break;
348  }
349  }
350  return NULL;
351 }
352 
353 
358 key_type*
359 keylist_lookup_by_dnskey(keylist_type* list, ldns_rr* dnskey)
360 {
361  key_type* search = NULL;
362  size_t i = 0;
363 
364  if (!list || !dnskey) {
365  return NULL;
366  }
367 
368  search = list->first_key;
369  for (i=0; i < list->count; i++) {
370  if (search && search->dnskey) {
371  if (ldns_rr_compare(search->dnskey, dnskey) == 0) {
372  return search;
373  }
374  search = search->next;
375  } else {
376  break;
377  }
378  }
379  return NULL;
380 }
381 
382 
387 void
389 {
390  key_type* walk = NULL;
391 
392  if (fd && kl) {
393  walk = kl->first_key;
394  while (walk) {
395  key_print(fd, walk);
396  walk = walk->next;
397  }
398  }
399  return;
400 }
401 
402 
407 void
409 {
410  key_type* walk = NULL;
411 
412  if (fd) {
413  if (kl) {
414  walk = kl->first_key;
415  while (walk) {
416  key_backup(fd, walk);
417  walk = walk->next;
418  }
419  }
420  fprintf(fd, ";;\n");
421  }
422  return;
423 }
424 
425 
430 void
431 keylist_log(keylist_type* kl, const char* name)
432 {
433  key_type* walk = NULL;
434 
435  if (kl) {
436  walk = kl->first_key;
437  while (walk) {
438  key_log(walk, name);
439  walk = walk->next;
440  }
441  }
442  return;
443 }
444 
445 
450 static void
451 key_delfunc(key_type* key)
452 {
453  allocator_type* allocator;
454 
455  if (!key) {
456  return;
457  }
458  if (key->dnskey) {
459  ldns_rr_free(key->dnskey);
460  key->dnskey = NULL;
461  }
462  if (key->hsmkey) {
463  hsm_key_free(key->hsmkey);
464  key->hsmkey = NULL;
465  }
466  if (key->params) {
467  hsm_sign_params_free(key->params);
468  key->params = NULL;
469  }
470  allocator = key->allocator;
471  allocator_deallocate(allocator, (void*) key->locator);
472  allocator_deallocate(allocator, (void*) key);
473  return;
474 }
475 
476 
481 void
483 {
484  key_type* walk = NULL;
485  key_type* next = NULL;
486  allocator_type* allocator;
487 
488  if (!kl) {
489  return;
490  }
491  walk = kl->first_key;
492  while (walk) {
493  next = walk->next;
494  key_delfunc(walk);
495  walk = next;
496  }
497  allocator = kl->allocator;
498  allocator_deallocate(allocator, (void*) kl);
499  return;
500 }