1 static const char rcsid
[] = "$Header: /pub/NetBSD/misc/repositories/cvsroot/src/dist/dhcp/dst/dst_support.c,v 1.3 2005/08/11 17:13:21 drochner 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.
27 #include <netinet/in.h>
28 #include <sys/socket.h>
30 #include "minires/minires.h"
31 #include "arpa/nameser.h"
33 #include "dst_internal.h"
36 * dst_s_conv_bignum_u8_to_b64
37 * This function converts binary data stored as a u_char[] to a
38 * base-64 string. Leading zeroes are discarded. If a header is
39 * supplied, it is prefixed to the input prior to encoding. The
40 * output is \n\0 terminated (the \0 is not included in output length).
42 * out_buf binary data to convert
43 * header character string to prefix to the output (label)
44 * bin_data binary data
45 * bin_len size of binary data
47 * -1 not enough space in output work area
49 * >0 number of bytes written to output work area
53 dst_s_conv_bignum_u8_to_b64(char *out_buf
, const unsigned out_len
,
54 const char *header
, const u_char
*bin_data
,
55 const unsigned bin_len
)
57 const u_char
*bp
= bin_data
;
59 unsigned lenh
= 0, len64
= 0;
60 unsigned local_in_len
= bin_len
;
61 unsigned local_out_len
= out_len
;
63 if (bin_data
== NULL
) /* no data no */
66 if (out_buf
== NULL
|| out_len
<= 0) /* no output_work area */
69 /* suppress leading \0 */
70 for (; (*bp
== 0x0) && (local_in_len
> 0); local_in_len
--)
73 if (header
) { /* add header to output string */
74 lenh
= strlen(header
);
76 memcpy(op
, header
, lenh
);
79 local_out_len
-= lenh
;
82 len64
= b64_ntop(bp
, local_in_len
, op
, local_out_len
- 2);
86 *(op
++) = '\n'; /* put CR in the output */
87 *op
= '\0'; /* make sure output is 0 terminated */
88 return (lenh
+ len64
);
94 * Validate that the input string(*str) is at the head of the input
95 * buffer(**buf). If so, move the buffer head pointer (*buf) to
96 * the first byte of data following the string(*str).
101 * 0 *str is not the head of **buff
102 * 1 *str is the head of **buff, *buf is is advanced to
107 dst_s_verify_str(const char **buf
, const char *str
)
110 if (*buf
== NULL
) /* error checks */
112 if (str
== NULL
|| *str
== '\0')
115 b
= strlen(*buf
); /* get length of strings */
117 if (s
> b
|| strncmp(*buf
, str
, s
)) /* check if same */
118 return (0); /* not a match */
119 (*buf
) += s
; /* advance pointer */
125 * dst_s_conv_bignum_b64_to_u8
126 * Read a line of base-64 encoded string from the input buffer,
127 * convert it to binary, and store it in an output area. The
128 * input buffer is read until reaching a newline marker or the
129 * end of the buffer. The binary data is stored in the last X
130 * number of bytes of the output area where X is the size of the
131 * binary output. If the operation is successful, the input buffer
132 * pointer is advanced. This procedure does not do network to host
133 * byte order conversion.
135 * buf Pointer to encoded input string. Pointer is updated if
136 * function is successfull.
138 * loclen Size in bytes of output area.
140 * >0 Return = number of bytes of binary data stored in loc.
145 dst_s_conv_bignum_b64_to_u8(const char **buf
,
146 u_char
*loc
, const unsigned loclen
)
150 u_char bstr
[RAW_KEY_SIZE
];
152 if (buf
== NULL
|| *buf
== NULL
) { /* error checks */
153 EREPORT(("dst_s_conv_bignum_b64_to_u8: null input buffer.\n"));
156 bp
= strchr(*buf
, '\n'); /* find length of input line */
160 blen
= b64_pton(*buf
, bstr
, sizeof(bstr
));
162 EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is null.\n"));
165 else if (loclen
< blen
) {
166 EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is longer than output buffer.\n"));
170 *buf
= bp
; /* advancing buffer past \n */
171 memset(loc
, 0, loclen
- blen
); /* clearing unused output area */
172 memcpy(loc
+ loclen
- blen
, bstr
, blen
); /* write last blen bytes */
178 * dst_s_calculate_bits
179 * Given a binary number represented in a u_char[], determine
180 * the number of significant bits used.
182 * str An input character string containing a binary number.
183 * max_bits The maximum possible significant bits.
185 * N The number of significant bits in str.
189 dst_s_calculate_bits(const u_char
*str
, const int max_bits
)
191 const u_char
*p
= str
;
194 for (bits
= max_bits
; *p
== 0x00 && bits
> 0; p
++)
196 for (i
= *p
; (i
& j
) != j
; j
>>= 1)
203 * calculates a checksum used in kmt for a id.
204 * takes an array of bytes and a length.
205 * returns a 16 bit checksum.
208 dst_s_id_calc(const u_char
*key
, const unsigned keysize
)
211 const u_char
*kp
= key
;
212 unsigned size
= keysize
;
217 for (ac
= 0; size
> 1; size
-= 2, kp
+= 2)
218 ac
+= ((*kp
) << 8) + *(kp
+ 1);
222 ac
+= (ac
>> 16) & 0xffff;
224 return (ac
& 0xffff);
228 * dst_s_dns_key_id() Function to calculated DNSSEC footprint from KEY reocrd
229 * rdata (all of record)
231 * dns_key_rdata: the raw data in wire format
232 * rdata_len: the size of the input data
234 * the key footprint/id calcuated from the key data
237 dst_s_dns_key_id(const u_char
*dns_key_rdata
, const unsigned rdata_len
)
239 unsigned key_data
= 4;
241 if (!dns_key_rdata
|| (rdata_len
< key_data
))
244 /* check the extended parameters bit in the DNS Key RR flags */
245 if (dst_s_get_int16(dns_key_rdata
) & DST_EXTEND_FLAG
)
249 if (dns_key_rdata
[3] == KEY_RSA
) /* Algorithm RSA */
250 return dst_s_get_int16((const u_char
*)
251 &dns_key_rdata
[rdata_len
- 3]);
253 /* compute a checksum on the key part of the key rr */
254 return dst_s_id_calc(&dns_key_rdata
[key_data
],
255 (rdata_len
- key_data
));
260 * This routine extracts a 16 bit integer from a two byte character
261 * string. The character string is assumed to be in network byte
262 * order and may be unaligned. The number returned is in host order.
264 * buf A two byte character string.
266 * The converted integer value.
270 dst_s_get_int16(const u_char
*buf
)
272 register u_int16_t a
= 0;
273 a
= ((u_int16_t
)(buf
[0] << 8)) | ((u_int16_t
)(buf
[1]));
280 * This routine extracts a 32 bit integer from a four byte character
281 * string. The character string is assumed to be in network byte
282 * order and may be unaligned. The number returned is in host order.
284 * buf A four byte character string.
286 * The converted integer value.
290 dst_s_get_int32(const u_char
*buf
)
292 register u_int32_t a
= 0;
293 a
= ((u_int32_t
)(buf
[0] << 24)) | ((u_int32_t
)(buf
[1] << 16)) |
294 ((u_int32_t
)(buf
[2] << 8)) | ((u_int32_t
)(buf
[3]));
301 * Take a 16 bit integer and store the value in a two byte
302 * character string. The integer is assumed to be in network
303 * order and the string is returned in host order.
306 * buf Storage for a two byte character string.
307 * val 16 bit integer.
311 dst_s_put_int16(u_int8_t
*buf
, const u_int16_t val
)
313 buf
[0] = (u_int8_t
)(val
>> 8);
314 buf
[1] = (u_int8_t
)(val
);
320 * Take a 32 bit integer and store the value in a four byte
321 * character string. The integer is assumed to be in network
322 * order and the string is returned in host order.
325 * buf Storage for a four byte character string.
326 * val 32 bit integer.
330 dst_s_put_int32(u_int8_t
*buf
, const u_int32_t val
)
332 buf
[0] = (u_int8_t
)(val
>> 24);
333 buf
[1] = (u_int8_t
)(val
>> 16);
334 buf
[2] = (u_int8_t
)(val
>> 8);
335 buf
[3] = (u_int8_t
)(val
);
340 * dst_s_filename_length
342 * This function returns the number of bytes needed to hold the
343 * filename for a key file. '/', '\' and ':' are not allowed.
344 * form: K<keyname>+<alg>+<id>.<suffix>
346 * Returns 0 if the filename would contain either '\', '/' or ':'
349 dst_s_filename_length(const char *name
, const char *suffix
)
353 if (strrchr(name
, '\\'))
355 if (strrchr(name
, '/'))
357 if (strrchr(name
, ':'))
361 if (strrchr(suffix
, '\\'))
363 if (strrchr(suffix
, '/'))
365 if (strrchr(suffix
, ':'))
367 return (1 + strlen(name
) + 6 + strlen(suffix
));
372 * dst_s_build_filename ()
373 * Builds a key filename from the key name, it's id, and a
374 * suffix. '\', '/' and ':' are not allowed. fA filename is of the
375 * form: K<keyname><id>.<suffix>
376 * form: K<keyname>+<alg>+<id>.<suffix>
378 * Returns -1 if the conversion fails:
379 * if the filename would be too long for space allotted
380 * if the filename would contain a '\', '/' or ':'
381 * Returns 0 on success
385 dst_s_build_filename(char *filename
, const char *name
, unsigned id
,
386 int alg
, const char *suffix
, size_t filename_length
)
389 if (filename
== NULL
)
391 memset(filename
, 0, filename_length
);
396 if (filename_length
< 1 + strlen(name
) + 4 + 6 + 1 + strlen(suffix
))
399 sprintf(filename
, "K%s+%03d+%05d.%s", name
, alg
, my_id
,
400 (const char *) suffix
);
401 if (strrchr(filename
, '/'))
403 if (strrchr(filename
, '\\'))
405 if (strrchr(filename
, ':'))
412 * Open a file in the dst_path directory. If perm is specified, the
413 * file is checked for existence first, and not opened if it exists.
415 * filename File to open
416 * mode Mode to open the file (passed directly to fopen)
417 * perm File permission, if creating a new file.
420 * NON-NULL (FILE *) of opened file.
423 dst_s_fopen(const char *filename
, const char *mode
, unsigned perm
)
426 char pathname
[PATH_MAX
];
427 unsigned plen
= sizeof(pathname
);
429 if (*dst_path
!= '\0') {
430 strcpy(pathname
, dst_path
);
431 plen
-= strlen(pathname
);
436 if (plen
> strlen(filename
))
437 strncpy(&pathname
[PATH_MAX
- plen
], filename
, plen
-1);
441 fp
= fopen(pathname
, mode
);
443 chmod(pathname
, perm
);
449 dst_s_dump(const int mode
, const u_char
*data
, const int size
,
454 static u_char scratch
[1000];
456 n
= b64_ntop(data
, scratch
, size
, sizeof(scratch
));
457 printf("%s: %x %d %s\n", msg
, mode
, n
, scratch
);
459 printf("%s,%x %d\n", msg
, mode
, size
);