OpenDNSSEC-signer
1.3.8
|
00001 /* 00002 * $Id: keys.c 6237 2012-04-03 09:38:16Z matthijs $ 00003 * 00004 * Copyright (c) 2009 NLNet Labs. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00019 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00020 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00021 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00023 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00024 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00025 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 */ 00028 00034 #include "shared/allocator.h" 00035 #include "shared/file.h" 00036 #include "shared/log.h" 00037 #include "shared/status.h" 00038 #include "signer/backup.h" 00039 #include "signer/keys.h" 00040 00041 static const char* key_str = "keys"; 00042 00043 00048 key_type* 00049 key_create(allocator_type* allocator, const char* locator, uint8_t algorithm, 00050 uint32_t flags, int publish, int ksk, int zsk) 00051 { 00052 key_type* key; 00053 00054 if (!allocator) { 00055 ods_log_error("[%s] create key failed: no allocator available", 00056 key_str); 00057 return NULL; 00058 } 00059 ods_log_assert(allocator); 00060 00061 if (!locator || !algorithm || !flags) { 00062 ods_log_error("[%s] create failed: missing required elements", 00063 key_str); 00064 return NULL; 00065 } 00066 ods_log_assert(locator); 00067 ods_log_assert(algorithm); 00068 ods_log_assert(flags); 00069 00070 key = (key_type*) allocator_alloc(allocator, sizeof(key_type)); 00071 if (!key) { 00072 ods_log_error("[%s] create key failed: allocator failed", 00073 key_str); 00074 return NULL; 00075 } 00076 ods_log_assert(key); 00077 00078 key->allocator = allocator; 00079 key->locator = allocator_strdup(allocator, locator); 00080 key->dnskey = NULL; 00081 key->hsmkey = NULL; 00082 key->params = NULL; 00083 key->algorithm = algorithm; 00084 key->flags = flags; 00085 key->publish = publish; 00086 key->ksk = ksk; 00087 key->zsk = zsk; 00088 key->next = NULL; 00089 return key; 00090 } 00091 00092 00097 key_type* 00098 key_recover(FILE* fd, allocator_type* allocator) 00099 { 00100 key_type* key = NULL; 00101 const char* locator = NULL; 00102 uint8_t algorithm = 0; 00103 uint32_t flags = 0; 00104 int publish = 0; 00105 int ksk = 0; 00106 int zsk = 0; 00107 ldns_rr* rr = NULL; 00108 00109 ods_log_assert(fd); 00110 00111 if (!backup_read_check_str(fd, "locator") || 00112 !backup_read_str(fd, &locator) || 00113 !backup_read_check_str(fd, "algorithm") || 00114 !backup_read_uint8_t(fd, &algorithm) || 00115 !backup_read_check_str(fd, "flags") || 00116 !backup_read_uint32_t(fd, &flags) || 00117 !backup_read_check_str(fd, "publish") || 00118 !backup_read_int(fd, &publish) || 00119 !backup_read_check_str(fd, "ksk") || 00120 !backup_read_int(fd, &ksk) || 00121 !backup_read_check_str(fd, "zsk") || 00122 !backup_read_int(fd, &zsk)) { 00123 00124 ods_log_error("[%s] key in backup corrupted", key_str); 00125 if (locator) { 00126 free((void*)locator); 00127 locator = NULL; 00128 } 00129 return NULL; 00130 } 00131 00132 if (publish && 00133 ldns_rr_new_frm_fp(&rr, fd, NULL, NULL, NULL) != LDNS_STATUS_OK) { 00134 ods_log_error("[%s] key in backup is published, but no rr found", 00135 key_str); 00136 if (locator) { 00137 free((void*)locator); 00138 locator = NULL; 00139 } 00140 return NULL; 00141 } 00142 00143 if (!backup_read_check_str(fd, ";;Keydone")) { 00144 ods_log_error("[%s] key in backup corrupted", key_str); 00145 if (locator) { 00146 free((void*)locator); 00147 locator = NULL; 00148 } 00149 if (rr) { 00150 ldns_rr_free(rr); 00151 rr = NULL; 00152 } 00153 return NULL; 00154 } 00155 00156 /* key ok */ 00157 key = (key_type*) allocator_alloc(allocator, sizeof(key_type)); 00158 if (!key) { 00159 ods_log_error("[%s] unable to recover key: allocator failed", 00160 key_str); 00161 if (locator) { 00162 free((void*)locator); 00163 locator = NULL; 00164 } 00165 if (rr) { 00166 ldns_rr_free(rr); 00167 rr = NULL; 00168 } 00169 return NULL; 00170 } 00171 ods_log_assert(key); 00172 00173 key->allocator = allocator; 00174 key->locator = allocator_strdup(allocator, locator); 00175 key->dnskey = rr; 00176 key->hsmkey = NULL; 00177 key->params = NULL; 00178 key->algorithm = algorithm; 00179 key->flags = flags; 00180 key->publish = publish; 00181 key->ksk = ksk; 00182 key->zsk = zsk; 00183 key->next = NULL; 00184 00185 if (locator) { 00186 free((void*)locator); 00187 locator = NULL; 00188 } 00189 return key; 00190 } 00191 00192 00197 static void 00198 key_print(FILE* fd, key_type* key) 00199 { 00200 if (!fd || !key) { 00201 return; 00202 } 00203 fprintf(fd, "\t\t\t<Key>\n"); 00204 fprintf(fd, "\t\t\t\t<Flags>%u</Flags>\n", key->flags); 00205 fprintf(fd, "\t\t\t\t<Algorithm>%u</Algorithm>\n", key->algorithm); 00206 if (key->locator) { 00207 fprintf(fd, "\t\t\t\t<Locator>%s</Locator>\n", key->locator); 00208 } 00209 if (key->ksk) { 00210 fprintf(fd, "\t\t\t\t<KSK />\n"); 00211 } 00212 if (key->zsk) { 00213 fprintf(fd, "\t\t\t\t<ZSK />\n"); 00214 } 00215 if (key->publish) { 00216 fprintf(fd, "\t\t\t\t<Publish />\n"); 00217 } 00218 fprintf(fd, "\t\t\t</Key>\n"); 00219 fprintf(fd, "\n"); 00220 return; 00221 } 00222 00223 00228 static void 00229 key_backup(FILE* fd, key_type* key) 00230 { 00231 if (!fd || !key) { 00232 return; 00233 } 00234 00235 fprintf(fd, ";;Key: locator %s algorithm %u flags %u publish %i ksk %i " 00236 "zsk %i\n", key->locator, (unsigned) key->algorithm, 00237 (unsigned) key->flags, key->publish, key->ksk, key->zsk); 00238 if (key->dnskey) { 00239 ldns_rr_print(fd, key->dnskey); 00240 } 00241 fprintf(fd, ";;Keydone\n"); 00242 return; 00243 } 00244 00245 00250 static void 00251 key_log(key_type* key, const char* name) 00252 { 00253 if (!key) { 00254 return; 00255 } 00256 ods_log_verbose("[%s] zone %s key: LOCATOR[%s] FLAGS[%u] ALGORITHM[%u] " 00257 "KSK[%i] ZSK[%i] PUBLISH[%i]", key_str, name?name:"(null)", key->locator, 00258 key->flags, key->algorithm, key->ksk, key->zsk, key->publish); 00259 return; 00260 } 00261 00262 00267 keylist_type* 00268 keylist_create(allocator_type* allocator) 00269 { 00270 keylist_type* kl; 00271 00272 if (!allocator) { 00273 ods_log_error("[%s] create list failed: no allocator available", 00274 key_str); 00275 return NULL; 00276 } 00277 ods_log_assert(allocator); 00278 00279 kl = (keylist_type*) allocator_alloc(allocator, sizeof(keylist_type)); 00280 if (!kl) { 00281 ods_log_error("[%s] create list failed: allocator failed", 00282 key_str); 00283 return NULL; 00284 } 00285 ods_log_assert(kl); 00286 00287 kl->allocator = allocator; 00288 kl->count = 0; 00289 kl->first_key = NULL; 00290 return kl; 00291 } 00292 00293 00298 ods_status 00299 keylist_push(keylist_type* kl, key_type* key) 00300 { 00301 key_type* walk = NULL; 00302 00303 if (!kl || !key || !key->locator) { 00304 ods_log_error("[%s] push failed: no list or no key", key_str); 00305 return ODS_STATUS_ASSERT_ERR; 00306 } 00307 ods_log_assert(kl); 00308 ods_log_assert(key); 00309 ods_log_debug("[%s] add locator %s", key_str, key->locator); 00310 00311 if (kl->count == 0) { 00312 kl->first_key = key; 00313 } else { 00314 walk = kl->first_key; 00315 while (walk->next) { 00316 walk = walk->next; 00317 } 00318 walk->next = key; 00319 } 00320 kl->count += 1; 00321 return ODS_STATUS_OK; 00322 } 00323 00324 00329 key_type* 00330 keylist_lookup(keylist_type* list, const char* locator) 00331 { 00332 key_type* search = NULL; 00333 size_t i = 0; 00334 00335 if (!list || !locator) { 00336 return NULL; 00337 } 00338 00339 search = list->first_key; 00340 for (i=0; i < list->count; i++) { 00341 if (search && search->locator) { 00342 if (ods_strcmp(search->locator, locator) == 0) { 00343 return search; 00344 } 00345 search = search->next; 00346 } else { 00347 break; 00348 } 00349 } 00350 return NULL; 00351 } 00352 00353 00358 key_type* 00359 keylist_lookup_by_dnskey(keylist_type* list, ldns_rr* dnskey) 00360 { 00361 key_type* search = NULL; 00362 size_t i = 0; 00363 00364 if (!list || !dnskey) { 00365 return NULL; 00366 } 00367 00368 search = list->first_key; 00369 for (i=0; i < list->count; i++) { 00370 if (search && search->dnskey) { 00371 if (ldns_rr_compare(search->dnskey, dnskey) == 0) { 00372 return search; 00373 } 00374 search = search->next; 00375 } else { 00376 break; 00377 } 00378 } 00379 return NULL; 00380 } 00381 00382 00387 void 00388 keylist_print(FILE* fd, keylist_type* kl) 00389 { 00390 key_type* walk = NULL; 00391 00392 if (fd && kl) { 00393 walk = kl->first_key; 00394 while (walk) { 00395 key_print(fd, walk); 00396 walk = walk->next; 00397 } 00398 } 00399 return; 00400 } 00401 00402 00407 void 00408 keylist_backup(FILE* fd, keylist_type* kl) 00409 { 00410 key_type* walk = NULL; 00411 00412 if (fd) { 00413 if (kl) { 00414 walk = kl->first_key; 00415 while (walk) { 00416 key_backup(fd, walk); 00417 walk = walk->next; 00418 } 00419 } 00420 fprintf(fd, ";;\n"); 00421 } 00422 return; 00423 } 00424 00425 00430 void 00431 keylist_log(keylist_type* kl, const char* name) 00432 { 00433 key_type* walk = NULL; 00434 00435 if (kl) { 00436 walk = kl->first_key; 00437 while (walk) { 00438 key_log(walk, name); 00439 walk = walk->next; 00440 } 00441 } 00442 return; 00443 } 00444 00445 00450 static void 00451 key_delfunc(key_type* key) 00452 { 00453 allocator_type* allocator; 00454 00455 if (!key) { 00456 return; 00457 } 00458 if (key->dnskey) { 00459 ldns_rr_free(key->dnskey); 00460 key->dnskey = NULL; 00461 } 00462 if (key->hsmkey) { 00463 hsm_key_free(key->hsmkey); 00464 key->hsmkey = NULL; 00465 } 00466 if (key->params) { 00467 hsm_sign_params_free(key->params); 00468 key->params = NULL; 00469 } 00470 allocator = key->allocator; 00471 allocator_deallocate(allocator, (void*) key->locator); 00472 allocator_deallocate(allocator, (void*) key); 00473 return; 00474 } 00475 00476 00481 void 00482 keylist_cleanup(keylist_type* kl) 00483 { 00484 key_type* walk = NULL; 00485 key_type* next = NULL; 00486 allocator_type* allocator; 00487 00488 if (!kl) { 00489 return; 00490 } 00491 walk = kl->first_key; 00492 while (walk) { 00493 next = walk->next; 00494 key_delfunc(walk); 00495 walk = next; 00496 } 00497 allocator = kl->allocator; 00498 allocator_deallocate(allocator, (void*) kl); 00499 return; 00500 }