1 static const char rcsid[] = "$Header: /proj/cvs/prod/bind9/lib/bind/dst/support.c,v 1.2.2.1.10.2 2005/10/11 00:48:14 marka Exp $";
5 * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
7 * Permission to use, copy modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS
12 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
13 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
14 * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT,
15 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
16 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
17 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
18 * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
21 #include "port_before.h"
29 #include <netinet/in.h>
30 #include <arpa/nameser.h>
33 #include "dst_internal.h"
35 #include "port_after.h"
39 * Validate that the input string(*str) is at the head of the input
40 * buffer(**buf). If so, move the buffer head pointer (*buf) to
41 * the first byte of data following the string(*str).
46 * 0 *str is not the head of **buff
47 * 1 *str is the head of **buff, *buf is is advanced to
52 dst_s_verify_str(const char **buf, const char *str)
55 if (*buf == NULL) /* error checks */
57 if (str == NULL || *str == '\0')
60 b = strlen(*buf); /* get length of strings */
62 if (s > b || strncmp(*buf, str, s)) /* check if same */
63 return (0); /* not a match */
64 (*buf) += s; /* advance pointer */
69 * dst_s_calculate_bits
70 * Given a binary number represented in a u_char[], determine
71 * the number of significant bits used.
73 * str An input character string containing a binary number.
74 * max_bits The maximum possible significant bits.
76 * N The number of significant bits in str.
80 dst_s_calculate_bits(const u_char *str, const int max_bits)
82 const u_char *p = str;
85 for (bits = max_bits; *p == 0x00 && bits > 0; p++)
87 for (i = *p; (i & j) != j; j >>= 1)
94 * calculates a checksum used in dst for an id.
95 * takes an array of bytes and a length.
96 * returns a 16 bit checksum.
99 dst_s_id_calc(const u_char *key, const int keysize)
102 const u_char *kp = key;
105 if (!key || (keysize <= 0))
108 for (ac = 0; size > 1; size -= 2, kp += 2)
109 ac += ((*kp) << 8) + *(kp + 1);
113 ac += (ac >> 16) & 0xffff;
115 return (ac & 0xffff);
119 * dst_s_dns_key_id() Function to calculate DNSSEC footprint from KEY record
122 * dns_key_rdata: the raw data in wire format
123 * rdata_len: the size of the input data
125 * the key footprint/id calculated from the key data
128 dst_s_dns_key_id(const u_char *dns_key_rdata, const int rdata_len)
134 if (dns_key_rdata[3] == KEY_RSA) /* Algorithm RSA */
135 return dst_s_get_int16((const u_char *)
136 &dns_key_rdata[rdata_len - 3]);
137 else if (dns_key_rdata[3] == KEY_HMAC_MD5)
141 /* compute a checksum on the key part of the key rr */
142 return dst_s_id_calc(dns_key_rdata, rdata_len);
147 * This routine extracts a 16 bit integer from a two byte character
148 * string. The character string is assumed to be in network byte
149 * order and may be unaligned. The number returned is in host order.
151 * buf A two byte character string.
153 * The converted integer value.
157 dst_s_get_int16(const u_char *buf)
159 register u_int16_t a = 0;
160 a = ((u_int16_t)(buf[0] << 8)) | ((u_int16_t)(buf[1]));
167 * This routine extracts a 32 bit integer from a four byte character
168 * string. The character string is assumed to be in network byte
169 * order and may be unaligned. The number returned is in host order.
171 * buf A four byte character string.
173 * The converted integer value.
177 dst_s_get_int32(const u_char *buf)
179 register u_int32_t a = 0;
180 a = ((u_int32_t)(buf[0] << 24)) | ((u_int32_t)(buf[1] << 16)) |
181 ((u_int32_t)(buf[2] << 8)) | ((u_int32_t)(buf[3]));
188 * Take a 16 bit integer and store the value in a two byte
189 * character string. The integer is assumed to be in network
190 * order and the string is returned in host order.
193 * buf Storage for a two byte character string.
194 * val 16 bit integer.
198 dst_s_put_int16(u_int8_t *buf, const u_int16_t val)
200 buf[0] = (u_int8_t)(val >> 8);
201 buf[1] = (u_int8_t)(val);
207 * Take a 32 bit integer and store the value in a four byte
208 * character string. The integer is assumed to be in network
209 * order and the string is returned in host order.
212 * buf Storage for a four byte character string.
213 * val 32 bit integer.
217 dst_s_put_int32(u_int8_t *buf, const u_int32_t val)
219 buf[0] = (u_int8_t)(val >> 24);
220 buf[1] = (u_int8_t)(val >> 16);
221 buf[2] = (u_int8_t)(val >> 8);
222 buf[3] = (u_int8_t)(val);
227 * dst_s_filename_length
229 * This function returns the number of bytes needed to hold the
230 * filename for a key file. '/', '\' and ':' are not allowed.
231 * form: K<keyname>+<alg>+<id>.<suffix>
233 * Returns 0 if the filename would contain either '\', '/' or ':'
236 dst_s_filename_length(const char *name, const char *suffix)
240 if (strrchr(name, '\\'))
242 if (strrchr(name, '/'))
244 if (strrchr(name, ':'))
248 if (strrchr(suffix, '\\'))
250 if (strrchr(suffix, '/'))
252 if (strrchr(suffix, ':'))
254 return (1 + strlen(name) + 6 + strlen(suffix));
259 * dst_s_build_filename ()
260 * Builds a key filename from the key name, it's id, and a
261 * suffix. '\', '/' and ':' are not allowed. fA filename is of the
262 * form: K<keyname><id>.<suffix>
263 * form: K<keyname>+<alg>+<id>.<suffix>
265 * Returns -1 if the conversion fails:
266 * if the filename would be too long for space allotted
267 * if the filename would contain a '\', '/' or ':'
268 * Returns 0 on success
272 dst_s_build_filename(char *filename, const char *name, u_int16_t id,
273 int alg, const char *suffix, size_t filename_length)
276 if (filename == NULL)
278 memset(filename, 0, filename_length);
283 if (filename_length < 1 + strlen(name) + 4 + 6 + 1 + strlen(suffix))
286 sprintf(filename, "K%s+%03d+%05d.%s", name, alg, my_id,
287 (const char *) suffix);
288 if (strrchr(filename, '/'))
290 if (strrchr(filename, '\\'))
292 if (strrchr(filename, ':'))
299 * Open a file in the dst_path directory. If perm is specified, the
300 * file is checked for existence first, and not opened if it exists.
302 * filename File to open
303 * mode Mode to open the file (passed directly to fopen)
304 * perm File permission, if creating a new file.
307 * NON-NULL (FILE *) of opened file.
310 dst_s_fopen(const char *filename, const char *mode, int perm)
313 char pathname[PATH_MAX];
315 if (strlen(filename) + strlen(dst_path) >= sizeof(pathname))
318 if (*dst_path != '\0') {
319 strcpy(pathname, dst_path);
320 strcat(pathname, filename);
322 strcpy(pathname, filename);
324 fp = fopen(pathname, mode);
326 chmod(pathname, perm);
331 dst_s_dump(const int mode, const u_char *data, const int size,
338 static u_char scratch[1000];
340 n = b64_ntop(data, scratch, size, sizeof(scratch));
341 printf("%s: %x %d %s\n", msg, mode, n, scratch);
343 printf("%s,%x %d\n", msg, mode, size);