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/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
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;
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;
00106 uint8_t* 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;
00126 nsec3params->flags = flags;
00127 nsec3params->iterations = iter;
00128
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;
00134 nsec3params->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;
00177 uint8_t* 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;
00203 nsec3params->flags = flags;
00204 nsec3params->iterations = iterations;
00205
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;
00214 nsec3params->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
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 }