OpenDNSSEC-signer 1.3.0
|
00001 /* 00002 * $Id: nsec3params.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/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 }