tools/adflib: build only host variant which is used by Sam440 target
[AROS.git] / workbench / network / stacks / AROSTCP / dhcp / dst / dst_support.c
bloba7c997346fd41ac17657e66149ef35f83c42b361
1 #if !defined(__AROS__)
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 $";
3 #endif
5 /*
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.
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <memory.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <sys/stat.h>
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).
42 * Parameters
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
47 * Return
48 * -1 not enough space in output work area
49 * 0 no output
50 * >0 number of bytes written to output work area
53 int
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;
59 char *op = out_buf;
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 */
65 return (0);
67 if (out_buf == NULL || out_len <= 0) /* no output_work area */
68 return (-1);
70 /* suppress leading \0 */
71 for (; (*bp == 0x0) && (local_in_len > 0); local_in_len--)
72 bp++;
74 if (header) { /* add header to output string */
75 lenh = strlen(header);
76 if (lenh < out_len)
77 memcpy(op, header, lenh);
78 else
79 return (-1);
80 local_out_len -= lenh;
81 op += lenh;
83 len64 = b64_ntop(bp, local_in_len, op, local_out_len - 2);
84 if (len64 < 0)
85 return (-1);
86 op += len64++;
87 *(op++) = '\n'; /* put CR in the output */
88 *op = '\0'; /* make sure output is 0 terminated */
89 return (lenh + len64);
94 * dst_s_verify_str()
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).
98 * Parameters
99 * buf Input buffer.
100 * str Input string.
101 * Return
102 * 0 *str is not the head of **buff
103 * 1 *str is the head of **buff, *buf is is advanced to
104 * the tail of **buf.
108 dst_s_verify_str(const char **buf, const char *str)
110 unsigned b, s;
111 if (*buf == NULL) /* error checks */
112 return (0);
113 if (str == NULL || *str == '\0')
114 return (1);
116 b = strlen(*buf); /* get length of strings */
117 s = strlen(str);
118 if (s > b || strncmp(*buf, str, s)) /* check if same */
119 return (0); /* not a match */
120 (*buf) += s; /* advance pointer */
121 return (1);
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.
135 * Parameters
136 * buf Pointer to encoded input string. Pointer is updated if
137 * function is successfull.
138 * loc Output area.
139 * loclen Size in bytes of output area.
140 * Return
141 * >0 Return = number of bytes of binary data stored in loc.
142 * 0 Failure.
146 dst_s_conv_bignum_b64_to_u8(const char **buf,
147 u_char *loc, const unsigned loclen)
149 unsigned blen;
150 char *bp;
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"));
155 return (0);
157 bp = strchr(*buf, '\n'); /* find length of input line */
158 if (bp != NULL)
159 *bp = 0;
161 blen = b64_pton(*buf, bstr, sizeof(bstr));
162 if (blen <= 0) {
163 EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is null.\n"));
164 return (0);
166 else if (loclen < blen) {
167 EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is longer than output buffer.\n"));
168 return (0);
170 if (bp)
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 */
174 return (blen);
179 * dst_s_calculate_bits
180 * Given a binary number represented in a u_char[], determine
181 * the number of significant bits used.
182 * Parameters
183 * str An input character string containing a binary number.
184 * max_bits The maximum possible significant bits.
185 * Return
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;
193 u_char i, j = 0x80;
194 int bits;
195 for (bits = max_bits; *p == 0x00 && bits > 0; p++)
196 bits -= 8;
197 for (i = *p; (i & j) != j; j >>= 1)
198 bits--;
199 return (bits);
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.
208 u_int16_t
209 dst_s_id_calc(const u_char *key, const unsigned keysize)
211 u_int32_t ac;
212 const u_char *kp = key;
213 unsigned size = keysize;
215 if (!key)
216 return 0;
218 for (ac = 0; size > 1; size -= 2, kp += 2)
219 ac += ((*kp) << 8) + *(kp + 1);
221 if (size > 0)
222 ac += ((*kp) << 8);
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)
231 * Input:
232 * dns_key_rdata: the raw data in wire format
233 * rdata_len: the size of the input data
234 * Output:
235 * the key footprint/id calcuated from the key data
237 u_int16_t
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))
243 return 0;
245 /* check the extended parameters bit in the DNS Key RR flags */
246 if (dst_s_get_int16(dns_key_rdata) & DST_EXTEND_FLAG)
247 key_data += 2;
249 /* compute id */
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]);
253 else
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));
260 * dst_s_get_int16
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.
264 * Parameter
265 * buf A two byte character string.
266 * Return
267 * The converted integer value.
270 u_int16_t
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]));
275 return (a);
280 * dst_s_get_int32
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.
284 * Parameter
285 * buf A four byte character string.
286 * Return
287 * The converted integer value.
290 u_int32_t
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]));
296 return (a);
301 * dst_s_put_int16
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.
306 * Parameters
307 * buf Storage for a two byte character string.
308 * val 16 bit integer.
311 void
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);
320 * dst_s_put_int32
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.
325 * Parameters
326 * buf Storage for a four byte character string.
327 * val 32 bit integer.
330 void
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 ':'
349 size_t
350 dst_s_filename_length(const char *name, const char *suffix)
352 if (name == NULL)
353 return (0);
354 if (strrchr(name, '\\'))
355 return (0);
356 if (strrchr(name, '/'))
357 return (0);
358 if (strrchr(name, ':'))
359 return (0);
360 if (suffix == NULL)
361 return (0);
362 if (strrchr(suffix, '\\'))
363 return (0);
364 if (strrchr(suffix, '/'))
365 return (0);
366 if (strrchr(suffix, ':'))
367 return (0);
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)
389 unsigned my_id;
390 if (filename == NULL)
391 return (-1);
392 memset(filename, 0, filename_length);
393 if (name == NULL)
394 return (-1);
395 if (suffix == NULL)
396 return (-1);
397 if (filename_length < 1 + strlen(name) + 4 + 6 + 1 + strlen(suffix))
398 return (-1);
399 my_id = id;
400 sprintf(filename, "K%s+%03d+%05d.%s", name, alg, my_id,
401 (const char *) suffix);
402 if (strrchr(filename, '/'))
403 return (-1);
404 if (strrchr(filename, '\\'))
405 return (-1);
406 if (strrchr(filename, ':'))
407 return (-1);
408 return (0);
412 * dst_s_fopen ()
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.
415 * Parameters
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.
419 * Returns
420 * NULL Failure
421 * NON-NULL (FILE *) of opened file.
423 FILE *
424 dst_s_fopen(const char *filename, const char *mode, unsigned perm)
426 FILE *fp;
427 char pathname[PATH_MAX];
428 unsigned plen = sizeof(pathname);
430 if (*dst_path != '\0') {
431 strcpy(pathname, dst_path);
432 plen -= strlen(pathname);
434 else
435 pathname[0] = '\0';
437 if (plen > strlen(filename))
438 strncpy(&pathname[PATH_MAX - plen], filename, plen-1);
439 else
440 return (NULL);
442 fp = fopen(pathname, mode);
443 if (perm)
444 chmod(pathname, perm);
445 return (fp);
448 #if 0
449 void
450 dst_s_dump(const int mode, const u_char *data, const int size,
451 const char *msg)
453 if (size > 0) {
454 #ifdef LONG_TEST
455 static u_char scratch[1000];
456 int n ;
457 n = b64_ntop(data, scratch, size, sizeof(scratch));
458 printf("%s: %x %d %s\n", msg, mode, n, scratch);
459 #else
460 printf("%s,%x %d\n", msg, mode, size);
461 #endif
464 #endif