OpenDNSSEC-signer 1.2.1
|
00001 /* 00002 * $Id: nsec3params.c 4294 2011-01-13 19:58:29Z 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 "signer/backup.h" 00035 #include "signer/nsec3params.h" 00036 #include "util/log.h" 00037 #include "util/se_malloc.h" 00038 00039 #include <ctype.h> /* isxdigit() */ 00040 #include <ldns/ldns.h> /* ldns_hexdigit_to_int() */ 00041 #include <string.h> /* strlen() */ 00042 00047 int 00048 nsec3params_create_salt(const char* salt_str, uint8_t* salt_len, uint8_t** salt) 00049 { 00050 uint8_t c; 00051 uint8_t* salt_tmp; 00052 00053 if (!salt_str) { 00054 *salt_len = 0; 00055 *salt = NULL; 00056 return 0; 00057 } 00058 00059 *salt_len = (uint8_t) strlen(salt_str); 00060 if (*salt_len == 1 && salt_str[0] == '-') { 00061 *salt_len = 0; 00062 *salt = NULL; 00063 return 0; 00064 } else if (*salt_len % 2 != 0) { 00065 se_log_error("invalid salt %s", salt_str); 00066 *salt = NULL; 00067 return 1; 00068 } 00069 00070 /* construct salt data */ 00071 salt_tmp = (uint8_t*) se_calloc(*salt_len / 2, sizeof(uint8_t)); 00072 for (c = 0; c < *salt_len; c += 2) { 00073 if (isxdigit((int) salt_str[c]) && isxdigit((int) salt_str[c+1])) { 00074 salt_tmp[c/2] = (uint8_t) ldns_hexdigit_to_int(salt_str[c]) * 16 + 00075 ldns_hexdigit_to_int(salt_str[c+1]); 00076 } else { 00077 se_log_error("invalid salt %s", salt_str); 00078 se_free((void*)salt_tmp); 00079 *salt = NULL; 00080 return 1; 00081 } 00082 } 00083 00084 *salt_len = *salt_len / 2; /* update length */ 00085 *salt = salt_tmp; 00086 return 0; 00087 } 00088 00089 00094 nsec3params_type* 00095 nsec3params_create(uint8_t algo, uint8_t flags, uint16_t iter, const char* salt) 00096 { 00097 nsec3params_type* nsec3params = (nsec3params_type*) 00098 se_malloc(sizeof(nsec3params_type)); 00099 uint8_t salt_len; /* calculate salt len */ 00100 uint8_t* salt_data; /* calculate salt data */ 00101 00102 nsec3params->algorithm = algo; /* algorithm identifier */ 00103 nsec3params->flags = flags; /* flags */ 00104 nsec3params->iterations = iter; /* iterations */ 00105 /* construct the salt from the string */ 00106 if (nsec3params_create_salt(salt, &salt_len, &salt_data) != 0) { 00107 se_free((void*)nsec3params); 00108 return NULL; 00109 } 00110 nsec3params->salt_len = salt_len; /* salt length */ 00111 nsec3params->salt_data = salt_data; /* salt data */ 00112 return nsec3params; 00113 } 00114 00115 00120 nsec3params_type* 00121 nsec3params_recover_from_backup(FILE* fd, ldns_rr** rr) 00122 { 00123 const char* salt = NULL; 00124 uint8_t algorithm = 0; 00125 uint8_t flags = 0; 00126 uint16_t iterations = 0; 00127 ldns_rr* nsec3params_rr = NULL; 00128 nsec3params_type* nsec3params = NULL; 00129 uint8_t salt_len; /* calculate salt len */ 00130 uint8_t* salt_data; /* calculate salt data */ 00131 00132 se_log_assert(fd); 00133 00134 if (!backup_read_str(fd, &salt) || 00135 !backup_read_uint8_t(fd, &algorithm) || 00136 !backup_read_uint8_t(fd, &flags) || 00137 !backup_read_uint16_t(fd, &iterations) || 00138 ldns_rr_new_frm_fp(&nsec3params_rr, fd, NULL, NULL, NULL) 00139 != LDNS_STATUS_OK || 00140 !backup_read_check_str(fd, ";END")) 00141 { 00142 se_log_error("nsec3params part in backup file is corrupted"); 00143 if (nsec3params_rr) { 00144 ldns_rr_free(nsec3params_rr); 00145 nsec3params_rr = NULL; 00146 } 00147 if (salt) { 00148 se_free((void*) salt); 00149 salt = NULL; 00150 } 00151 return NULL; 00152 } 00153 00154 nsec3params = (nsec3params_type*) se_malloc(sizeof(nsec3params_type)); 00155 nsec3params->algorithm = algorithm; /* algorithm identifier */ 00156 nsec3params->flags = flags; /* flags */ 00157 nsec3params->iterations = iterations; /* iterations */ 00158 /* construct the salt from the string */ 00159 if (nsec3params_create_salt(salt, &salt_len, &salt_data) != 0) { 00160 se_free((void*)nsec3params); 00161 se_free((void*)salt); 00162 ldns_rr_free(nsec3params_rr); 00163 return NULL; 00164 } 00165 se_free((void*) salt); 00166 nsec3params->salt_len = salt_len; /* salt length */ 00167 nsec3params->salt_data = salt_data; /* salt data */ 00168 *rr = nsec3params_rr; 00169 return nsec3params; 00170 } 00171 00172 00177 const char* 00178 nsec3params_salt2str(nsec3params_type* nsec3params) 00179 { 00180 uint8_t *data; 00181 uint8_t salt_length = 0; 00182 uint8_t salt_pos = 0; 00183 int written = 0; 00184 char* str = NULL; 00185 ldns_buffer* buffer = NULL; 00186 00187 salt_length = nsec3params->salt_len; 00188 data = nsec3params->salt_data; 00189 00190 /* from now there are variable length entries so remember pos */ 00191 if (salt_length == 0) { 00192 buffer = ldns_buffer_new(2); 00193 written = ldns_buffer_printf(buffer, "-"); 00194 } else { 00195 buffer = ldns_buffer_new(salt_pos+1); 00196 for (salt_pos = 0; salt_pos < salt_length; salt_pos++) { 00197 written = ldns_buffer_printf(buffer, "%02x", data[salt_pos]); 00198 } 00199 } 00200 00201 if (ldns_buffer_status(buffer) == LDNS_STATUS_OK) { 00202 str = ldns_buffer2str(buffer); 00203 } else { 00204 se_log_error("failed to convert nsec3 salt to string: %s", 00205 ldns_get_errorstr_by_id(ldns_buffer_status(buffer))); 00206 } 00207 ldns_buffer_free(buffer); 00208 return (const char*) str; 00209 } 00210 00211 00216 void 00217 nsec3params_cleanup(nsec3params_type* nsec3params) 00218 { 00219 if (nsec3params) { 00220 se_free((void*) nsec3params->salt_data); 00221 se_free((void*) nsec3params); 00222 } else { 00223 se_log_warning("cleanup empty nsec3 parameters"); 00224 } 00225 return; 00226 }