xref: /minix3/external/bsd/dhcp/dist/dst/dst_support.c (revision 83ee113ee0d94f3844d44065af2311604e9a30ad)
1*83ee113eSDavid van Moolenbroek /*	$NetBSD: dst_support.c,v 1.1.1.4 2014/07/12 11:57:50 spz Exp $	*/
2*83ee113eSDavid van Moolenbroek static const char rcsid[] = "Header: /tmp/cvstest/DHCP/dst/dst_support.c,v 1.7 2009/11/24 02:06:56 sar Exp ";
3*83ee113eSDavid van Moolenbroek 
4*83ee113eSDavid van Moolenbroek 
5*83ee113eSDavid van Moolenbroek /*
6*83ee113eSDavid van Moolenbroek  * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
7*83ee113eSDavid van Moolenbroek  * Portions Copyright (c) 2007,2009 by Internet Systems Consortium, Inc. ("ISC")
8*83ee113eSDavid van Moolenbroek  * Portions Copyright (c) 2012 by Internet Systems Consortium, Inc. ("ISC")
9*83ee113eSDavid van Moolenbroek  *
10*83ee113eSDavid van Moolenbroek  * Permission to use, copy modify, and distribute this software for any
11*83ee113eSDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
12*83ee113eSDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
13*83ee113eSDavid van Moolenbroek  *
14*83ee113eSDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS
15*83ee113eSDavid van Moolenbroek  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
16*83ee113eSDavid van Moolenbroek  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL
17*83ee113eSDavid van Moolenbroek  * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT,
18*83ee113eSDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
19*83ee113eSDavid van Moolenbroek  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20*83ee113eSDavid van Moolenbroek  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21*83ee113eSDavid van Moolenbroek  * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
22*83ee113eSDavid van Moolenbroek  */
23*83ee113eSDavid van Moolenbroek 
24*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
25*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: dst_support.c,v 1.1.1.4 2014/07/12 11:57:50 spz Exp $");
26*83ee113eSDavid van Moolenbroek 
27*83ee113eSDavid van Moolenbroek #include <stdio.h>
28*83ee113eSDavid van Moolenbroek #include <unistd.h>
29*83ee113eSDavid van Moolenbroek #include <memory.h>
30*83ee113eSDavid van Moolenbroek #include <string.h>
31*83ee113eSDavid van Moolenbroek #include <errno.h>
32*83ee113eSDavid van Moolenbroek #include <sys/stat.h>
33*83ee113eSDavid van Moolenbroek #include <netinet/in.h>
34*83ee113eSDavid van Moolenbroek #include <sys/socket.h>
35*83ee113eSDavid van Moolenbroek 
36*83ee113eSDavid van Moolenbroek #include "cdefs.h"
37*83ee113eSDavid van Moolenbroek #include "osdep.h"
38*83ee113eSDavid van Moolenbroek #include "arpa/nameser.h"
39*83ee113eSDavid van Moolenbroek 
40*83ee113eSDavid van Moolenbroek #include "dst_internal.h"
41*83ee113eSDavid van Moolenbroek 
42*83ee113eSDavid van Moolenbroek /*
43*83ee113eSDavid van Moolenbroek  * dst_s_conv_bignum_u8_to_b64
44*83ee113eSDavid van Moolenbroek  *	This function converts binary data stored as a u_char[] to a
45*83ee113eSDavid van Moolenbroek  *	base-64 string.  Leading zeroes are discarded.  If a header is
46*83ee113eSDavid van Moolenbroek  *	supplied, it is prefixed to the input prior to encoding.  The
47*83ee113eSDavid van Moolenbroek  *	output is \n\0 terminated (the \0 is not included in output length).
48*83ee113eSDavid van Moolenbroek  * Parameters
49*83ee113eSDavid van Moolenbroek  *     out_buf   binary data to convert
50*83ee113eSDavid van Moolenbroek  *     header    character string to prefix to the output (label)
51*83ee113eSDavid van Moolenbroek  *     bin_data  binary data
52*83ee113eSDavid van Moolenbroek  *     bin_len   size of binary data
53*83ee113eSDavid van Moolenbroek  * Return
54*83ee113eSDavid van Moolenbroek  *     -1     not enough space in output work area
55*83ee113eSDavid van Moolenbroek  *	0     no output
56*83ee113eSDavid van Moolenbroek  *     >0     number of bytes written to output work area
57*83ee113eSDavid van Moolenbroek  */
58*83ee113eSDavid van Moolenbroek 
59*83ee113eSDavid van Moolenbroek int
dst_s_conv_bignum_u8_to_b64(char * out_buf,const unsigned out_len,const char * header,const u_char * bin_data,const unsigned bin_len)60*83ee113eSDavid van Moolenbroek dst_s_conv_bignum_u8_to_b64(char *out_buf, const unsigned out_len,
61*83ee113eSDavid van Moolenbroek 			    const char *header, const u_char *bin_data,
62*83ee113eSDavid van Moolenbroek 			    const unsigned bin_len)
63*83ee113eSDavid van Moolenbroek {
64*83ee113eSDavid van Moolenbroek 	const u_char *bp = bin_data;
65*83ee113eSDavid van Moolenbroek 	char *op = out_buf;
66*83ee113eSDavid van Moolenbroek 	int res = 0;
67*83ee113eSDavid van Moolenbroek 	unsigned lenh = 0, len64 = 0;
68*83ee113eSDavid van Moolenbroek 	unsigned local_in_len = bin_len;
69*83ee113eSDavid van Moolenbroek 	unsigned local_out_len = out_len;
70*83ee113eSDavid van Moolenbroek 
71*83ee113eSDavid van Moolenbroek 	if (bin_data == NULL)	/* no data no */
72*83ee113eSDavid van Moolenbroek 		return (0);
73*83ee113eSDavid van Moolenbroek 
74*83ee113eSDavid van Moolenbroek 	if (out_buf == NULL || out_len <= 0)	/* no output_work area */
75*83ee113eSDavid van Moolenbroek 		return (-1);
76*83ee113eSDavid van Moolenbroek 
77*83ee113eSDavid van Moolenbroek 	/* suppress leading \0  */
78*83ee113eSDavid van Moolenbroek 	for (; (*bp == 0x0) && (local_in_len > 0); local_in_len--)
79*83ee113eSDavid van Moolenbroek 		bp++;
80*83ee113eSDavid van Moolenbroek 
81*83ee113eSDavid van Moolenbroek 	if (header) {		/* add header to output string */
82*83ee113eSDavid van Moolenbroek 		lenh = strlen(header);
83*83ee113eSDavid van Moolenbroek 		if (lenh < out_len)
84*83ee113eSDavid van Moolenbroek 			memcpy(op, header, lenh);
85*83ee113eSDavid van Moolenbroek 		else
86*83ee113eSDavid van Moolenbroek 			return (-1);
87*83ee113eSDavid van Moolenbroek 		local_out_len -= lenh;
88*83ee113eSDavid van Moolenbroek 		op += lenh;
89*83ee113eSDavid van Moolenbroek 	}
90*83ee113eSDavid van Moolenbroek 	res = b64_ntop(bp, local_in_len, op, local_out_len - 2);
91*83ee113eSDavid van Moolenbroek 	if (res < 0)
92*83ee113eSDavid van Moolenbroek 		return (-1);
93*83ee113eSDavid van Moolenbroek 	len64 = (unsigned) res;
94*83ee113eSDavid van Moolenbroek 	op += len64++;
95*83ee113eSDavid van Moolenbroek 	*(op++) = '\n';		/* put CR in the output */
96*83ee113eSDavid van Moolenbroek 	*op = '\0';		/* make sure output is 0 terminated */
97*83ee113eSDavid van Moolenbroek 	return (lenh + len64);
98*83ee113eSDavid van Moolenbroek }
99*83ee113eSDavid van Moolenbroek 
100*83ee113eSDavid van Moolenbroek 
101*83ee113eSDavid van Moolenbroek /*
102*83ee113eSDavid van Moolenbroek  * dst_s_verify_str()
103*83ee113eSDavid van Moolenbroek  *     Validate that the input string(*str) is at the head of the input
104*83ee113eSDavid van Moolenbroek  *     buffer(**buf).  If so, move the buffer head pointer (*buf) to
105*83ee113eSDavid van Moolenbroek  *     the first byte of data following the string(*str).
106*83ee113eSDavid van Moolenbroek  * Parameters
107*83ee113eSDavid van Moolenbroek  *     buf     Input buffer.
108*83ee113eSDavid van Moolenbroek  *     str     Input string.
109*83ee113eSDavid van Moolenbroek  * Return
110*83ee113eSDavid van Moolenbroek  *	0       *str is not the head of **buff
111*83ee113eSDavid van Moolenbroek  *	1       *str is the head of **buff, *buf is is advanced to
112*83ee113eSDavid van Moolenbroek  *	the tail of **buf.
113*83ee113eSDavid van Moolenbroek  */
114*83ee113eSDavid van Moolenbroek 
115*83ee113eSDavid van Moolenbroek int
dst_s_verify_str(const char ** buf,const char * str)116*83ee113eSDavid van Moolenbroek dst_s_verify_str(const char **buf, const char *str)
117*83ee113eSDavid van Moolenbroek {
118*83ee113eSDavid van Moolenbroek 	unsigned b, s;
119*83ee113eSDavid van Moolenbroek 	if (*buf == NULL)	/* error checks */
120*83ee113eSDavid van Moolenbroek 		return (0);
121*83ee113eSDavid van Moolenbroek 	if (str == NULL || *str == '\0')
122*83ee113eSDavid van Moolenbroek 		return (1);
123*83ee113eSDavid van Moolenbroek 
124*83ee113eSDavid van Moolenbroek 	b = strlen(*buf);	/* get length of strings */
125*83ee113eSDavid van Moolenbroek 	s = strlen(str);
126*83ee113eSDavid van Moolenbroek 	if (s > b || strncmp(*buf, str, s))	/* check if same */
127*83ee113eSDavid van Moolenbroek 		return (0);	/* not a match */
128*83ee113eSDavid van Moolenbroek 	(*buf) += s;		/* advance pointer */
129*83ee113eSDavid van Moolenbroek 	return (1);
130*83ee113eSDavid van Moolenbroek }
131*83ee113eSDavid van Moolenbroek 
132*83ee113eSDavid van Moolenbroek 
133*83ee113eSDavid van Moolenbroek /*
134*83ee113eSDavid van Moolenbroek  * dst_s_conv_bignum_b64_to_u8
135*83ee113eSDavid van Moolenbroek  *     Read a line of base-64 encoded string from the input buffer,
136*83ee113eSDavid van Moolenbroek  *     convert it to binary, and store it in an output area.  The
137*83ee113eSDavid van Moolenbroek  *     input buffer is read until reaching a newline marker or the
138*83ee113eSDavid van Moolenbroek  *     end of the buffer.  The binary data is stored in the last X
139*83ee113eSDavid van Moolenbroek  *     number of bytes of the output area where X is the size of the
140*83ee113eSDavid van Moolenbroek  *     binary output.  If the operation is successful, the input buffer
141*83ee113eSDavid van Moolenbroek  *     pointer is advanced.  This procedure does not do network to host
142*83ee113eSDavid van Moolenbroek  *     byte order conversion.
143*83ee113eSDavid van Moolenbroek  * Parameters
144*83ee113eSDavid van Moolenbroek  *     buf     Pointer to encoded input string. Pointer is updated if
145*83ee113eSDavid van Moolenbroek  *	   function is successful.
146*83ee113eSDavid van Moolenbroek  *     loc     Output area.
147*83ee113eSDavid van Moolenbroek  *     loclen  Size in bytes of output area.
148*83ee113eSDavid van Moolenbroek  * Return
149*83ee113eSDavid van Moolenbroek  *	>0      Return = number of bytes of binary data stored in loc.
150*83ee113eSDavid van Moolenbroek  *	 0      Failure.
151*83ee113eSDavid van Moolenbroek  */
152*83ee113eSDavid van Moolenbroek 
153*83ee113eSDavid van Moolenbroek int
dst_s_conv_bignum_b64_to_u8(const char ** buf,u_char * loc,const unsigned loclen)154*83ee113eSDavid van Moolenbroek dst_s_conv_bignum_b64_to_u8(const char **buf,
155*83ee113eSDavid van Moolenbroek 			    u_char *loc, const unsigned loclen)
156*83ee113eSDavid van Moolenbroek {
157*83ee113eSDavid van Moolenbroek 	unsigned blen;
158*83ee113eSDavid van Moolenbroek 	char *bp;
159*83ee113eSDavid van Moolenbroek 	u_char bstr[RAW_KEY_SIZE];
160*83ee113eSDavid van Moolenbroek 	int res = 0;
161*83ee113eSDavid van Moolenbroek 
162*83ee113eSDavid van Moolenbroek 	if (buf == NULL || *buf == NULL) {	/* error checks */
163*83ee113eSDavid van Moolenbroek 		EREPORT(("dst_s_conv_bignum_b64_to_u8: null input buffer.\n"));
164*83ee113eSDavid van Moolenbroek 		return (0);
165*83ee113eSDavid van Moolenbroek 	}
166*83ee113eSDavid van Moolenbroek 	bp = strchr(*buf, '\n');	/* find length of input line */
167*83ee113eSDavid van Moolenbroek 	if (bp != NULL)
168*83ee113eSDavid van Moolenbroek 		*bp = '\0';
169*83ee113eSDavid van Moolenbroek 
170*83ee113eSDavid van Moolenbroek 	res = b64_pton(*buf, bstr, sizeof(bstr));
171*83ee113eSDavid van Moolenbroek 	if (res <= 0) {
172*83ee113eSDavid van Moolenbroek 		EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is null.\n"));
173*83ee113eSDavid van Moolenbroek 		return (0);
174*83ee113eSDavid van Moolenbroek 	}
175*83ee113eSDavid van Moolenbroek 	blen = (unsigned) res;
176*83ee113eSDavid van Moolenbroek 	if (loclen < blen) {
177*83ee113eSDavid van Moolenbroek 		EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is longer than output buffer.\n"));
178*83ee113eSDavid van Moolenbroek 		return (0);
179*83ee113eSDavid van Moolenbroek 	}
180*83ee113eSDavid van Moolenbroek 	if (bp)
181*83ee113eSDavid van Moolenbroek 		*buf = bp;	/* advancing buffer past \n */
182*83ee113eSDavid van Moolenbroek 	memset(loc, 0, loclen - blen);	/* clearing unused output area */
183*83ee113eSDavid van Moolenbroek 	memcpy(loc + loclen - blen, bstr, blen);	/* write last blen bytes  */
184*83ee113eSDavid van Moolenbroek 	return (blen);
185*83ee113eSDavid van Moolenbroek }
186*83ee113eSDavid van Moolenbroek 
187*83ee113eSDavid van Moolenbroek 
188*83ee113eSDavid van Moolenbroek /*
189*83ee113eSDavid van Moolenbroek  * dst_s_calculate_bits
190*83ee113eSDavid van Moolenbroek  *     Given a binary number represented in a u_char[], determine
191*83ee113eSDavid van Moolenbroek  *     the number of significant bits used.
192*83ee113eSDavid van Moolenbroek  * Parameters
193*83ee113eSDavid van Moolenbroek  *     str       An input character string containing a binary number.
194*83ee113eSDavid van Moolenbroek  *     max_bits The maximum possible significant bits.
195*83ee113eSDavid van Moolenbroek  * Return
196*83ee113eSDavid van Moolenbroek  *     N       The number of significant bits in str.
197*83ee113eSDavid van Moolenbroek  */
198*83ee113eSDavid van Moolenbroek 
199*83ee113eSDavid van Moolenbroek int
dst_s_calculate_bits(const u_char * str,const int max_bits)200*83ee113eSDavid van Moolenbroek dst_s_calculate_bits(const u_char *str, const int max_bits)
201*83ee113eSDavid van Moolenbroek {
202*83ee113eSDavid van Moolenbroek 	const u_char *p = str;
203*83ee113eSDavid van Moolenbroek 	u_char i, j = 0x80;
204*83ee113eSDavid van Moolenbroek 	int bits;
205*83ee113eSDavid van Moolenbroek 	for (bits = max_bits; *p == 0x00 && bits > 0; p++)
206*83ee113eSDavid van Moolenbroek 		bits -= 8;
207*83ee113eSDavid van Moolenbroek 	for (i = *p; (i & j) != j; j >>= 1)
208*83ee113eSDavid van Moolenbroek 		bits--;
209*83ee113eSDavid van Moolenbroek 	return (bits);
210*83ee113eSDavid van Moolenbroek }
211*83ee113eSDavid van Moolenbroek 
212*83ee113eSDavid van Moolenbroek 
213*83ee113eSDavid van Moolenbroek /*
214*83ee113eSDavid van Moolenbroek  * calculates a checksum used in kmt for a id.
215*83ee113eSDavid van Moolenbroek  * takes an array of bytes and a length.
216*83ee113eSDavid van Moolenbroek  * returns a 16  bit checksum.
217*83ee113eSDavid van Moolenbroek  */
218*83ee113eSDavid van Moolenbroek u_int16_t
dst_s_id_calc(const u_char * key,const unsigned keysize)219*83ee113eSDavid van Moolenbroek dst_s_id_calc(const u_char *key, const unsigned keysize)
220*83ee113eSDavid van Moolenbroek {
221*83ee113eSDavid van Moolenbroek 	u_int32_t ac;
222*83ee113eSDavid van Moolenbroek 	const u_char *kp = key;
223*83ee113eSDavid van Moolenbroek 	unsigned size = keysize;
224*83ee113eSDavid van Moolenbroek 
225*83ee113eSDavid van Moolenbroek 	if (!key)
226*83ee113eSDavid van Moolenbroek 		return 0;
227*83ee113eSDavid van Moolenbroek 
228*83ee113eSDavid van Moolenbroek 	for (ac = 0; size > 1; size -= 2, kp += 2)
229*83ee113eSDavid van Moolenbroek 		ac += ((*kp) << 8) + *(kp + 1);
230*83ee113eSDavid van Moolenbroek 
231*83ee113eSDavid van Moolenbroek 	if (size > 0)
232*83ee113eSDavid van Moolenbroek 		ac += ((*kp) << 8);
233*83ee113eSDavid van Moolenbroek 	ac += (ac >> 16) & 0xffff;
234*83ee113eSDavid van Moolenbroek 
235*83ee113eSDavid van Moolenbroek 	return (ac & 0xffff);
236*83ee113eSDavid van Moolenbroek }
237*83ee113eSDavid van Moolenbroek 
238*83ee113eSDavid van Moolenbroek /*
239*83ee113eSDavid van Moolenbroek  * dst_s_dns_key_id() Function to calculated DNSSEC footprint from KEY record
240*83ee113eSDavid van Moolenbroek  *   rdata (all of  record)
241*83ee113eSDavid van Moolenbroek  * Input:
242*83ee113eSDavid van Moolenbroek  *	dns_key_rdata: the raw data in wire format
243*83ee113eSDavid van Moolenbroek  *      rdata_len: the size of the input data
244*83ee113eSDavid van Moolenbroek  * Output:
245*83ee113eSDavid van Moolenbroek  *      the key footprint/id calculated from the key data
246*83ee113eSDavid van Moolenbroek  */
247*83ee113eSDavid van Moolenbroek u_int16_t
dst_s_dns_key_id(const u_char * dns_key_rdata,const unsigned rdata_len)248*83ee113eSDavid van Moolenbroek dst_s_dns_key_id(const u_char *dns_key_rdata, const unsigned rdata_len)
249*83ee113eSDavid van Moolenbroek {
250*83ee113eSDavid van Moolenbroek 	unsigned key_data = 4;
251*83ee113eSDavid van Moolenbroek 
252*83ee113eSDavid van Moolenbroek 	if (!dns_key_rdata || (rdata_len < key_data))
253*83ee113eSDavid van Moolenbroek 		return 0;
254*83ee113eSDavid van Moolenbroek 
255*83ee113eSDavid van Moolenbroek 	/* check the extended parameters bit in the DNS Key RR flags */
256*83ee113eSDavid van Moolenbroek 	if (dst_s_get_int16(dns_key_rdata) & DST_EXTEND_FLAG)
257*83ee113eSDavid van Moolenbroek 		key_data += 2;
258*83ee113eSDavid van Moolenbroek 
259*83ee113eSDavid van Moolenbroek 	/* compute id */
260*83ee113eSDavid van Moolenbroek 	if (dns_key_rdata[3] == KEY_RSA)	/* Algorithm RSA */
261*83ee113eSDavid van Moolenbroek 		return dst_s_get_int16((const u_char *)
262*83ee113eSDavid van Moolenbroek 				       &dns_key_rdata[rdata_len - 3]);
263*83ee113eSDavid van Moolenbroek 	else
264*83ee113eSDavid van Moolenbroek 		/* compute a checksum on the key part of the key rr */
265*83ee113eSDavid van Moolenbroek 		return dst_s_id_calc(&dns_key_rdata[key_data],
266*83ee113eSDavid van Moolenbroek 				     (rdata_len - key_data));
267*83ee113eSDavid van Moolenbroek }
268*83ee113eSDavid van Moolenbroek 
269*83ee113eSDavid van Moolenbroek /*
270*83ee113eSDavid van Moolenbroek  * dst_s_get_int16
271*83ee113eSDavid van Moolenbroek  *     This routine extracts a 16 bit integer from a two byte character
272*83ee113eSDavid van Moolenbroek  *     string.  The character string is assumed to be in network byte
273*83ee113eSDavid van Moolenbroek  *     order and may be unaligned.  The number returned is in host order.
274*83ee113eSDavid van Moolenbroek  * Parameter
275*83ee113eSDavid van Moolenbroek  *     buf     A two byte character string.
276*83ee113eSDavid van Moolenbroek  * Return
277*83ee113eSDavid van Moolenbroek  *     The converted integer value.
278*83ee113eSDavid van Moolenbroek  */
279*83ee113eSDavid van Moolenbroek 
280*83ee113eSDavid van Moolenbroek u_int16_t
dst_s_get_int16(const u_char * buf)281*83ee113eSDavid van Moolenbroek dst_s_get_int16(const u_char *buf)
282*83ee113eSDavid van Moolenbroek {
283*83ee113eSDavid van Moolenbroek 	register u_int16_t a = 0;
284*83ee113eSDavid van Moolenbroek 	a = ((u_int16_t)(buf[0] << 8)) | ((u_int16_t)(buf[1]));
285*83ee113eSDavid van Moolenbroek 	return (a);
286*83ee113eSDavid van Moolenbroek }
287*83ee113eSDavid van Moolenbroek 
288*83ee113eSDavid van Moolenbroek 
289*83ee113eSDavid van Moolenbroek /*
290*83ee113eSDavid van Moolenbroek  * dst_s_get_int32
291*83ee113eSDavid van Moolenbroek  *     This routine extracts a 32 bit integer from a four byte character
292*83ee113eSDavid van Moolenbroek  *     string.  The character string is assumed to be in network byte
293*83ee113eSDavid van Moolenbroek  *     order and may be unaligned.  The number returned is in host order.
294*83ee113eSDavid van Moolenbroek  * Parameter
295*83ee113eSDavid van Moolenbroek  *     buf     A four byte character string.
296*83ee113eSDavid van Moolenbroek  * Return
297*83ee113eSDavid van Moolenbroek  *     The converted integer value.
298*83ee113eSDavid van Moolenbroek  */
299*83ee113eSDavid van Moolenbroek 
300*83ee113eSDavid van Moolenbroek u_int32_t
dst_s_get_int32(const u_char * buf)301*83ee113eSDavid van Moolenbroek dst_s_get_int32(const u_char *buf)
302*83ee113eSDavid van Moolenbroek {
303*83ee113eSDavid van Moolenbroek 	register u_int32_t a = 0;
304*83ee113eSDavid van Moolenbroek 	a = ((u_int32_t)(buf[0] << 24)) | ((u_int32_t)(buf[1] << 16)) |
305*83ee113eSDavid van Moolenbroek 		((u_int32_t)(buf[2] << 8)) | ((u_int32_t)(buf[3]));
306*83ee113eSDavid van Moolenbroek 	return (a);
307*83ee113eSDavid van Moolenbroek }
308*83ee113eSDavid van Moolenbroek 
309*83ee113eSDavid van Moolenbroek 
310*83ee113eSDavid van Moolenbroek /*
311*83ee113eSDavid van Moolenbroek  * dst_s_put_int16
312*83ee113eSDavid van Moolenbroek  *     Take a 16 bit integer and store the value in a two byte
313*83ee113eSDavid van Moolenbroek  *     character string.  The integer is assumed to be in network
314*83ee113eSDavid van Moolenbroek  *     order and the string is returned in host order.
315*83ee113eSDavid van Moolenbroek  *
316*83ee113eSDavid van Moolenbroek  * Parameters
317*83ee113eSDavid van Moolenbroek  *     buf     Storage for a two byte character string.
318*83ee113eSDavid van Moolenbroek  *     val     16 bit integer.
319*83ee113eSDavid van Moolenbroek  */
320*83ee113eSDavid van Moolenbroek 
321*83ee113eSDavid van Moolenbroek void
dst_s_put_int16(u_int8_t * buf,const u_int16_t val)322*83ee113eSDavid van Moolenbroek dst_s_put_int16(u_int8_t *buf, const u_int16_t val)
323*83ee113eSDavid van Moolenbroek {
324*83ee113eSDavid van Moolenbroek 	buf[0] = (u_int8_t)(val >> 8);
325*83ee113eSDavid van Moolenbroek 	buf[1] = (u_int8_t)(val);
326*83ee113eSDavid van Moolenbroek }
327*83ee113eSDavid van Moolenbroek 
328*83ee113eSDavid van Moolenbroek 
329*83ee113eSDavid van Moolenbroek /*
330*83ee113eSDavid van Moolenbroek  * dst_s_put_int32
331*83ee113eSDavid van Moolenbroek  *     Take a 32 bit integer and store the value in a four byte
332*83ee113eSDavid van Moolenbroek  *     character string.  The integer is assumed to be in network
333*83ee113eSDavid van Moolenbroek  *     order and the string is returned in host order.
334*83ee113eSDavid van Moolenbroek  *
335*83ee113eSDavid van Moolenbroek  * Parameters
336*83ee113eSDavid van Moolenbroek  *     buf     Storage for a four byte character string.
337*83ee113eSDavid van Moolenbroek  *     val     32 bit integer.
338*83ee113eSDavid van Moolenbroek  */
339*83ee113eSDavid van Moolenbroek 
340*83ee113eSDavid van Moolenbroek void
dst_s_put_int32(u_int8_t * buf,const u_int32_t val)341*83ee113eSDavid van Moolenbroek dst_s_put_int32(u_int8_t *buf, const u_int32_t val)
342*83ee113eSDavid van Moolenbroek {
343*83ee113eSDavid van Moolenbroek 	buf[0] = (u_int8_t)(val >> 24);
344*83ee113eSDavid van Moolenbroek 	buf[1] = (u_int8_t)(val >> 16);
345*83ee113eSDavid van Moolenbroek 	buf[2] = (u_int8_t)(val >> 8);
346*83ee113eSDavid van Moolenbroek 	buf[3] = (u_int8_t)(val);
347*83ee113eSDavid van Moolenbroek }
348*83ee113eSDavid van Moolenbroek 
349*83ee113eSDavid van Moolenbroek 
350*83ee113eSDavid van Moolenbroek /*
351*83ee113eSDavid van Moolenbroek  *  dst_s_filename_length
352*83ee113eSDavid van Moolenbroek  *
353*83ee113eSDavid van Moolenbroek  *	This function returns the number of bytes needed to hold the
354*83ee113eSDavid van Moolenbroek  *	filename for a key file.  '/', '\' and ':' are not allowed.
355*83ee113eSDavid van Moolenbroek  *	form:  K<keyname>+<alg>+<id>.<suffix>
356*83ee113eSDavid van Moolenbroek  *
357*83ee113eSDavid van Moolenbroek  *	Returns 0 if the filename would contain either '\', '/' or ':'
358*83ee113eSDavid van Moolenbroek  */
359*83ee113eSDavid van Moolenbroek size_t
dst_s_filename_length(const char * name,const char * suffix)360*83ee113eSDavid van Moolenbroek dst_s_filename_length(const char *name, const char *suffix)
361*83ee113eSDavid van Moolenbroek {
362*83ee113eSDavid van Moolenbroek 	if (name == NULL)
363*83ee113eSDavid van Moolenbroek 		return (0);
364*83ee113eSDavid van Moolenbroek 	if (strrchr(name, '\\'))
365*83ee113eSDavid van Moolenbroek 		return (0);
366*83ee113eSDavid van Moolenbroek 	if (strrchr(name, '/'))
367*83ee113eSDavid van Moolenbroek 		return (0);
368*83ee113eSDavid van Moolenbroek 	if (strrchr(name, ':'))
369*83ee113eSDavid van Moolenbroek 		return (0);
370*83ee113eSDavid van Moolenbroek 	if (suffix == NULL)
371*83ee113eSDavid van Moolenbroek 		return (0);
372*83ee113eSDavid van Moolenbroek 	if (strrchr(suffix, '\\'))
373*83ee113eSDavid van Moolenbroek 		return (0);
374*83ee113eSDavid van Moolenbroek 	if (strrchr(suffix, '/'))
375*83ee113eSDavid van Moolenbroek 		return (0);
376*83ee113eSDavid van Moolenbroek 	if (strrchr(suffix, ':'))
377*83ee113eSDavid van Moolenbroek 		return (0);
378*83ee113eSDavid van Moolenbroek 	return (1 + strlen(name) + 6 + strlen(suffix));
379*83ee113eSDavid van Moolenbroek }
380*83ee113eSDavid van Moolenbroek 
381*83ee113eSDavid van Moolenbroek 
382*83ee113eSDavid van Moolenbroek /*
383*83ee113eSDavid van Moolenbroek  *  dst_s_build_filename ()
384*83ee113eSDavid van Moolenbroek  *	Builds a key filename from the key name, it's id, and a
385*83ee113eSDavid van Moolenbroek  *	suffix.  '\', '/' and ':' are not allowed. fA filename is of the
386*83ee113eSDavid van Moolenbroek  *	form:  K<keyname><id>.<suffix>
387*83ee113eSDavid van Moolenbroek  *	form: K<keyname>+<alg>+<id>.<suffix>
388*83ee113eSDavid van Moolenbroek  *
389*83ee113eSDavid van Moolenbroek  *	Returns -1 if the conversion fails:
390*83ee113eSDavid van Moolenbroek  *	  if the filename would be too long for space allotted
391*83ee113eSDavid van Moolenbroek  *	  if the filename would contain a '\', '/' or ':'
392*83ee113eSDavid van Moolenbroek  *	Returns 0 on success
393*83ee113eSDavid van Moolenbroek  */
394*83ee113eSDavid van Moolenbroek 
395*83ee113eSDavid van Moolenbroek int
dst_s_build_filename(char * filename,const char * name,unsigned id,int alg,const char * suffix,size_t filename_length)396*83ee113eSDavid van Moolenbroek dst_s_build_filename(char *filename, const char *name, unsigned id,
397*83ee113eSDavid van Moolenbroek 		     int alg, const char *suffix, size_t filename_length)
398*83ee113eSDavid van Moolenbroek {
399*83ee113eSDavid van Moolenbroek 	unsigned my_id;
400*83ee113eSDavid van Moolenbroek 	if (filename == NULL)
401*83ee113eSDavid van Moolenbroek 		return (-1);
402*83ee113eSDavid van Moolenbroek 	memset(filename, 0, filename_length);
403*83ee113eSDavid van Moolenbroek 	if (name == NULL)
404*83ee113eSDavid van Moolenbroek 		return (-1);
405*83ee113eSDavid van Moolenbroek 	if (suffix == NULL)
406*83ee113eSDavid van Moolenbroek 		return (-1);
407*83ee113eSDavid van Moolenbroek 	if (filename_length < 1 + strlen(name) + 4 + 6 + 1 + strlen(suffix))
408*83ee113eSDavid van Moolenbroek 		return (-1);
409*83ee113eSDavid van Moolenbroek 	my_id = id;
410*83ee113eSDavid van Moolenbroek 	sprintf(filename, "K%s+%03d+%05d.%s", name, alg, my_id,
411*83ee113eSDavid van Moolenbroek 		(const char *) suffix);
412*83ee113eSDavid van Moolenbroek 	if (strrchr(filename, '/'))
413*83ee113eSDavid van Moolenbroek 		return (-1);
414*83ee113eSDavid van Moolenbroek 	if (strrchr(filename, '\\'))
415*83ee113eSDavid van Moolenbroek 		return (-1);
416*83ee113eSDavid van Moolenbroek 	if (strrchr(filename, ':'))
417*83ee113eSDavid van Moolenbroek 		return (-1);
418*83ee113eSDavid van Moolenbroek 	return (0);
419*83ee113eSDavid van Moolenbroek }
420*83ee113eSDavid van Moolenbroek 
421*83ee113eSDavid van Moolenbroek /*
422*83ee113eSDavid van Moolenbroek  *  dst_s_fopen ()
423*83ee113eSDavid van Moolenbroek  *     Open a file in the dst_path directory.  If perm is specified, the
424*83ee113eSDavid van Moolenbroek  *     file is checked for existence first, and not opened if it exists.
425*83ee113eSDavid van Moolenbroek  *  Parameters
426*83ee113eSDavid van Moolenbroek  *     filename  File to open
427*83ee113eSDavid van Moolenbroek  *     mode       Mode to open the file (passed directly to fopen)
428*83ee113eSDavid van Moolenbroek  *     perm       File permission, if creating a new file.
429*83ee113eSDavid van Moolenbroek  *  Returns
430*83ee113eSDavid van Moolenbroek  *     NULL       Failure
431*83ee113eSDavid van Moolenbroek  *     NON-NULL  (FILE *) of opened file.
432*83ee113eSDavid van Moolenbroek  */
433*83ee113eSDavid van Moolenbroek FILE *
dst_s_fopen(const char * filename,const char * mode,unsigned perm)434*83ee113eSDavid van Moolenbroek dst_s_fopen(const char *filename, const char *mode, unsigned perm)
435*83ee113eSDavid van Moolenbroek {
436*83ee113eSDavid van Moolenbroek 	FILE *fp;
437*83ee113eSDavid van Moolenbroek 	char pathname[PATH_MAX];
438*83ee113eSDavid van Moolenbroek 	unsigned plen = sizeof(pathname);
439*83ee113eSDavid van Moolenbroek 
440*83ee113eSDavid van Moolenbroek 	if (*dst_path != '\0') {
441*83ee113eSDavid van Moolenbroek 		strncpy(pathname, dst_path, PATH_MAX);
442*83ee113eSDavid van Moolenbroek 		plen -= strlen(pathname);
443*83ee113eSDavid van Moolenbroek 	}
444*83ee113eSDavid van Moolenbroek 	else
445*83ee113eSDavid van Moolenbroek 		pathname[0] = '\0';
446*83ee113eSDavid van Moolenbroek 
447*83ee113eSDavid van Moolenbroek 	if (plen > strlen(filename))
448*83ee113eSDavid van Moolenbroek 		strncpy(&pathname[PATH_MAX - plen], filename, plen-1);
449*83ee113eSDavid van Moolenbroek 	else
450*83ee113eSDavid van Moolenbroek 		return (NULL);
451*83ee113eSDavid van Moolenbroek 
452*83ee113eSDavid van Moolenbroek 	fp = fopen(pathname, mode);
453*83ee113eSDavid van Moolenbroek 	if (perm)
454*83ee113eSDavid van Moolenbroek 		chmod(pathname, perm);
455*83ee113eSDavid van Moolenbroek 	return (fp);
456*83ee113eSDavid van Moolenbroek }
457*83ee113eSDavid van Moolenbroek 
458*83ee113eSDavid van Moolenbroek #if 0
459*83ee113eSDavid van Moolenbroek void
460*83ee113eSDavid van Moolenbroek dst_s_dump(const int mode, const u_char *data, const int size,
461*83ee113eSDavid van Moolenbroek 	    const char *msg)
462*83ee113eSDavid van Moolenbroek {
463*83ee113eSDavid van Moolenbroek 	if (size > 0) {
464*83ee113eSDavid van Moolenbroek #ifdef LONG_TEST
465*83ee113eSDavid van Moolenbroek 		static u_char scratch[1000];
466*83ee113eSDavid van Moolenbroek 		int n ;
467*83ee113eSDavid van Moolenbroek 		n = b64_ntop(data, scratch, size, sizeof(scratch));
468*83ee113eSDavid van Moolenbroek 		printf("%s: %x %d %s\n", msg, mode, n, scratch);
469*83ee113eSDavid van Moolenbroek #else
470*83ee113eSDavid van Moolenbroek 		printf("%s,%x %d\n", msg, mode, size);
471*83ee113eSDavid van Moolenbroek #endif
472*83ee113eSDavid van Moolenbroek 	}
473*83ee113eSDavid van Moolenbroek }
474*83ee113eSDavid van Moolenbroek #endif
475