Line data Source code
1 : /*
2 : * Copyright (c) 1997 - 2007 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 : /*
37 : * All decoding functions take a pointer `p' to first position in
38 : * which to read, from the left, `len' which means the maximum number
39 : * of characters we are able to read, `ret' were the value will be
40 : * returned and `size' where the number of used bytes is stored.
41 : * Either 0 or an error code is returned.
42 : */
43 :
44 : int ASN1CALL
45 5245777 : der_get_unsigned (const unsigned char *p, size_t len,
46 : unsigned *ret, size_t *size)
47 : {
48 5245777 : unsigned val = 0;
49 5245777 : size_t oldlen = len;
50 :
51 5245777 : if (len == sizeof(val) + 1 && p[0] == 0)
52 : ;
53 5229092 : else if (len > sizeof(val))
54 0 : return ASN1_OVERRUN;
55 :
56 19733413 : while (len--)
57 9241859 : val = val * 256 + *p++;
58 5245777 : *ret = val;
59 5245777 : if(size) *size = oldlen;
60 5245777 : return 0;
61 : }
62 :
63 : int ASN1CALL
64 0 : der_get_unsigned64 (const unsigned char *p, size_t len,
65 : uint64_t *ret, size_t *size)
66 : {
67 0 : uint64_t val = 0;
68 0 : size_t oldlen = len;
69 :
70 0 : if (len == sizeof(val) + 1 && p[0] == 0)
71 : ;
72 0 : else if (len > sizeof(val))
73 0 : return ASN1_OVERRUN;
74 :
75 0 : while (len--)
76 0 : val = val * 256 + *p++;
77 0 : *ret = val;
78 0 : if(size) *size = oldlen;
79 0 : return 0;
80 : }
81 :
82 : int ASN1CALL
83 4184027 : der_get_integer (const unsigned char *p, size_t len,
84 : int *ret, size_t *size)
85 : {
86 4184027 : int val = 0;
87 4184027 : size_t oldlen = len;
88 :
89 4184027 : if (len > sizeof(val))
90 0 : return ASN1_OVERRUN;
91 :
92 4184027 : if (len > 0) {
93 4184027 : val = (signed char)*p++;
94 9582965 : while (--len)
95 1214911 : val = val * 256 + *p++;
96 : }
97 4184027 : *ret = val;
98 4184027 : if(size) *size = oldlen;
99 4184027 : return 0;
100 : }
101 :
102 : int ASN1CALL
103 0 : der_get_integer64 (const unsigned char *p, size_t len,
104 : int64_t *ret, size_t *size)
105 : {
106 0 : int64_t val = 0;
107 0 : size_t oldlen = len;
108 :
109 0 : if (len > sizeof(val))
110 0 : return ASN1_OVERRUN;
111 :
112 0 : if (len > 0) {
113 0 : val = (signed char)*p++;
114 0 : while (--len)
115 0 : val = val * 256 + *p++;
116 : }
117 0 : *ret = val;
118 0 : if(size) *size = oldlen;
119 0 : return 0;
120 : }
121 :
122 :
123 : int ASN1CALL
124 23870769 : der_get_length (const unsigned char *p, size_t len,
125 : size_t *val, size_t *size)
126 : {
127 : size_t v;
128 :
129 23870769 : if (len <= 0)
130 0 : return ASN1_OVERRUN;
131 23870769 : --len;
132 23870769 : v = *p++;
133 23870769 : if (v < 128) {
134 18698234 : *val = v;
135 18698234 : if(size) *size = 1;
136 : } else {
137 : int e;
138 : size_t l;
139 : unsigned tmp;
140 :
141 5172535 : if(v == 0x80){
142 0 : *val = ASN1_INDEFINITE;
143 0 : if(size) *size = 1;
144 0 : return 0;
145 : }
146 5172535 : v &= 0x7F;
147 5172535 : if (len < v)
148 0 : return ASN1_OVERRUN;
149 5172535 : e = der_get_unsigned (p, v, &tmp, &l);
150 5172535 : if(e) return e;
151 5172535 : *val = tmp;
152 5172535 : if(size) *size = l + 1;
153 : }
154 23870769 : return 0;
155 : }
156 :
157 : int ASN1CALL
158 619 : der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
159 : {
160 619 : if(len < 1)
161 0 : return ASN1_OVERRUN;
162 619 : if(*p != 0)
163 619 : *data = 1;
164 : else
165 0 : *data = 0;
166 619 : *size = 1;
167 619 : return 0;
168 : }
169 :
170 : int ASN1CALL
171 1747715 : der_get_general_string (const unsigned char *p, size_t len,
172 : heim_general_string *str, size_t *size)
173 : {
174 : const unsigned char *p1;
175 : char *s;
176 :
177 1747715 : assert(p != NULL);
178 :
179 1747715 : if (size)
180 1747715 : *size = 0;
181 :
182 1747715 : p1 = memchr(p, 0, len);
183 1747715 : if (p1 != NULL) {
184 : /*
185 : * Allow trailing NULs. We allow this since MIT Kerberos sends
186 : * an strings in the NEED_PREAUTH case that includes a
187 : * trailing NUL.
188 : */
189 0 : while ((size_t)(p1 - p) < len && *p1 == '\0')
190 0 : p1++;
191 0 : if ((size_t)(p1 - p) != len) {
192 0 : *str = NULL;
193 0 : return ASN1_BAD_CHARACTER;
194 : }
195 : }
196 1747715 : if (len == SIZE_MAX) {
197 0 : *str = NULL;
198 0 : return ASN1_BAD_LENGTH;
199 : }
200 :
201 1747715 : *str = s = malloc (len + 1);
202 1747715 : if (s == NULL)
203 0 : return ENOMEM;
204 1747715 : memcpy (s, p, len);
205 1747715 : s[len] = '\0';
206 :
207 1747715 : if(size) *size = len;
208 1747715 : return 0;
209 : }
210 :
211 : int ASN1CALL
212 963 : der_get_utf8string (const unsigned char *p, size_t len,
213 : heim_utf8_string *str, size_t *size)
214 : {
215 963 : return der_get_general_string(p, len, str, size);
216 : }
217 :
218 : #define gen_data_zero(_data) \
219 : do { (_data)->length = 0; (_data)->data = NULL; } while(0)
220 :
221 : int ASN1CALL
222 1006 : der_get_printable_string(const unsigned char *p, size_t len,
223 : heim_printable_string *str, size_t *size)
224 : {
225 1006 : assert(p != NULL);
226 :
227 1006 : if (size)
228 1006 : *size = 0;
229 :
230 1006 : if (len == SIZE_MAX) {
231 0 : gen_data_zero(str);
232 0 : return ASN1_BAD_LENGTH;
233 : }
234 1006 : str->length = len;
235 1006 : str->data = malloc(len + 1);
236 1006 : if (str->data == NULL) {
237 0 : gen_data_zero(str);
238 0 : return ENOMEM;
239 : }
240 :
241 1006 : memcpy(str->data, p, len);
242 1006 : ((char *)str->data)[len] = '\0';
243 1006 : if(size) *size = len;
244 1006 : return 0;
245 : }
246 :
247 : int ASN1CALL
248 500 : der_get_ia5_string(const unsigned char *p, size_t len,
249 : heim_ia5_string *str, size_t *size)
250 : {
251 500 : return der_get_printable_string(p, len, str, size);
252 : }
253 :
254 : int ASN1CALL
255 0 : der_get_bmp_string (const unsigned char *p, size_t len,
256 : heim_bmp_string *data, size_t *size)
257 : {
258 : size_t i;
259 :
260 0 : assert(p != NULL);
261 :
262 0 : if (size)
263 0 : *size = 0;
264 :
265 0 : if (len & 1) {
266 0 : gen_data_zero(data);
267 0 : return ASN1_BAD_FORMAT;
268 : }
269 0 : data->length = len / 2;
270 0 : if (data->length > UINT_MAX/sizeof(data->data[0])) {
271 0 : gen_data_zero(data);
272 0 : return ERANGE;
273 : }
274 0 : data->data = malloc(data->length * sizeof(data->data[0]));
275 0 : if (data->data == NULL && data->length != 0) {
276 0 : gen_data_zero(data);
277 0 : return ENOMEM;
278 : }
279 :
280 0 : for (i = 0; i < data->length; i++) {
281 0 : data->data[i] = (p[0] << 8) | p[1];
282 0 : p += 2;
283 : /* check for NUL in the middle of the string */
284 0 : if (data->data[i] == 0 && i != (data->length - 1)) {
285 0 : free(data->data);
286 0 : gen_data_zero(data);
287 0 : return ASN1_BAD_CHARACTER;
288 : }
289 : }
290 0 : if (size) *size = len;
291 :
292 0 : return 0;
293 : }
294 :
295 : int ASN1CALL
296 0 : der_get_universal_string (const unsigned char *p, size_t len,
297 : heim_universal_string *data, size_t *size)
298 : {
299 : size_t i;
300 :
301 0 : assert(p != NULL);
302 :
303 0 : if (size)
304 0 : *size = 0;
305 :
306 0 : if (len & 3) {
307 0 : gen_data_zero(data);
308 0 : return ASN1_BAD_FORMAT;
309 : }
310 0 : data->length = len / 4;
311 0 : if (data->length > UINT_MAX/sizeof(data->data[0])) {
312 0 : gen_data_zero(data);
313 0 : return ERANGE;
314 : }
315 0 : data->data = malloc(data->length * sizeof(data->data[0]));
316 0 : if (data->data == NULL && data->length != 0) {
317 0 : gen_data_zero(data);
318 0 : return ENOMEM;
319 : }
320 :
321 0 : for (i = 0; i < data->length; i++) {
322 0 : data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
323 0 : p += 4;
324 : /* check for NUL in the middle of the string */
325 0 : if (data->data[i] == 0 && i != (data->length - 1)) {
326 0 : free(data->data);
327 0 : gen_data_zero(data);
328 0 : return ASN1_BAD_CHARACTER;
329 : }
330 : }
331 0 : if (size) *size = len;
332 0 : return 0;
333 : }
334 :
335 : int ASN1CALL
336 0 : der_get_visible_string (const unsigned char *p, size_t len,
337 : heim_visible_string *str, size_t *size)
338 : {
339 0 : return der_get_general_string(p, len, str, size);
340 : }
341 :
342 : int ASN1CALL
343 1535371 : der_get_octet_string (const unsigned char *p, size_t len,
344 : heim_octet_string *data, size_t *size)
345 : {
346 1535371 : assert(p != NULL);
347 :
348 1535371 : if (size)
349 1535371 : *size = 0;
350 :
351 1535371 : if (len == 0)
352 188249 : data->data = malloc(1);
353 : else
354 1347122 : data->data = malloc(len);
355 1535371 : if (data->data == NULL) {
356 0 : data->length = 0;
357 0 : return ENOMEM;
358 : }
359 1535371 : data->length = len;
360 1535371 : memcpy (data->data, p, len);
361 1535371 : if (size)
362 1535371 : *size = len;
363 1535371 : return 0;
364 : }
365 :
366 : int ASN1CALL
367 0 : der_get_octet_string_ber (const unsigned char *p, size_t len,
368 : heim_octet_string *data, size_t *size)
369 : {
370 : int e;
371 : Der_type type;
372 : Der_class cls;
373 0 : unsigned int tag, depth = 0;
374 0 : size_t l, datalen, oldlen = len;
375 :
376 0 : assert(p != NULL);
377 :
378 0 : if (size)
379 0 : *size = 0;
380 :
381 0 : data->length = 0;
382 0 : data->data = NULL;
383 :
384 0 : while (len) {
385 0 : e = der_get_tag (p, len, &cls, &type, &tag, &l);
386 0 : if (e) goto out;
387 0 : if (cls != ASN1_C_UNIV) {
388 0 : e = ASN1_BAD_ID;
389 0 : goto out;
390 : }
391 0 : if (type == PRIM && tag == UT_EndOfContent) {
392 0 : if (depth == 0)
393 0 : break;
394 0 : depth--;
395 : }
396 0 : if (tag != UT_OctetString) {
397 0 : e = ASN1_BAD_ID;
398 0 : goto out;
399 : }
400 :
401 0 : p += l;
402 0 : len -= l;
403 0 : e = der_get_length (p, len, &datalen, &l);
404 0 : if (e) goto out;
405 0 : p += l;
406 0 : len -= l;
407 :
408 0 : if (datalen > len)
409 0 : return ASN1_OVERRUN;
410 :
411 0 : if (type == PRIM && datalen) {
412 : void *ptr;
413 :
414 0 : ptr = realloc(data->data, data->length + datalen);
415 0 : if (ptr == NULL) {
416 0 : e = ENOMEM;
417 0 : goto out;
418 : }
419 0 : data->data = ptr;
420 0 : memcpy(((unsigned char *)data->data) + data->length, p, datalen);
421 0 : data->length += datalen;
422 0 : } else if (type != PRIM)
423 0 : depth++;
424 :
425 0 : p += datalen;
426 0 : len -= datalen;
427 : }
428 0 : if (depth != 0)
429 0 : return ASN1_INDEF_OVERRUN;
430 0 : if(size) *size = oldlen - len;
431 0 : return 0;
432 0 : out:
433 0 : free(data->data);
434 0 : data->data = NULL;
435 0 : data->length = 0;
436 0 : return e;
437 : }
438 :
439 :
440 : int ASN1CALL
441 531 : der_get_heim_integer (const unsigned char *p, size_t len,
442 : heim_integer *data, size_t *size)
443 : {
444 531 : data->length = 0;
445 531 : data->negative = 0;
446 531 : data->data = NULL;
447 :
448 531 : if (size)
449 531 : *size = 0;
450 :
451 531 : if (len == 0)
452 0 : return 0;
453 :
454 531 : assert(p != NULL);
455 :
456 531 : if (p[0] & 0x80) {
457 : unsigned char *q;
458 49 : int carry = 1;
459 49 : data->negative = 1;
460 :
461 49 : data->length = len;
462 :
463 49 : if (p[0] == 0xff) {
464 0 : p++;
465 0 : data->length--;
466 : }
467 49 : data->data = malloc(data->length);
468 49 : if (data->data == NULL) {
469 0 : data->length = 0;
470 0 : if (size)
471 0 : *size = 0;
472 0 : return ENOMEM;
473 : }
474 49 : q = &((unsigned char*)data->data)[data->length - 1];
475 49 : p += data->length - 1;
476 294 : while (q >= (unsigned char*)data->data) {
477 196 : *q = *p ^ 0xff;
478 196 : if (carry)
479 49 : carry = !++*q;
480 196 : p--;
481 196 : q--;
482 : }
483 : } else {
484 482 : data->negative = 0;
485 482 : data->length = len;
486 :
487 482 : if (p[0] == 0) {
488 220 : p++;
489 220 : data->length--;
490 : }
491 482 : data->data = malloc(data->length);
492 482 : if (data->data == NULL && data->length != 0) {
493 0 : data->length = 0;
494 0 : if (size)
495 0 : *size = 0;
496 0 : return ENOMEM;
497 : }
498 482 : memcpy(data->data, p, data->length);
499 : }
500 531 : if (size)
501 531 : *size = len;
502 531 : return 0;
503 : }
504 :
505 : static int
506 734618 : generalizedtime2time (const char *s, time_t *t)
507 : {
508 : struct tm tm;
509 :
510 734618 : memset(&tm, 0, sizeof(tm));
511 734618 : if (sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
512 : &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
513 : &tm.tm_min, &tm.tm_sec) != 6) {
514 302 : if (sscanf (s, "%02d%02d%02d%02d%02d%02dZ",
515 : &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
516 : &tm.tm_min, &tm.tm_sec) != 6)
517 0 : return ASN1_BAD_TIMEFORMAT;
518 302 : if (tm.tm_year < 50)
519 302 : tm.tm_year += 2000;
520 : else
521 0 : tm.tm_year += 1900;
522 : }
523 734618 : tm.tm_year -= 1900;
524 734618 : tm.tm_mon -= 1;
525 734618 : *t = _der_timegm (&tm);
526 734618 : return 0;
527 : }
528 :
529 : static int ASN1CALL
530 734618 : der_get_time (const unsigned char *p, size_t len,
531 : time_t *data, size_t *size)
532 : {
533 : char *times;
534 : int e;
535 :
536 734618 : assert(p != NULL);
537 :
538 734618 : if (size)
539 734618 : *size = 0;
540 :
541 734618 : if (len == SIZE_MAX || len == 0)
542 0 : return ASN1_BAD_LENGTH;
543 :
544 734618 : times = malloc(len + 1);
545 734618 : if (times == NULL)
546 0 : return ENOMEM;
547 734618 : memcpy(times, p, len);
548 734618 : times[len] = '\0';
549 734618 : e = generalizedtime2time(times, data);
550 734618 : free (times);
551 734618 : if(size) *size = len;
552 734618 : return e;
553 : }
554 :
555 : int ASN1CALL
556 734316 : der_get_generalized_time (const unsigned char *p, size_t len,
557 : time_t *data, size_t *size)
558 : {
559 734316 : return der_get_time(p, len, data, size);
560 : }
561 :
562 : int ASN1CALL
563 302 : der_get_utctime (const unsigned char *p, size_t len,
564 : time_t *data, size_t *size)
565 : {
566 302 : return der_get_time(p, len, data, size);
567 : }
568 :
569 : int ASN1CALL
570 54478 : der_get_oid (const unsigned char *p, size_t len,
571 : heim_oid *data, size_t *size)
572 : {
573 : size_t n;
574 54478 : size_t oldlen = len;
575 :
576 54478 : assert(p != NULL);
577 :
578 54478 : if (size)
579 18180 : *size = 0;
580 :
581 54478 : if (len < 1)
582 0 : return ASN1_OVERRUN;
583 :
584 54478 : if (len == SIZE_MAX)
585 0 : return ASN1_BAD_LENGTH;
586 :
587 54478 : if (len + 1 > UINT_MAX/sizeof(data->components[0]))
588 0 : return ERANGE;
589 :
590 54478 : data->components = malloc((len + 1) * sizeof(data->components[0]));
591 54478 : if (data->components == NULL) {
592 0 : data->length = 0;
593 0 : return ENOMEM;
594 : }
595 54478 : data->components[0] = (*p) / 40;
596 54478 : data->components[1] = (*p) % 40;
597 54478 : --len;
598 54478 : ++p;
599 302098 : for (n = 2; len > 0; ++n) {
600 247620 : unsigned u = 0, u1;
601 :
602 : do {
603 348770 : --len;
604 348770 : u1 = u * 128 + (*p++ % 128);
605 : /* check that we don't overflow the element */
606 348770 : if (u1 < u) {
607 0 : der_free_oid(data);
608 0 : return ASN1_OVERRUN;
609 : }
610 348770 : u = u1;
611 348770 : } while (len > 0 && p[-1] & 0x80);
612 247620 : data->components[n] = u;
613 : }
614 54478 : if (n > 2 && p[-1] & 0x80) {
615 0 : der_free_oid (data);
616 0 : return ASN1_OVERRUN;
617 : }
618 54478 : data->length = n;
619 54478 : if (size)
620 18180 : *size = oldlen;
621 54478 : return 0;
622 : }
623 :
624 : int ASN1CALL
625 25010792 : der_get_tag (const unsigned char *p, size_t len,
626 : Der_class *cls, Der_type *type,
627 : unsigned int *tag, size_t *size)
628 : {
629 25010792 : size_t ret = 0;
630 :
631 25010792 : if (size)
632 25010792 : *size = 0;
633 :
634 25010792 : if (len < 1)
635 364238 : return ASN1_MISSING_FIELD;
636 :
637 24646554 : assert(p != NULL);
638 :
639 24646554 : *cls = (Der_class)(((*p) >> 6) & 0x03);
640 24646554 : *type = (Der_type)(((*p) >> 5) & 0x01);
641 24646554 : *tag = (*p) & 0x1f;
642 24646554 : p++; len--; ret++;
643 24646554 : if(*tag == 0x1f) {
644 : unsigned int continuation;
645 : unsigned int tag1;
646 0 : *tag = 0;
647 : do {
648 0 : if(len < 1)
649 0 : return ASN1_OVERRUN;
650 0 : continuation = *p & 128;
651 0 : tag1 = *tag * 128 + (*p % 128);
652 : /* check that we don't overflow the tag */
653 0 : if (tag1 < *tag)
654 0 : return ASN1_OVERFLOW;
655 0 : *tag = tag1;
656 0 : p++; len--; ret++;
657 0 : } while(continuation);
658 : }
659 24646554 : if(size) *size = ret;
660 24646554 : return 0;
661 : }
662 :
663 : int ASN1CALL
664 0 : der_match_tag (const unsigned char *p, size_t len,
665 : Der_class cls, Der_type type,
666 : unsigned int tag, size_t *size)
667 : {
668 : Der_type thistype;
669 : int e;
670 :
671 0 : e = der_match_tag2(p, len, cls, &thistype, tag, size);
672 0 : if (e) return e;
673 0 : if (thistype != type) return ASN1_BAD_ID;
674 0 : return 0;
675 : }
676 :
677 : int ASN1CALL
678 25010072 : der_match_tag2 (const unsigned char *p, size_t len,
679 : Der_class cls, Der_type *type,
680 : unsigned int tag, size_t *size)
681 : {
682 : size_t l;
683 : Der_class thisclass;
684 : unsigned int thistag;
685 : int e;
686 :
687 25010072 : if (size)
688 25010072 : *size = 0;
689 :
690 25010072 : e = der_get_tag(p, len, &thisclass, type, &thistag, &l);
691 25010072 : if (e) return e;
692 : /*
693 : * We do depend on ASN1_BAD_ID being returned in places where we're
694 : * essentially implementing an application-level CHOICE where we try to
695 : * decode one way then the other. In Heimdal this happens only in lib/hdb/
696 : * where we try to decode a blob as an hdb_entry, then as an
697 : * hdb_entry_alias. Applications should really not depend on this.
698 : */
699 24645834 : if (cls != thisclass && (cls == ASN1_C_APPL || thisclass == ASN1_C_APPL))
700 0 : return ASN1_BAD_ID;
701 24645834 : if (cls != thisclass || tag != thistag)
702 949347 : return ASN1_MISSING_FIELD;
703 23696487 : if (size) *size = l;
704 23696487 : return 0;
705 : }
706 :
707 : /*
708 : * Returns 0 if the encoded data at `p' of length `len' starts with the tag of
709 : * class `cls`, type `type', and tag value `tag', and puts the length of the
710 : * payload (i.e., the length of V in TLV, not the length of TLV) in
711 : * `*length_ret', and the size of the whole thing (the TLV) in `*size' if
712 : * `size' is not NULL.
713 : *
714 : * Else returns an error.
715 : */
716 : int ASN1CALL
717 25010072 : der_match_tag_and_length (const unsigned char *p, size_t len,
718 : Der_class cls, Der_type *type, unsigned int tag,
719 : size_t *length_ret, size_t *size)
720 : {
721 25010072 : size_t l, ret = 0;
722 : int e;
723 :
724 25010072 : e = der_match_tag2 (p, len, cls, type, tag, &l);
725 25010072 : if (e) return e;
726 23696487 : p += l;
727 23696487 : len -= l;
728 23696487 : ret += l;
729 23696487 : e = der_get_length (p, len, length_ret, &l);
730 23696487 : if (e) return e;
731 23696487 : if(size) *size = ret + l;
732 23696487 : return 0;
733 : }
734 :
735 :
736 :
737 : /*
738 : * Old versions of DCE was based on a very early beta of the MIT code,
739 : * which used MAVROS for ASN.1 encoding. MAVROS had the interesting
740 : * feature that it encoded data in the forward direction, which has
741 : * it's problems, since you have no idea how long the data will be
742 : * until after you're done. MAVROS solved this by reserving one byte
743 : * for length, and later, if the actual length was longer, it reverted
744 : * to indefinite, BER style, lengths. The version of MAVROS used by
745 : * the DCE people could apparently generate correct X.509 DER encodings, and
746 : * did this by making space for the length after encoding, but
747 : * unfortunately this feature wasn't used with Kerberos.
748 : */
749 :
750 : int
751 0 : _heim_fix_dce(size_t reallen, size_t *len)
752 : {
753 0 : if(reallen == ASN1_INDEFINITE)
754 0 : return 1;
755 0 : if(*len < reallen)
756 0 : return -1;
757 0 : *len = reallen;
758 0 : return 0;
759 : }
760 :
761 : int ASN1CALL
762 302 : der_get_bit_string (const unsigned char *p, size_t len,
763 : heim_bit_string *data, size_t *size)
764 : {
765 302 : assert(p != NULL);
766 :
767 302 : if (size)
768 302 : *size = 0;
769 :
770 302 : if (len < 1)
771 0 : return ASN1_OVERRUN;
772 302 : if (p[0] > 7)
773 0 : return ASN1_BAD_FORMAT;
774 302 : if (len - 1 == 0 && p[0] != 0)
775 0 : return ASN1_BAD_FORMAT;
776 : /* check if any of the three upper bits are set
777 : * any of them will cause a interger overrun */
778 302 : if ((len - 1) >> (sizeof(len) * 8 - 3))
779 0 : return ASN1_OVERRUN;
780 : /*
781 : * If there is data to copy, do that now.
782 : */
783 302 : if (len - 1 > 0) {
784 302 : data->length = (len - 1) * 8;
785 302 : data->data = malloc(len - 1);
786 302 : if (data->data == NULL) {
787 0 : data->length = 0;
788 0 : return ENOMEM;
789 : }
790 302 : memcpy (data->data, p + 1, len - 1);
791 302 : data->length -= p[0];
792 : } else {
793 0 : data->data = NULL;
794 0 : data->length = 0;
795 : }
796 302 : if(size) *size = len;
797 302 : return 0;
798 : }
|