1 /* 2 * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. 3 * 4 * Permission to use, copy modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS 9 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 10 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 11 * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 13 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 14 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 15 * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. 16 */ 17 18 #include "port_before.h" 19 20 #include <stdio.h> 21 #include <unistd.h> 22 #include <memory.h> 23 #include <string.h> 24 #include <errno.h> 25 #include <sys/stat.h> 26 #include <netinet/in.h> 27 #include <arpa/nameser.h> 28 #include <resolv.h> 29 30 #include "dst_internal.h" 31 32 #include "port_after.h" 33 34 /*% 35 * dst_s_verify_str() 36 * Validate that the input string(*str) is at the head of the input 37 * buffer(**buf). If so, move the buffer head pointer (*buf) to 38 * the first byte of data following the string(*str). 39 * Parameters 40 * buf Input buffer. 41 * str Input string. 42 * Return 43 * 0 *str is not the head of **buff 44 * 1 *str is the head of **buff, *buf is is advanced to 45 * the tail of **buf. 46 */ 47 48 int 49 dst_s_verify_str(const char **buf, const char *str) 50 { 51 int b, s; 52 if (*buf == NULL) /*%< error checks */ 53 return (0); 54 if (str == NULL || *str == '\0') 55 return (1); 56 57 b = strlen(*buf); /*%< get length of strings */ 58 s = strlen(str); 59 if (s > b || strncmp(*buf, str, s)) /*%< check if same */ 60 return (0); /*%< not a match */ 61 (*buf) += s; /*%< advance pointer */ 62 return (1); 63 } 64 65 /*% 66 * dst_s_calculate_bits 67 * Given a binary number represented in a u_char[], determine 68 * the number of significant bits used. 69 * Parameters 70 * str An input character string containing a binary number. 71 * max_bits The maximum possible significant bits. 72 * Return 73 * N The number of significant bits in str. 74 */ 75 76 int 77 dst_s_calculate_bits(const u_char *str, const int max_bits) 78 { 79 const u_char *p = str; 80 u_char i, j = 0x80; 81 int bits; 82 for (bits = max_bits; *p == 0x00 && bits > 0; p++) 83 bits -= 8; 84 for (i = *p; (i & j) != j; j >>= 1) 85 bits--; 86 return (bits); 87 } 88 89 /*% 90 * calculates a checksum used in dst for an id. 91 * takes an array of bytes and a length. 92 * returns a 16 bit checksum. 93 */ 94 u_int16_t 95 dst_s_id_calc(const u_char *key, const int keysize) 96 { 97 u_int32_t ac; 98 const u_char *kp = key; 99 int size = keysize; 100 101 if (!key || (keysize <= 0)) 102 return (0xffffU); 103 104 for (ac = 0; size > 1; size -= 2, kp += 2) 105 ac += ((*kp) << 8) + *(kp + 1); 106 107 if (size > 0) 108 ac += ((*kp) << 8); 109 ac += (ac >> 16) & 0xffff; 110 111 return (ac & 0xffff); 112 } 113 114 /*% 115 * dst_s_dns_key_id() Function to calculate DNSSEC footprint from KEY record 116 * rdata 117 * Input: 118 * dns_key_rdata: the raw data in wire format 119 * rdata_len: the size of the input data 120 * Output: 121 * the key footprint/id calculated from the key data 122 */ 123 u_int16_t 124 dst_s_dns_key_id(const u_char *dns_key_rdata, const int rdata_len) 125 { 126 if (!dns_key_rdata) 127 return 0; 128 129 /* compute id */ 130 if (dns_key_rdata[3] == KEY_RSA) /*%< Algorithm RSA */ 131 return dst_s_get_int16((const u_char *) 132 &dns_key_rdata[rdata_len - 3]); 133 else if (dns_key_rdata[3] == KEY_HMAC_MD5) 134 /* compatibility */ 135 return 0; 136 else 137 /* compute a checksum on the key part of the key rr */ 138 return dst_s_id_calc(dns_key_rdata, rdata_len); 139 } 140 141 /*% 142 * dst_s_get_int16 143 * This routine extracts a 16 bit integer from a two byte character 144 * string. The character string is assumed to be in network byte 145 * order and may be unaligned. The number returned is in host order. 146 * Parameter 147 * buf A two byte character string. 148 * Return 149 * The converted integer value. 150 */ 151 152 u_int16_t 153 dst_s_get_int16(const u_char *buf) 154 { 155 register u_int16_t a = 0; 156 a = ((u_int16_t)(buf[0] << 8)) | ((u_int16_t)(buf[1])); 157 return (a); 158 } 159 160 /*% 161 * dst_s_get_int32 162 * This routine extracts a 32 bit integer from a four byte character 163 * string. The character string is assumed to be in network byte 164 * order and may be unaligned. The number returned is in host order. 165 * Parameter 166 * buf A four byte character string. 167 * Return 168 * The converted integer value. 169 */ 170 171 u_int32_t 172 dst_s_get_int32(const u_char *buf) 173 { 174 register u_int32_t a = 0; 175 a = ((u_int32_t)(buf[0] << 24)) | ((u_int32_t)(buf[1] << 16)) | 176 ((u_int32_t)(buf[2] << 8)) | ((u_int32_t)(buf[3])); 177 return (a); 178 } 179 180 /*% 181 * dst_s_put_int16 182 * Take a 16 bit integer and store the value in a two byte 183 * character string. The integer is assumed to be in network 184 * order and the string is returned in host order. 185 * 186 * Parameters 187 * buf Storage for a two byte character string. 188 * val 16 bit integer. 189 */ 190 191 void 192 dst_s_put_int16(u_int8_t *buf, const u_int16_t val) 193 { 194 buf[0] = (u_int8_t)(val >> 8); 195 buf[1] = (u_int8_t)(val); 196 } 197 198 /*% 199 * dst_s_put_int32 200 * Take a 32 bit integer and store the value in a four byte 201 * character string. The integer is assumed to be in network 202 * order and the string is returned in host order. 203 * 204 * Parameters 205 * buf Storage for a four byte character string. 206 * val 32 bit integer. 207 */ 208 209 void 210 dst_s_put_int32(u_int8_t *buf, const u_int32_t val) 211 { 212 buf[0] = (u_int8_t)(val >> 24); 213 buf[1] = (u_int8_t)(val >> 16); 214 buf[2] = (u_int8_t)(val >> 8); 215 buf[3] = (u_int8_t)(val); 216 } 217 218 /*% 219 * dst_s_filename_length 220 * 221 * This function returns the number of bytes needed to hold the 222 * filename for a key file. '/', '\' and ':' are not allowed. 223 * form: K<keyname>+<alg>+<id>.<suffix> 224 * 225 * Returns 0 if the filename would contain either '\', '/' or ':' 226 */ 227 size_t 228 dst_s_filename_length(const char *name, const char *suffix) 229 { 230 if (name == NULL) 231 return (0); 232 if (strrchr(name, '\\')) 233 return (0); 234 if (strrchr(name, '/')) 235 return (0); 236 if (strrchr(name, ':')) 237 return (0); 238 if (suffix == NULL) 239 return (0); 240 if (strrchr(suffix, '\\')) 241 return (0); 242 if (strrchr(suffix, '/')) 243 return (0); 244 if (strrchr(suffix, ':')) 245 return (0); 246 return (1 + strlen(name) + 6 + strlen(suffix)); 247 } 248 249 /*% 250 * dst_s_build_filename () 251 * Builds a key filename from the key name, it's id, and a 252 * suffix. '\', '/' and ':' are not allowed. fA filename is of the 253 * form: K<keyname><id>.<suffix> 254 * form: K<keyname>+<alg>+<id>.<suffix> 255 * 256 * Returns -1 if the conversion fails: 257 * if the filename would be too long for space allotted 258 * if the filename would contain a '\', '/' or ':' 259 * Returns 0 on success 260 */ 261 262 int 263 dst_s_build_filename(char *filename, const char *name, u_int16_t id, 264 int alg, const char *suffix, size_t filename_length) 265 { 266 u_int32_t my_id; 267 if (filename == NULL) 268 return (-1); 269 memset(filename, 0, filename_length); 270 if (name == NULL) 271 return (-1); 272 if (suffix == NULL) 273 return (-1); 274 if (filename_length < 1 + strlen(name) + 4 + 6 + 1 + strlen(suffix)) 275 return (-1); 276 my_id = id; 277 sprintf(filename, "K%s+%03d+%05d.%s", name, alg, my_id, 278 (const char *) suffix); 279 if (strrchr(filename, '/')) 280 return (-1); 281 if (strrchr(filename, '\\')) 282 return (-1); 283 if (strrchr(filename, ':')) 284 return (-1); 285 return (0); 286 } 287 288 /*% 289 * dst_s_fopen () 290 * Open a file in the dst_path directory. If perm is specified, the 291 * file is checked for existence first, and not opened if it exists. 292 * Parameters 293 * filename File to open 294 * mode Mode to open the file (passed directly to fopen) 295 * perm File permission, if creating a new file. 296 * Returns 297 * NULL Failure 298 * NON-NULL (FILE *) of opened file. 299 */ 300 FILE * 301 dst_s_fopen(const char *filename, const char *mode, int perm) 302 { 303 FILE *fp; 304 char pathname[PATH_MAX]; 305 306 if (strlen(filename) + strlen(dst_path) >= sizeof(pathname)) 307 return (NULL); 308 309 if (*dst_path != '\0') { 310 strcpy(pathname, dst_path); 311 strcat(pathname, filename); 312 } else 313 strcpy(pathname, filename); 314 315 fp = fopen(pathname, mode); 316 if (perm) 317 chmod(pathname, perm); 318 return (fp); 319 } 320 321 void 322 dst_s_dump(const int mode, const u_char *data, const int size, 323 const char *msg) 324 { 325 UNUSED(data); 326 327 if (size > 0) { 328 #ifdef LONG_TEST 329 static u_char scratch[1000]; 330 int n ; 331 n = b64_ntop(data, scratch, size, sizeof(scratch)); 332 printf("%s: %x %d %s\n", msg, mode, n, scratch); 333 #else 334 printf("%s,%x %d\n", msg, mode, size); 335 #endif 336 } 337 } 338 339 /*! \file */ 340