OpenDNSSEC-signer 1.3.0
/build/buildd/opendnssec-1.3.0/signer/src/signer/keys.c
Go to the documentation of this file.
00001 /*
00002  * $Id: keys.c 5320 2011-07-12 10:42:26Z jakob $
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_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 }