00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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_debug("[%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 }