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