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