OpenDNSSEC-signer  1.3.8
/build/buildd/opendnssec-1.3.8/signer/src/signer/nsec3params.c
Go to the documentation of this file.
00001 /*
00002  * $Id: nsec3params.c 4627 2011-03-23 10:00:49Z 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/log.h"
00036 #include "shared/status.h"
00037 #include "signer/backup.h"
00038 #include "signer/nsec3params.h"
00039 
00040 #include <ctype.h>
00041 #include <ldns/ldns.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 
00045 static const char* nsec3_str = "nsec3";
00046 
00047 
00052 ods_status
00053 nsec3params_create_salt(const char* salt_str, uint8_t* salt_len,
00054     uint8_t** salt)
00055 {
00056     uint8_t c;
00057     uint8_t* salt_tmp;
00058 
00059     if (!salt_str) {
00060         *salt_len = 0;
00061         *salt = NULL;
00062         return ODS_STATUS_OK;
00063     }
00064 
00065     *salt_len = (uint8_t) strlen(salt_str);
00066     if (*salt_len == 1 && salt_str[0] == '-') {
00067         *salt_len = 0;
00068         *salt = NULL;
00069         return ODS_STATUS_OK;
00070     } else if (*salt_len % 2 != 0) {
00071         ods_log_error("[%s] invalid salt %s", nsec3_str, salt_str);
00072         *salt = NULL;
00073         return ODS_STATUS_ERR;
00074     }
00075 
00076     /* construct salt data */
00077     salt_tmp = (uint8_t*) calloc(*salt_len / 2, sizeof(uint8_t));
00078     for (c = 0; c < *salt_len; c += 2) {
00079         if (isxdigit((int) salt_str[c]) && isxdigit((int) salt_str[c+1])) {
00080             salt_tmp[c/2] = (uint8_t) ldns_hexdigit_to_int(salt_str[c]) * 16 +
00081                                       ldns_hexdigit_to_int(salt_str[c+1]);
00082         } else {
00083             ods_log_error("[%s] invalid salt %s", nsec3_str, salt_str);
00084             free((void*)salt_tmp);
00085             *salt = NULL;
00086             return ODS_STATUS_ERR;
00087         }
00088     }
00089 
00090     *salt_len = *salt_len / 2; /* update length */
00091     *salt = salt_tmp;
00092     return ODS_STATUS_OK;
00093 }
00094 
00095 
00100 nsec3params_type*
00101 nsec3params_create(uint8_t algo, uint8_t flags, uint16_t iter,
00102     const char* salt)
00103 {
00104     nsec3params_type* nsec3params;
00105     uint8_t salt_len; /* calculate salt len */
00106     uint8_t* salt_data; /* calculate salt data */
00107     allocator_type* allocator = allocator_create(malloc, free);
00108     if (!allocator) {
00109         ods_log_error("[%s] unable to create: create allocator failed",
00110             nsec3_str);
00111         return NULL;
00112     }
00113     ods_log_assert(allocator);
00114 
00115     nsec3params = (nsec3params_type*) allocator_alloc(allocator,
00116         sizeof(nsec3params_type));
00117     if (!nsec3params) {
00118         ods_log_error("[%s] unable to create: allocator failed", nsec3_str);
00119         allocator_cleanup(allocator);
00120         return NULL;
00121     }
00122     ods_log_assert(nsec3params);
00123 
00124     nsec3params->allocator = allocator;
00125     nsec3params->algorithm = algo; /* algorithm identifier */
00126     nsec3params->flags = flags; /* flags */
00127     nsec3params->iterations = iter; /* iterations */
00128     /* construct the salt from the string */
00129     if (nsec3params_create_salt(salt, &salt_len, &salt_data) != 0) {
00130         free((void*)nsec3params);
00131         return NULL;
00132     }
00133     nsec3params->salt_len = salt_len; /* salt length */
00134     nsec3params->salt_data = salt_data; /* salt data */
00135     nsec3params->rr = NULL;
00136     return nsec3params;
00137 }
00138 
00139 
00144 void
00145 nsec3params_backup(FILE* fd, uint8_t algo, uint8_t flags,
00146     uint16_t iter, const char* salt, ldns_rr* rr)
00147 {
00148     if (!fd) {
00149         return;
00150     }
00151     fprintf(fd, ";;Nsec3parameters: salt %s algorithm %u optout %u "
00152         "iterations %u\n", salt?salt:"-", (unsigned) algo,
00153         (unsigned) flags, (unsigned) iter);
00154     if (rr) {
00155         ldns_rr_print(fd, rr);
00156     }
00157     fprintf(fd, ";;Nsec3done\n");
00158     fprintf(fd, ";;\n");
00159     return;
00160 }
00161 
00162 
00167 nsec3params_type*
00168 nsec3params_recover_from_backup(FILE* fd, ldns_rr** rr)
00169 {
00170     const char* salt = NULL;
00171     uint8_t algorithm = 0;
00172     uint8_t flags = 0;
00173     uint16_t iterations = 0;
00174     ldns_rr* nsec3params_rr = NULL;
00175     nsec3params_type* nsec3params = NULL;
00176     uint8_t salt_len; /* calculate salt len */
00177     uint8_t* salt_data; /* calculate salt data */
00178 
00179     ods_log_assert(fd);
00180 
00181     if (!backup_read_str(fd, &salt) ||
00182         !backup_read_uint8_t(fd, &algorithm) ||
00183         !backup_read_uint8_t(fd, &flags) ||
00184         !backup_read_uint16_t(fd, &iterations) ||
00185         ldns_rr_new_frm_fp(&nsec3params_rr, fd, NULL, NULL, NULL)
00186             != LDNS_STATUS_OK ||
00187         !backup_read_check_str(fd, ";END"))
00188     {
00189         ods_log_error("[%s] nsec3params part in backup file is corrupted", nsec3_str);
00190         if (nsec3params_rr) {
00191             ldns_rr_free(nsec3params_rr);
00192             nsec3params_rr = NULL;
00193         }
00194         if (salt) {
00195             free((void*) salt);
00196             salt = NULL;
00197         }
00198         return NULL;
00199     }
00200 
00201     nsec3params = (nsec3params_type*) malloc(sizeof(nsec3params_type));
00202     nsec3params->algorithm = algorithm; /* algorithm identifier */
00203     nsec3params->flags = flags; /* flags */
00204     nsec3params->iterations = iterations; /* iterations */
00205     /* construct the salt from the string */
00206     if (nsec3params_create_salt(salt, &salt_len, &salt_data) != 0) {
00207         free((void*)nsec3params);
00208         free((void*)salt);
00209         ldns_rr_free(nsec3params_rr);
00210         return NULL;
00211     }
00212     free((void*) salt);
00213     nsec3params->salt_len = salt_len; /* salt length */
00214     nsec3params->salt_data = salt_data; /* salt data */
00215     *rr = nsec3params_rr;
00216     nsec3params->rr = ldns_rr_clone(nsec3params_rr);
00217     return nsec3params;
00218 }
00219 
00220 
00225 const char*
00226 nsec3params_salt2str(nsec3params_type* nsec3params)
00227 {
00228     uint8_t *data;
00229     uint8_t salt_length = 0;
00230     uint8_t salt_pos = 0;
00231     int written = 0;
00232     char* str = NULL;
00233     ldns_buffer* buffer = NULL;
00234 
00235     salt_length = nsec3params->salt_len;
00236     data = nsec3params->salt_data;
00237 
00238     /* from now there are variable length entries so remember pos */
00239     if (salt_length == 0) {
00240         buffer = ldns_buffer_new(2);
00241         written = ldns_buffer_printf(buffer, "-");
00242     } else {
00243         buffer = ldns_buffer_new(salt_pos+1);
00244         for (salt_pos = 0; salt_pos < salt_length; salt_pos++) {
00245             written = ldns_buffer_printf(buffer, "%02x", data[salt_pos]);
00246         }
00247     }
00248 
00249     if (ldns_buffer_status(buffer) == LDNS_STATUS_OK) {
00250         str = ldns_buffer2str(buffer);
00251     } else {
00252         ods_log_error("[%s] unable to convert nsec3 salt to string: %s",
00253             nsec3_str, ldns_get_errorstr_by_id(ldns_buffer_status(buffer)));
00254     }
00255     ldns_buffer_free(buffer);
00256     return (const char*) str;
00257 }
00258 
00259 
00264 void
00265 nsec3params_cleanup(nsec3params_type* nsec3params)
00266 {
00267     allocator_type* allocator;
00268     if (!nsec3params) {
00269         return;
00270     }
00271     allocator = nsec3params->allocator;
00272     ldns_rr_free(nsec3params->rr);
00273     allocator_deallocate(allocator, (void*) nsec3params->salt_data);
00274     allocator_deallocate(allocator, (void*) nsec3params);
00275     allocator_cleanup(allocator);
00276     return;
00277 }