2 static const char rcsid
[] = "$Header: /cvsroot/unmorphos/ezTCP/dhcp/dst/dst_support.c,v 1.1.1.1 2005/12/07 10:50:33 sonic_amiga Exp $";
6 * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
8 * Permission to use, copy modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS
13 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
14 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
15 * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT,
16 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
17 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
18 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
19 * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
28 #include <netinet/in.h>
29 #include <sys/socket.h>
31 #include "minires/minires.h"
32 #include "arpa/nameser.h"
34 #include "dst_internal.h"
37 * dst_s_conv_bignum_u8_to_b64
38 * This function converts binary data stored as a u_char[] to a
39 * base-64 string. Leading zeroes are discarded. If a header is
40 * supplied, it is prefixed to the input prior to encoding. The
41 * output is \n\0 terminated (the \0 is not included in output length).
43 * out_buf binary data to convert
44 * header character string to prefix to the output (label)
45 * bin_data binary data
46 * bin_len size of binary data
48 * -1 not enough space in output work area
50 * >0 number of bytes written to output work area
54 dst_s_conv_bignum_u8_to_b64(char *out_buf
, const unsigned out_len
,
55 const char *header
, const u_char
*bin_data
,
56 const unsigned bin_len
)
58 const u_char
*bp
= bin_data
;
60 unsigned lenh
= 0, len64
= 0;
61 unsigned local_in_len
= bin_len
;
62 unsigned local_out_len
= out_len
;
64 if (bin_data
== NULL
) /* no data no */
67 if (out_buf
== NULL
|| out_len
<= 0) /* no output_work area */
70 /* suppress leading \0 */
71 for (; (*bp
== 0x0) && (local_in_len
> 0); local_in_len
--)
74 if (header
) { /* add header to output string */
75 lenh
= strlen(header
);
77 memcpy(op
, header
, lenh
);
80 local_out_len
-= lenh
;
83 len64
= b64_ntop(bp
, local_in_len
, op
, local_out_len
- 2);
87 *(op
++) = '\n'; /* put CR in the output */
88 *op
= '\0'; /* make sure output is 0 terminated */
89 return (lenh
+ len64
);
95 * Validate that the input string(*str) is at the head of the input
96 * buffer(**buf). If so, move the buffer head pointer (*buf) to
97 * the first byte of data following the string(*str).
102 * 0 *str is not the head of **buff
103 * 1 *str is the head of **buff, *buf is is advanced to
108 dst_s_verify_str(const char **buf
, const char *str
)
111 if (*buf
== NULL
) /* error checks */
113 if (str
== NULL
|| *str
== '\0')
116 b
= strlen(*buf
); /* get length of strings */
118 if (s
> b
|| strncmp(*buf
, str
, s
)) /* check if same */
119 return (0); /* not a match */
120 (*buf
) += s
; /* advance pointer */
126 * dst_s_conv_bignum_b64_to_u8
127 * Read a line of base-64 encoded string from the input buffer,
128 * convert it to binary, and store it in an output area. The
129 * input buffer is read until reaching a newline marker or the
130 * end of the buffer. The binary data is stored in the last X
131 * number of bytes of the output area where X is the size of the
132 * binary output. If the operation is successful, the input buffer
133 * pointer is advanced. This procedure does not do network to host
134 * byte order conversion.
136 * buf Pointer to encoded input string. Pointer is updated if
137 * function is successfull.
139 * loclen Size in bytes of output area.
141 * >0 Return = number of bytes of binary data stored in loc.
146 dst_s_conv_bignum_b64_to_u8(const char **buf
,
147 u_char
*loc
, const unsigned loclen
)
151 u_char bstr
[RAW_KEY_SIZE
];
153 if (buf
== NULL
|| *buf
== NULL
) { /* error checks */
154 EREPORT(("dst_s_conv_bignum_b64_to_u8: null input buffer.\n"));
157 bp
= strchr(*buf
, '\n'); /* find length of input line */
161 blen
= b64_pton(*buf
, bstr
, sizeof(bstr
));
163 EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is null.\n"));
166 else if (loclen
< blen
) {
167 EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is longer than output buffer.\n"));
171 *buf
= bp
; /* advancing buffer past \n */
172 memset(loc
, 0, loclen
- blen
); /* clearing unused output area */
173 memcpy(loc
+ loclen
- blen
, bstr
, blen
); /* write last blen bytes */
179 * dst_s_calculate_bits
180 * Given a binary number represented in a u_char[], determine
181 * the number of significant bits used.
183 * str An input character string containing a binary number.
184 * max_bits The maximum possible significant bits.
186 * N The number of significant bits in str.
190 dst_s_calculate_bits(const u_char
*str
, const int max_bits
)
192 const u_char
*p
= str
;
195 for (bits
= max_bits
; *p
== 0x00 && bits
> 0; p
++)
197 for (i
= *p
; (i
& j
) != j
; j
>>= 1)
204 * calculates a checksum used in kmt for a id.
205 * takes an array of bytes and a length.
206 * returns a 16 bit checksum.
209 dst_s_id_calc(const u_char
*key
, const unsigned keysize
)
212 const u_char
*kp
= key
;
213 unsigned size
= keysize
;
218 for (ac
= 0; size
> 1; size
-= 2, kp
+= 2)
219 ac
+= ((*kp
) << 8) + *(kp
+ 1);
223 ac
+= (ac
>> 16) & 0xffff;
225 return (ac
& 0xffff);
229 * dst_s_dns_key_id() Function to calculated DNSSEC footprint from KEY reocrd
230 * rdata (all of record)
232 * dns_key_rdata: the raw data in wire format
233 * rdata_len: the size of the input data
235 * the key footprint/id calcuated from the key data
238 dst_s_dns_key_id(const u_char
*dns_key_rdata
, const unsigned rdata_len
)
240 unsigned key_data
= 4;
242 if (!dns_key_rdata
|| (rdata_len
< key_data
))
245 /* check the extended parameters bit in the DNS Key RR flags */
246 if (dst_s_get_int16(dns_key_rdata
) & DST_EXTEND_FLAG
)
250 if (dns_key_rdata
[3] == KEY_RSA
) /* Algorithm RSA */
251 return dst_s_get_int16((const u_char
*)
252 &dns_key_rdata
[rdata_len
- 3]);
254 /* compute a checksum on the key part of the key rr */
255 return dst_s_id_calc(&dns_key_rdata
[key_data
],
256 (rdata_len
- key_data
));
261 * This routine extracts a 16 bit integer from a two byte character
262 * string. The character string is assumed to be in network byte
263 * order and may be unaligned. The number returned is in host order.
265 * buf A two byte character string.
267 * The converted integer value.
271 dst_s_get_int16(const u_char
*buf
)
273 register u_int16_t a
= 0;
274 a
= ((u_int16_t
)(buf
[0] << 8)) | ((u_int16_t
)(buf
[1]));
281 * This routine extracts a 32 bit integer from a four byte character
282 * string. The character string is assumed to be in network byte
283 * order and may be unaligned. The number returned is in host order.
285 * buf A four byte character string.
287 * The converted integer value.
291 dst_s_get_int32(const u_char
*buf
)
293 register u_int32_t a
= 0;
294 a
= ((u_int32_t
)(buf
[0] << 24)) | ((u_int32_t
)(buf
[1] << 16)) |
295 ((u_int32_t
)(buf
[2] << 8)) | ((u_int32_t
)(buf
[3]));
302 * Take a 16 bit integer and store the value in a two byte
303 * character string. The integer is assumed to be in network
304 * order and the string is returned in host order.
307 * buf Storage for a two byte character string.
308 * val 16 bit integer.
312 dst_s_put_int16(u_int8_t
*buf
, const u_int16_t val
)
314 buf
[0] = (u_int8_t
)(val
>> 8);
315 buf
[1] = (u_int8_t
)(val
);
321 * Take a 32 bit integer and store the value in a four byte
322 * character string. The integer is assumed to be in network
323 * order and the string is returned in host order.
326 * buf Storage for a four byte character string.
327 * val 32 bit integer.
331 dst_s_put_int32(u_int8_t
*buf
, const u_int32_t val
)
333 buf
[0] = (u_int8_t
)(val
>> 24);
334 buf
[1] = (u_int8_t
)(val
>> 16);
335 buf
[2] = (u_int8_t
)(val
>> 8);
336 buf
[3] = (u_int8_t
)(val
);
341 * dst_s_filename_length
343 * This function returns the number of bytes needed to hold the
344 * filename for a key file. '/', '\' and ':' are not allowed.
345 * form: K<keyname>+<alg>+<id>.<suffix>
347 * Returns 0 if the filename would contain either '\', '/' or ':'
350 dst_s_filename_length(const char *name
, const char *suffix
)
354 if (strrchr(name
, '\\'))
356 if (strrchr(name
, '/'))
358 if (strrchr(name
, ':'))
362 if (strrchr(suffix
, '\\'))
364 if (strrchr(suffix
, '/'))
366 if (strrchr(suffix
, ':'))
368 return (1 + strlen(name
) + 6 + strlen(suffix
));
373 * dst_s_build_filename ()
374 * Builds a key filename from the key name, it's id, and a
375 * suffix. '\', '/' and ':' are not allowed. fA filename is of the
376 * form: K<keyname><id>.<suffix>
377 * form: K<keyname>+<alg>+<id>.<suffix>
379 * Returns -1 if the conversion fails:
380 * if the filename would be too long for space allotted
381 * if the filename would contain a '\', '/' or ':'
382 * Returns 0 on success
386 dst_s_build_filename(char *filename
, const char *name
, unsigned id
,
387 int alg
, const char *suffix
, size_t filename_length
)
390 if (filename
== NULL
)
392 memset(filename
, 0, filename_length
);
397 if (filename_length
< 1 + strlen(name
) + 4 + 6 + 1 + strlen(suffix
))
400 sprintf(filename
, "K%s+%03d+%05d.%s", name
, alg
, my_id
,
401 (const char *) suffix
);
402 if (strrchr(filename
, '/'))
404 if (strrchr(filename
, '\\'))
406 if (strrchr(filename
, ':'))
413 * Open a file in the dst_path directory. If perm is specified, the
414 * file is checked for existence first, and not opened if it exists.
416 * filename File to open
417 * mode Mode to open the file (passed directly to fopen)
418 * perm File permission, if creating a new file.
421 * NON-NULL (FILE *) of opened file.
424 dst_s_fopen(const char *filename
, const char *mode
, unsigned perm
)
427 char pathname
[PATH_MAX
];
428 unsigned plen
= sizeof(pathname
);
430 if (*dst_path
!= '\0') {
431 strcpy(pathname
, dst_path
);
432 plen
-= strlen(pathname
);
437 if (plen
> strlen(filename
))
438 strncpy(&pathname
[PATH_MAX
- plen
], filename
, plen
-1);
442 fp
= fopen(pathname
, mode
);
444 chmod(pathname
, perm
);
450 dst_s_dump(const int mode
, const u_char
*data
, const int size
,
455 static u_char scratch
[1000];
457 n
= b64_ntop(data
, scratch
, size
, sizeof(scratch
));
458 printf("%s: %x %d %s\n", msg
, mode
, n
, scratch
);
460 printf("%s,%x %d\n", msg
, mode
, size
);