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