1*0a6a1f1dSLionel Sambuc /*	$NetBSD: der_put.c,v 1.1.1.2 2014/04/24 12:45:28 pettai Exp $	*/
2ebfedea0SLionel Sambuc 
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc  * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc  * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc  * All rights reserved.
7ebfedea0SLionel Sambuc  *
8ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
9ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
10ebfedea0SLionel Sambuc  * are met:
11ebfedea0SLionel Sambuc  *
12ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
13ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
14ebfedea0SLionel Sambuc  *
15ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
16ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
17ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
18ebfedea0SLionel Sambuc  *
19ebfedea0SLionel Sambuc  * 3. Neither the name of the Institute nor the names of its contributors
20ebfedea0SLionel Sambuc  *    may be used to endorse or promote products derived from this software
21ebfedea0SLionel Sambuc  *    without specific prior written permission.
22ebfedea0SLionel Sambuc  *
23ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ebfedea0SLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ebfedea0SLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ebfedea0SLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ebfedea0SLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ebfedea0SLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ebfedea0SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ebfedea0SLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ebfedea0SLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ebfedea0SLionel Sambuc  * SUCH DAMAGE.
34ebfedea0SLionel Sambuc  */
35ebfedea0SLionel Sambuc 
36ebfedea0SLionel Sambuc #include "der_locl.h"
37ebfedea0SLionel Sambuc 
38*0a6a1f1dSLionel Sambuc __RCSID("NetBSD");
39ebfedea0SLionel Sambuc 
40ebfedea0SLionel Sambuc /*
41ebfedea0SLionel Sambuc  * All encoding functions take a pointer `p' to first position in
42ebfedea0SLionel Sambuc  * which to write, from the right, `len' which means the maximum
43ebfedea0SLionel Sambuc  * number of characters we are able to write.  The function returns
44ebfedea0SLionel Sambuc  * the number of characters written in `size' (if non-NULL).
45ebfedea0SLionel Sambuc  * The return value is 0 or an error.
46ebfedea0SLionel Sambuc  */
47ebfedea0SLionel Sambuc 
48ebfedea0SLionel Sambuc int
der_put_unsigned(unsigned char * p,size_t len,const unsigned * v,size_t * size)49ebfedea0SLionel Sambuc der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size)
50ebfedea0SLionel Sambuc {
51ebfedea0SLionel Sambuc     unsigned char *base = p;
52ebfedea0SLionel Sambuc     unsigned val = *v;
53ebfedea0SLionel Sambuc 
54ebfedea0SLionel Sambuc     if (val) {
55ebfedea0SLionel Sambuc 	while (len > 0 && val) {
56ebfedea0SLionel Sambuc 	    *p-- = val % 256;
57ebfedea0SLionel Sambuc 	    val /= 256;
58ebfedea0SLionel Sambuc 	    --len;
59ebfedea0SLionel Sambuc 	}
60ebfedea0SLionel Sambuc 	if (val != 0)
61ebfedea0SLionel Sambuc 	    return ASN1_OVERFLOW;
62ebfedea0SLionel Sambuc 	else {
63ebfedea0SLionel Sambuc 	    if(p[1] >= 128) {
64ebfedea0SLionel Sambuc 		if(len < 1)
65ebfedea0SLionel Sambuc 		    return ASN1_OVERFLOW;
66ebfedea0SLionel Sambuc 		*p-- = 0;
67ebfedea0SLionel Sambuc 	    }
68ebfedea0SLionel Sambuc 	    *size = base - p;
69ebfedea0SLionel Sambuc 	    return 0;
70ebfedea0SLionel Sambuc 	}
71ebfedea0SLionel Sambuc     } else if (len < 1)
72ebfedea0SLionel Sambuc 	return ASN1_OVERFLOW;
73ebfedea0SLionel Sambuc     else {
74ebfedea0SLionel Sambuc 	*p    = 0;
75ebfedea0SLionel Sambuc 	*size = 1;
76ebfedea0SLionel Sambuc 	return 0;
77ebfedea0SLionel Sambuc     }
78ebfedea0SLionel Sambuc }
79ebfedea0SLionel Sambuc 
80ebfedea0SLionel Sambuc int
der_put_integer(unsigned char * p,size_t len,const int * v,size_t * size)81ebfedea0SLionel Sambuc der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size)
82ebfedea0SLionel Sambuc {
83ebfedea0SLionel Sambuc     unsigned char *base = p;
84ebfedea0SLionel Sambuc     int val = *v;
85ebfedea0SLionel Sambuc 
86ebfedea0SLionel Sambuc     if(val >= 0) {
87ebfedea0SLionel Sambuc 	do {
88ebfedea0SLionel Sambuc 	    if(len < 1)
89ebfedea0SLionel Sambuc 		return ASN1_OVERFLOW;
90ebfedea0SLionel Sambuc 	    *p-- = val % 256;
91ebfedea0SLionel Sambuc 	    len--;
92ebfedea0SLionel Sambuc 	    val /= 256;
93ebfedea0SLionel Sambuc 	} while(val);
94ebfedea0SLionel Sambuc 	if(p[1] >= 128) {
95ebfedea0SLionel Sambuc 	    if(len < 1)
96ebfedea0SLionel Sambuc 		return ASN1_OVERFLOW;
97ebfedea0SLionel Sambuc 	    *p-- = 0;
98ebfedea0SLionel Sambuc 	    len--;
99ebfedea0SLionel Sambuc 	}
100ebfedea0SLionel Sambuc     } else {
101ebfedea0SLionel Sambuc 	val = ~val;
102ebfedea0SLionel Sambuc 	do {
103ebfedea0SLionel Sambuc 	    if(len < 1)
104ebfedea0SLionel Sambuc 		return ASN1_OVERFLOW;
105ebfedea0SLionel Sambuc 	    *p-- = ~(val % 256);
106ebfedea0SLionel Sambuc 	    len--;
107ebfedea0SLionel Sambuc 	    val /= 256;
108ebfedea0SLionel Sambuc 	} while(val);
109ebfedea0SLionel Sambuc 	if(p[1] < 128) {
110ebfedea0SLionel Sambuc 	    if(len < 1)
111ebfedea0SLionel Sambuc 		return ASN1_OVERFLOW;
112ebfedea0SLionel Sambuc 	    *p-- = 0xff;
113ebfedea0SLionel Sambuc 	    len--;
114ebfedea0SLionel Sambuc 	}
115ebfedea0SLionel Sambuc     }
116ebfedea0SLionel Sambuc     *size = base - p;
117ebfedea0SLionel Sambuc     return 0;
118ebfedea0SLionel Sambuc }
119ebfedea0SLionel Sambuc 
120ebfedea0SLionel Sambuc 
121ebfedea0SLionel Sambuc int
der_put_length(unsigned char * p,size_t len,size_t val,size_t * size)122ebfedea0SLionel Sambuc der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
123ebfedea0SLionel Sambuc {
124ebfedea0SLionel Sambuc     if (len < 1)
125ebfedea0SLionel Sambuc 	return ASN1_OVERFLOW;
126ebfedea0SLionel Sambuc 
127ebfedea0SLionel Sambuc     if (val < 128) {
128ebfedea0SLionel Sambuc 	*p = val;
129ebfedea0SLionel Sambuc 	*size = 1;
130ebfedea0SLionel Sambuc     } else {
131ebfedea0SLionel Sambuc 	size_t l = 0;
132ebfedea0SLionel Sambuc 
133ebfedea0SLionel Sambuc 	while(val > 0) {
134ebfedea0SLionel Sambuc 	    if(len < 2)
135ebfedea0SLionel Sambuc 		return ASN1_OVERFLOW;
136ebfedea0SLionel Sambuc 	    *p-- = val % 256;
137ebfedea0SLionel Sambuc 	    val /= 256;
138ebfedea0SLionel Sambuc 	    len--;
139ebfedea0SLionel Sambuc 	    l++;
140ebfedea0SLionel Sambuc 	}
141ebfedea0SLionel Sambuc 	*p = 0x80 | l;
142ebfedea0SLionel Sambuc 	if(size)
143ebfedea0SLionel Sambuc 	    *size = l + 1;
144ebfedea0SLionel Sambuc     }
145ebfedea0SLionel Sambuc     return 0;
146ebfedea0SLionel Sambuc }
147ebfedea0SLionel Sambuc 
148ebfedea0SLionel Sambuc int
der_put_boolean(unsigned char * p,size_t len,const int * data,size_t * size)149ebfedea0SLionel Sambuc der_put_boolean(unsigned char *p, size_t len, const int *data, size_t *size)
150ebfedea0SLionel Sambuc {
151ebfedea0SLionel Sambuc     if(len < 1)
152ebfedea0SLionel Sambuc 	return ASN1_OVERFLOW;
153ebfedea0SLionel Sambuc     if(*data != 0)
154ebfedea0SLionel Sambuc 	*p = 0xff;
155ebfedea0SLionel Sambuc     else
156ebfedea0SLionel Sambuc 	*p = 0;
157ebfedea0SLionel Sambuc     *size = 1;
158ebfedea0SLionel Sambuc     return 0;
159ebfedea0SLionel Sambuc }
160ebfedea0SLionel Sambuc 
161ebfedea0SLionel Sambuc int
der_put_general_string(unsigned char * p,size_t len,const heim_general_string * str,size_t * size)162ebfedea0SLionel Sambuc der_put_general_string (unsigned char *p, size_t len,
163ebfedea0SLionel Sambuc 			const heim_general_string *str, size_t *size)
164ebfedea0SLionel Sambuc {
165ebfedea0SLionel Sambuc     size_t slen = strlen(*str);
166ebfedea0SLionel Sambuc 
167ebfedea0SLionel Sambuc     if (len < slen)
168ebfedea0SLionel Sambuc 	return ASN1_OVERFLOW;
169ebfedea0SLionel Sambuc     p -= slen;
170ebfedea0SLionel Sambuc     memcpy (p+1, *str, slen);
171ebfedea0SLionel Sambuc     *size = slen;
172ebfedea0SLionel Sambuc     return 0;
173ebfedea0SLionel Sambuc }
174ebfedea0SLionel Sambuc 
175ebfedea0SLionel Sambuc int
der_put_utf8string(unsigned char * p,size_t len,const heim_utf8_string * str,size_t * size)176ebfedea0SLionel Sambuc der_put_utf8string (unsigned char *p, size_t len,
177ebfedea0SLionel Sambuc 		    const heim_utf8_string *str, size_t *size)
178ebfedea0SLionel Sambuc {
179ebfedea0SLionel Sambuc     return der_put_general_string(p, len, str, size);
180ebfedea0SLionel Sambuc }
181ebfedea0SLionel Sambuc 
182ebfedea0SLionel Sambuc int
der_put_printable_string(unsigned char * p,size_t len,const heim_printable_string * str,size_t * size)183ebfedea0SLionel Sambuc der_put_printable_string (unsigned char *p, size_t len,
184ebfedea0SLionel Sambuc 			  const heim_printable_string *str, size_t *size)
185ebfedea0SLionel Sambuc {
186ebfedea0SLionel Sambuc     return der_put_octet_string(p, len, str, size);
187ebfedea0SLionel Sambuc }
188ebfedea0SLionel Sambuc 
189ebfedea0SLionel Sambuc int
der_put_ia5_string(unsigned char * p,size_t len,const heim_ia5_string * str,size_t * size)190ebfedea0SLionel Sambuc der_put_ia5_string (unsigned char *p, size_t len,
191ebfedea0SLionel Sambuc 		    const heim_ia5_string *str, size_t *size)
192ebfedea0SLionel Sambuc {
193ebfedea0SLionel Sambuc     return der_put_octet_string(p, len, str, size);
194ebfedea0SLionel Sambuc }
195ebfedea0SLionel Sambuc 
196ebfedea0SLionel Sambuc int
der_put_bmp_string(unsigned char * p,size_t len,const heim_bmp_string * data,size_t * size)197ebfedea0SLionel Sambuc der_put_bmp_string (unsigned char *p, size_t len,
198ebfedea0SLionel Sambuc 		    const heim_bmp_string *data, size_t *size)
199ebfedea0SLionel Sambuc {
200ebfedea0SLionel Sambuc     size_t i;
201ebfedea0SLionel Sambuc     if (len / 2 < data->length)
202ebfedea0SLionel Sambuc 	return ASN1_OVERFLOW;
203ebfedea0SLionel Sambuc     p -= data->length * 2;
204ebfedea0SLionel Sambuc     for (i = 0; i < data->length; i++) {
205ebfedea0SLionel Sambuc 	p[1] = (data->data[i] >> 8) & 0xff;
206ebfedea0SLionel Sambuc 	p[2] = data->data[i] & 0xff;
207ebfedea0SLionel Sambuc 	p += 2;
208ebfedea0SLionel Sambuc     }
209ebfedea0SLionel Sambuc     if (size) *size = data->length * 2;
210ebfedea0SLionel Sambuc     return 0;
211ebfedea0SLionel Sambuc }
212ebfedea0SLionel Sambuc 
213ebfedea0SLionel Sambuc int
der_put_universal_string(unsigned char * p,size_t len,const heim_universal_string * data,size_t * size)214ebfedea0SLionel Sambuc der_put_universal_string (unsigned char *p, size_t len,
215ebfedea0SLionel Sambuc 			  const heim_universal_string *data, size_t *size)
216ebfedea0SLionel Sambuc {
217ebfedea0SLionel Sambuc     size_t i;
218ebfedea0SLionel Sambuc     if (len / 4 < data->length)
219ebfedea0SLionel Sambuc 	return ASN1_OVERFLOW;
220ebfedea0SLionel Sambuc     p -= data->length * 4;
221ebfedea0SLionel Sambuc     for (i = 0; i < data->length; i++) {
222ebfedea0SLionel Sambuc 	p[1] = (data->data[i] >> 24) & 0xff;
223ebfedea0SLionel Sambuc 	p[2] = (data->data[i] >> 16) & 0xff;
224ebfedea0SLionel Sambuc 	p[3] = (data->data[i] >> 8) & 0xff;
225ebfedea0SLionel Sambuc 	p[4] = data->data[i] & 0xff;
226ebfedea0SLionel Sambuc 	p += 4;
227ebfedea0SLionel Sambuc     }
228ebfedea0SLionel Sambuc     if (size) *size = data->length * 4;
229ebfedea0SLionel Sambuc     return 0;
230ebfedea0SLionel Sambuc }
231ebfedea0SLionel Sambuc 
232ebfedea0SLionel Sambuc int
der_put_visible_string(unsigned char * p,size_t len,const heim_visible_string * str,size_t * size)233ebfedea0SLionel Sambuc der_put_visible_string (unsigned char *p, size_t len,
234ebfedea0SLionel Sambuc 			 const heim_visible_string *str, size_t *size)
235ebfedea0SLionel Sambuc {
236ebfedea0SLionel Sambuc     return der_put_general_string(p, len, str, size);
237ebfedea0SLionel Sambuc }
238ebfedea0SLionel Sambuc 
239ebfedea0SLionel Sambuc int
der_put_octet_string(unsigned char * p,size_t len,const heim_octet_string * data,size_t * size)240ebfedea0SLionel Sambuc der_put_octet_string (unsigned char *p, size_t len,
241ebfedea0SLionel Sambuc 		      const heim_octet_string *data, size_t *size)
242ebfedea0SLionel Sambuc {
243ebfedea0SLionel Sambuc     if (len < data->length)
244ebfedea0SLionel Sambuc 	return ASN1_OVERFLOW;
245ebfedea0SLionel Sambuc     p -= data->length;
246ebfedea0SLionel Sambuc     memcpy (p+1, data->data, data->length);
247ebfedea0SLionel Sambuc     *size = data->length;
248ebfedea0SLionel Sambuc     return 0;
249ebfedea0SLionel Sambuc }
250ebfedea0SLionel Sambuc 
251ebfedea0SLionel Sambuc int
der_put_heim_integer(unsigned char * p,size_t len,const heim_integer * data,size_t * size)252ebfedea0SLionel Sambuc der_put_heim_integer (unsigned char *p, size_t len,
253ebfedea0SLionel Sambuc 		     const heim_integer *data, size_t *size)
254ebfedea0SLionel Sambuc {
255ebfedea0SLionel Sambuc     unsigned char *buf = data->data;
256ebfedea0SLionel Sambuc     int hibitset = 0;
257ebfedea0SLionel Sambuc 
258ebfedea0SLionel Sambuc     if (data->length == 0) {
259ebfedea0SLionel Sambuc 	if (len < 1)
260ebfedea0SLionel Sambuc 	    return ASN1_OVERFLOW;
261ebfedea0SLionel Sambuc 	*p-- = 0;
262ebfedea0SLionel Sambuc 	if (size)
263ebfedea0SLionel Sambuc 	    *size = 1;
264ebfedea0SLionel Sambuc 	return 0;
265ebfedea0SLionel Sambuc     }
266ebfedea0SLionel Sambuc     if (len < data->length)
267ebfedea0SLionel Sambuc 	return ASN1_OVERFLOW;
268ebfedea0SLionel Sambuc 
269ebfedea0SLionel Sambuc     len -= data->length;
270ebfedea0SLionel Sambuc 
271ebfedea0SLionel Sambuc     if (data->negative) {
272ebfedea0SLionel Sambuc 	int i, carry;
273ebfedea0SLionel Sambuc 	for (i = data->length - 1, carry = 1; i >= 0; i--) {
274ebfedea0SLionel Sambuc 	    *p = buf[i] ^ 0xff;
275ebfedea0SLionel Sambuc 	    if (carry)
276ebfedea0SLionel Sambuc 		carry = !++*p;
277ebfedea0SLionel Sambuc 	    p--;
278ebfedea0SLionel Sambuc 	}
279ebfedea0SLionel Sambuc 	if (p[1] < 128) {
280ebfedea0SLionel Sambuc 	    if (len < 1)
281ebfedea0SLionel Sambuc 		return ASN1_OVERFLOW;
282ebfedea0SLionel Sambuc 	    *p-- = 0xff;
283ebfedea0SLionel Sambuc 	    len--;
284ebfedea0SLionel Sambuc 	    hibitset = 1;
285ebfedea0SLionel Sambuc 	}
286ebfedea0SLionel Sambuc     } else {
287ebfedea0SLionel Sambuc 	p -= data->length;
288ebfedea0SLionel Sambuc 	memcpy(p + 1, buf, data->length);
289ebfedea0SLionel Sambuc 
290ebfedea0SLionel Sambuc 	if (p[1] >= 128) {
291ebfedea0SLionel Sambuc 	    if (len < 1)
292ebfedea0SLionel Sambuc 		return ASN1_OVERFLOW;
293ebfedea0SLionel Sambuc 	    p[0] = 0;
294ebfedea0SLionel Sambuc 	    len--;
295ebfedea0SLionel Sambuc 	    hibitset = 1;
296ebfedea0SLionel Sambuc 	}
297ebfedea0SLionel Sambuc     }
298ebfedea0SLionel Sambuc     if (size)
299ebfedea0SLionel Sambuc 	*size = data->length + hibitset;
300ebfedea0SLionel Sambuc     return 0;
301ebfedea0SLionel Sambuc }
302ebfedea0SLionel Sambuc 
303ebfedea0SLionel Sambuc int
der_put_generalized_time(unsigned char * p,size_t len,const time_t * data,size_t * size)304ebfedea0SLionel Sambuc der_put_generalized_time (unsigned char *p, size_t len,
305ebfedea0SLionel Sambuc 			  const time_t *data, size_t *size)
306ebfedea0SLionel Sambuc {
307ebfedea0SLionel Sambuc     heim_octet_string k;
308ebfedea0SLionel Sambuc     size_t l;
309ebfedea0SLionel Sambuc     int e;
310ebfedea0SLionel Sambuc 
311ebfedea0SLionel Sambuc     e = _heim_time2generalizedtime (*data, &k, 1);
312ebfedea0SLionel Sambuc     if (e)
313ebfedea0SLionel Sambuc 	return e;
314ebfedea0SLionel Sambuc     e = der_put_octet_string(p, len, &k, &l);
315ebfedea0SLionel Sambuc     free(k.data);
316ebfedea0SLionel Sambuc     if(e)
317ebfedea0SLionel Sambuc 	return e;
318ebfedea0SLionel Sambuc     if(size)
319ebfedea0SLionel Sambuc 	*size = l;
320ebfedea0SLionel Sambuc     return 0;
321ebfedea0SLionel Sambuc }
322ebfedea0SLionel Sambuc 
323ebfedea0SLionel Sambuc int
der_put_utctime(unsigned char * p,size_t len,const time_t * data,size_t * size)324ebfedea0SLionel Sambuc der_put_utctime (unsigned char *p, size_t len,
325ebfedea0SLionel Sambuc 		 const time_t *data, size_t *size)
326ebfedea0SLionel Sambuc {
327ebfedea0SLionel Sambuc     heim_octet_string k;
328ebfedea0SLionel Sambuc     size_t l;
329ebfedea0SLionel Sambuc     int e;
330ebfedea0SLionel Sambuc 
331ebfedea0SLionel Sambuc     e = _heim_time2generalizedtime (*data, &k, 0);
332ebfedea0SLionel Sambuc     if (e)
333ebfedea0SLionel Sambuc 	return e;
334ebfedea0SLionel Sambuc     e = der_put_octet_string(p, len, &k, &l);
335ebfedea0SLionel Sambuc     free(k.data);
336ebfedea0SLionel Sambuc     if(e)
337ebfedea0SLionel Sambuc 	return e;
338ebfedea0SLionel Sambuc     if(size)
339ebfedea0SLionel Sambuc 	*size = l;
340ebfedea0SLionel Sambuc     return 0;
341ebfedea0SLionel Sambuc }
342ebfedea0SLionel Sambuc 
343ebfedea0SLionel Sambuc int
der_put_oid(unsigned char * p,size_t len,const heim_oid * data,size_t * size)344ebfedea0SLionel Sambuc der_put_oid (unsigned char *p, size_t len,
345ebfedea0SLionel Sambuc 	     const heim_oid *data, size_t *size)
346ebfedea0SLionel Sambuc {
347ebfedea0SLionel Sambuc     unsigned char *base = p;
348ebfedea0SLionel Sambuc     int n;
349ebfedea0SLionel Sambuc 
350ebfedea0SLionel Sambuc     for (n = data->length - 1; n >= 2; --n) {
351ebfedea0SLionel Sambuc 	unsigned u = data->components[n];
352ebfedea0SLionel Sambuc 
353ebfedea0SLionel Sambuc 	if (len < 1)
354ebfedea0SLionel Sambuc 	    return ASN1_OVERFLOW;
355ebfedea0SLionel Sambuc 	*p-- = u % 128;
356ebfedea0SLionel Sambuc 	u /= 128;
357ebfedea0SLionel Sambuc 	--len;
358ebfedea0SLionel Sambuc 	while (u > 0) {
359ebfedea0SLionel Sambuc 	    if (len < 1)
360ebfedea0SLionel Sambuc 		return ASN1_OVERFLOW;
361ebfedea0SLionel Sambuc 	    *p-- = 128 + u % 128;
362ebfedea0SLionel Sambuc 	    u /= 128;
363ebfedea0SLionel Sambuc 	    --len;
364ebfedea0SLionel Sambuc 	}
365ebfedea0SLionel Sambuc     }
366ebfedea0SLionel Sambuc     if (len < 1)
367ebfedea0SLionel Sambuc 	return ASN1_OVERFLOW;
368ebfedea0SLionel Sambuc     *p-- = 40 * data->components[0] + data->components[1];
369ebfedea0SLionel Sambuc     *size = base - p;
370ebfedea0SLionel Sambuc     return 0;
371ebfedea0SLionel Sambuc }
372ebfedea0SLionel Sambuc 
373ebfedea0SLionel Sambuc int
der_put_tag(unsigned char * p,size_t len,Der_class class,Der_type type,unsigned int tag,size_t * size)374ebfedea0SLionel Sambuc der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
375ebfedea0SLionel Sambuc 	     unsigned int tag, size_t *size)
376ebfedea0SLionel Sambuc {
377ebfedea0SLionel Sambuc     if (tag <= 30) {
378ebfedea0SLionel Sambuc 	if (len < 1)
379ebfedea0SLionel Sambuc 	    return ASN1_OVERFLOW;
380ebfedea0SLionel Sambuc 	*p = MAKE_TAG(class, type, tag);
381ebfedea0SLionel Sambuc 	*size = 1;
382ebfedea0SLionel Sambuc     } else {
383ebfedea0SLionel Sambuc 	size_t ret = 0;
384ebfedea0SLionel Sambuc 	unsigned int continuation = 0;
385ebfedea0SLionel Sambuc 
386ebfedea0SLionel Sambuc 	do {
387ebfedea0SLionel Sambuc 	    if (len < 1)
388ebfedea0SLionel Sambuc 		return ASN1_OVERFLOW;
389ebfedea0SLionel Sambuc 	    *p-- = tag % 128 | continuation;
390ebfedea0SLionel Sambuc 	    len--;
391ebfedea0SLionel Sambuc 	    ret++;
392ebfedea0SLionel Sambuc 	    tag /= 128;
393ebfedea0SLionel Sambuc 	    continuation = 0x80;
394ebfedea0SLionel Sambuc 	} while(tag > 0);
395ebfedea0SLionel Sambuc 	if (len < 1)
396ebfedea0SLionel Sambuc 	    return ASN1_OVERFLOW;
397ebfedea0SLionel Sambuc 	*p-- = MAKE_TAG(class, type, 0x1f);
398ebfedea0SLionel Sambuc 	ret++;
399ebfedea0SLionel Sambuc 	*size = ret;
400ebfedea0SLionel Sambuc     }
401ebfedea0SLionel Sambuc     return 0;
402ebfedea0SLionel Sambuc }
403ebfedea0SLionel Sambuc 
404ebfedea0SLionel Sambuc int
der_put_length_and_tag(unsigned char * p,size_t len,size_t len_val,Der_class class,Der_type type,unsigned int tag,size_t * size)405ebfedea0SLionel Sambuc der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
406ebfedea0SLionel Sambuc 			Der_class class, Der_type type,
407ebfedea0SLionel Sambuc 			unsigned int tag, size_t *size)
408ebfedea0SLionel Sambuc {
409ebfedea0SLionel Sambuc     size_t ret = 0;
410ebfedea0SLionel Sambuc     size_t l;
411ebfedea0SLionel Sambuc     int e;
412ebfedea0SLionel Sambuc 
413ebfedea0SLionel Sambuc     e = der_put_length (p, len, len_val, &l);
414ebfedea0SLionel Sambuc     if(e)
415ebfedea0SLionel Sambuc 	return e;
416ebfedea0SLionel Sambuc     p -= l;
417ebfedea0SLionel Sambuc     len -= l;
418ebfedea0SLionel Sambuc     ret += l;
419ebfedea0SLionel Sambuc     e = der_put_tag (p, len, class, type, tag, &l);
420ebfedea0SLionel Sambuc     if(e)
421ebfedea0SLionel Sambuc 	return e;
422ebfedea0SLionel Sambuc 
423ebfedea0SLionel Sambuc     ret += l;
424ebfedea0SLionel Sambuc     *size = ret;
425ebfedea0SLionel Sambuc     return 0;
426ebfedea0SLionel Sambuc }
427ebfedea0SLionel Sambuc 
428ebfedea0SLionel Sambuc int
_heim_time2generalizedtime(time_t t,heim_octet_string * s,int gtimep)429ebfedea0SLionel Sambuc _heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
430ebfedea0SLionel Sambuc {
431ebfedea0SLionel Sambuc      struct tm tm;
432ebfedea0SLionel Sambuc      const size_t len = gtimep ? 15 : 13;
433ebfedea0SLionel Sambuc 
434ebfedea0SLionel Sambuc      s->data = malloc(len + 1);
435ebfedea0SLionel Sambuc      if (s->data == NULL)
436ebfedea0SLionel Sambuc 	 return ENOMEM;
437ebfedea0SLionel Sambuc      s->length = len;
438*0a6a1f1dSLionel Sambuc      if (_der_gmtime(t, &tm) == NULL)
439*0a6a1f1dSLionel Sambuc 	 return ASN1_BAD_TIMEFORMAT;
440ebfedea0SLionel Sambuc      if (gtimep)
441ebfedea0SLionel Sambuc 	 snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
442ebfedea0SLionel Sambuc 		   tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
443ebfedea0SLionel Sambuc 		   tm.tm_hour, tm.tm_min, tm.tm_sec);
444ebfedea0SLionel Sambuc      else
445ebfedea0SLionel Sambuc 	 snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
446ebfedea0SLionel Sambuc 		   tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
447ebfedea0SLionel Sambuc 		   tm.tm_hour, tm.tm_min, tm.tm_sec);
448ebfedea0SLionel Sambuc 
449ebfedea0SLionel Sambuc      return 0;
450ebfedea0SLionel Sambuc }
451ebfedea0SLionel Sambuc 
452ebfedea0SLionel Sambuc int
der_put_bit_string(unsigned char * p,size_t len,const heim_bit_string * data,size_t * size)453ebfedea0SLionel Sambuc der_put_bit_string (unsigned char *p, size_t len,
454ebfedea0SLionel Sambuc 		    const heim_bit_string *data, size_t *size)
455ebfedea0SLionel Sambuc {
456ebfedea0SLionel Sambuc     size_t data_size = (data->length + 7) / 8;
457ebfedea0SLionel Sambuc     if (len < data_size + 1)
458ebfedea0SLionel Sambuc 	return ASN1_OVERFLOW;
459ebfedea0SLionel Sambuc     p -= data_size + 1;
460ebfedea0SLionel Sambuc 
461ebfedea0SLionel Sambuc     memcpy (p+2, data->data, data_size);
462ebfedea0SLionel Sambuc     if (data->length && (data->length % 8) != 0)
463ebfedea0SLionel Sambuc 	p[1] = 8 - (data->length % 8);
464ebfedea0SLionel Sambuc     else
465ebfedea0SLionel Sambuc 	p[1] = 0;
466ebfedea0SLionel Sambuc     *size = data_size + 1;
467ebfedea0SLionel Sambuc     return 0;
468ebfedea0SLionel Sambuc }
469ebfedea0SLionel Sambuc 
470ebfedea0SLionel Sambuc int
_heim_der_set_sort(const void * a1,const void * a2)471ebfedea0SLionel Sambuc _heim_der_set_sort(const void *a1, const void *a2)
472ebfedea0SLionel Sambuc {
473ebfedea0SLionel Sambuc     const struct heim_octet_string *s1 = a1, *s2 = a2;
474ebfedea0SLionel Sambuc     int ret;
475ebfedea0SLionel Sambuc 
476ebfedea0SLionel Sambuc     ret = memcmp(s1->data, s2->data,
477ebfedea0SLionel Sambuc 		 s1->length < s2->length ? s1->length : s2->length);
478ebfedea0SLionel Sambuc     if(ret)
479ebfedea0SLionel Sambuc 	return ret;
480ebfedea0SLionel Sambuc     return s1->length - s2->length;
481ebfedea0SLionel Sambuc }
482