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 7139590 : der_get_unsigned (const unsigned char *p, size_t len,
46 : unsigned *ret, size_t *size)
47 : {
48 7139590 : unsigned val = 0;
49 7139590 : size_t oldlen = len;
50 :
51 7139590 : if (len == sizeof(val) + 1 && p[0] == 0)
52 : ;
53 7115562 : else if (len > sizeof(val))
54 0 : return ASN1_OVERRUN;
55 :
56 19765118 : while (len--)
57 12625528 : val = val * 256 + *p++;
58 7139590 : *ret = val;
59 7139590 : if(size) *size = oldlen;
60 6890119 : 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 5804021 : der_get_integer (const unsigned char *p, size_t len,
84 : int *ret, size_t *size)
85 : {
86 5804021 : int val = 0;
87 5804021 : size_t oldlen = len;
88 :
89 5804021 : if (len == sizeof(val) + 1 && (p[0] == 0 || p[0] == 0xff))
90 : ;
91 5804021 : else if (len > sizeof(val))
92 0 : return ASN1_OVERRUN;
93 :
94 : /* We assume we're on a twos-complement platform */
95 5804021 : if (len > 0) {
96 5804021 : val = (signed char)*p++;
97 7481341 : while (--len)
98 1677320 : val = val * 256 + *p++;
99 : }
100 5804021 : *ret = val;
101 5804021 : if(size) *size = oldlen;
102 5596854 : 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 33075379 : 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 33075379 : if (len <= 0)
134 0 : return ASN1_OVERRUN;
135 33075379 : --len;
136 33075379 : v = *p++;
137 33075379 : if (v < 128) {
138 26035289 : *val = v;
139 26035289 : if(size) *size = 1;
140 : } else {
141 245948 : int e;
142 245948 : size_t l;
143 245948 : unsigned tmp;
144 :
145 7040090 : if(v == 0x80){
146 0 : *val = ASN1_INDEFINITE;
147 0 : if(size) *size = 1;
148 0 : return 0;
149 : }
150 7040090 : v &= 0x7F;
151 7040090 : if (len < v)
152 0 : return ASN1_OVERRUN;
153 7040090 : e = der_get_unsigned (p, v, &tmp, &l);
154 7040090 : if(e) return e;
155 7040090 : *val = tmp;
156 7040090 : if(size) *size = l + 1;
157 : }
158 31902643 : return 0;
159 : }
160 :
161 : int ASN1CALL
162 1296 : der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
163 : {
164 1296 : if(len < 1)
165 0 : return ASN1_OVERRUN;
166 1296 : if(*p != 0)
167 1287 : *data = 1;
168 : else
169 9 : *data = 0;
170 1296 : *size = 1;
171 1296 : return 0;
172 : }
173 :
174 : int ASN1CALL
175 2448502 : 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 2448502 : assert(p != NULL);
182 :
183 2448502 : if (size)
184 2448502 : *size = 0;
185 :
186 2448502 : p1 = memchr(p, 0, len);
187 2448502 : 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 2448502 : if (len == SIZE_MAX) {
201 0 : *str = NULL;
202 0 : return ASN1_BAD_LENGTH;
203 : }
204 :
205 2448502 : *str = s = malloc (len + 1);
206 2448502 : if (s == NULL)
207 0 : return ENOMEM;
208 2448502 : memcpy (s, p, len);
209 2448502 : s[len] = '\0';
210 :
211 2448502 : if(size) *size = len;
212 2360149 : return 0;
213 : }
214 :
215 : int ASN1CALL
216 3074 : der_get_utf8string (const unsigned char *p, size_t len,
217 : heim_utf8_string *str, size_t *size)
218 : {
219 3074 : 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 2249 : der_get_printable_string(const unsigned char *p, size_t len,
227 : heim_printable_string *str, size_t *size)
228 : {
229 2249 : assert(p != NULL);
230 :
231 2249 : if (size)
232 2249 : *size = 0;
233 :
234 2249 : if (len == SIZE_MAX) {
235 0 : gen_data_zero(str);
236 0 : return ASN1_BAD_LENGTH;
237 : }
238 2249 : str->length = len;
239 2249 : str->data = malloc(len + 1);
240 2249 : if (str->data == NULL) {
241 0 : gen_data_zero(str);
242 0 : return ENOMEM;
243 : }
244 :
245 2249 : memcpy(str->data, p, len);
246 2249 : ((char *)str->data)[len] = '\0';
247 2249 : if(size) *size = len;
248 2113 : return 0;
249 : }
250 :
251 : int ASN1CALL
252 1295 : der_get_ia5_string(const unsigned char *p, size_t len,
253 : heim_ia5_string *str, size_t *size)
254 : {
255 1295 : 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 2104136 : der_get_octet_string (const unsigned char *p, size_t len,
348 : heim_octet_string *data, size_t *size)
349 : {
350 2104136 : assert(p != NULL);
351 :
352 2104136 : if (size)
353 2104136 : *size = 0;
354 :
355 2104136 : if (len == 0)
356 240554 : data->data = malloc(1);
357 : else
358 1863582 : data->data = malloc(len);
359 2104136 : if (data->data == NULL) {
360 0 : data->length = 0;
361 0 : return ENOMEM;
362 : }
363 2104136 : data->length = len;
364 2104136 : memcpy (data->data, p, len);
365 2104136 : if (size)
366 2104136 : *size = len;
367 2029265 : 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 1769 : der_get_heim_integer (const unsigned char *p, size_t len,
446 : heim_integer *data, size_t *size)
447 : {
448 1769 : data->length = 0;
449 1769 : data->negative = 0;
450 1769 : data->data = NULL;
451 :
452 1769 : if (size)
453 1769 : *size = 0;
454 :
455 1769 : if (len == 0)
456 0 : return 0;
457 :
458 1769 : assert(p != NULL);
459 :
460 1769 : 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 1710 : data->negative = 0;
529 1710 : data->length = len;
530 :
531 1710 : if (p[0] == 0) {
532 775 : p++;
533 775 : data->length--;
534 : }
535 1710 : data->data = malloc(data->length);
536 1710 : 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 1710 : memcpy(data->data, p, data->length);
543 : }
544 1769 : if (size)
545 1769 : *size = len;
546 1673 : return 0;
547 : }
548 :
549 : static int
550 1022797 : generalizedtime2time (const char *s, time_t *t)
551 : {
552 35787 : struct tm tm;
553 :
554 1022797 : memset(&tm, 0, sizeof(tm));
555 1022797 : 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 763 : 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 763 : if (tm.tm_year < 50)
563 763 : tm.tm_year += 2000;
564 : else
565 0 : tm.tm_year += 1900;
566 : }
567 1022797 : tm.tm_year -= 1900;
568 1022797 : tm.tm_mon -= 1;
569 1022797 : *t = _der_timegm (&tm);
570 1022797 : return 0;
571 : }
572 :
573 : static int ASN1CALL
574 1022797 : 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 1022797 : assert(p != NULL);
581 :
582 1022797 : if (size)
583 1022797 : *size = 0;
584 :
585 1022797 : if (len == SIZE_MAX || len == 0)
586 0 : return ASN1_BAD_LENGTH;
587 :
588 1022797 : times = malloc(len + 1);
589 1022797 : if (times == NULL)
590 0 : return ENOMEM;
591 1022797 : memcpy(times, p, len);
592 1022797 : times[len] = '\0';
593 1022797 : e = generalizedtime2time(times, data);
594 1022797 : free (times);
595 1022797 : if(size) *size = len;
596 987010 : return e;
597 : }
598 :
599 : int ASN1CALL
600 1022034 : der_get_generalized_time (const unsigned char *p, size_t len,
601 : time_t *data, size_t *size)
602 : {
603 1022034 : return der_get_time(p, len, data, size);
604 : }
605 :
606 : int ASN1CALL
607 763 : der_get_utctime (const unsigned char *p, size_t len,
608 : time_t *data, size_t *size)
609 : {
610 763 : return der_get_time(p, len, data, size);
611 : }
612 :
613 : int ASN1CALL
614 77860 : der_get_oid (const unsigned char *p, size_t len,
615 : heim_oid *data, size_t *size)
616 : {
617 3115 : size_t n;
618 77860 : size_t oldlen = len;
619 :
620 77860 : assert(p != NULL);
621 :
622 77860 : if (size)
623 30200 : *size = 0;
624 :
625 77860 : if (len < 1)
626 0 : return ASN1_OVERRUN;
627 :
628 77860 : if (len == SIZE_MAX)
629 0 : return ASN1_BAD_LENGTH;
630 :
631 77860 : if (len + 1 > UINT_MAX/sizeof(data->components[0]))
632 0 : return ERANGE;
633 :
634 77860 : data->components = malloc((len + 1) * sizeof(data->components[0]));
635 77860 : if (data->components == NULL) {
636 0 : data->length = 0;
637 0 : return ENOMEM;
638 : }
639 77860 : data->components[0] = (*p) / 40;
640 77860 : data->components[1] = (*p) % 40;
641 77860 : --len;
642 77860 : ++p;
643 427735 : for (n = 2; len > 0; ++n) {
644 336213 : unsigned u = 0, u1;
645 :
646 19076 : do {
647 490538 : --len;
648 490538 : u1 = u * 128 + (*p++ % 128);
649 : /* check that we don't overflow the element */
650 490538 : if (u1 < u) {
651 0 : der_free_oid(data);
652 0 : return ASN1_OVERRUN;
653 : }
654 490538 : u = u1;
655 490538 : } while (len > 0 && p[-1] & 0x80);
656 349875 : data->components[n] = u;
657 : }
658 77860 : if (n > 2 && p[-1] & 0x80) {
659 0 : der_free_oid (data);
660 0 : return ASN1_OVERRUN;
661 : }
662 77860 : data->length = n;
663 77860 : if (size)
664 30200 : *size = oldlen;
665 74745 : return 0;
666 : }
667 :
668 : int ASN1CALL
669 34722650 : 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 34722650 : size_t ret = 0;
674 :
675 34722650 : if (size)
676 34722650 : *size = 0;
677 :
678 34722650 : if (len < 1)
679 507185 : return ASN1_MISSING_FIELD;
680 :
681 34198163 : assert(p != NULL);
682 :
683 34198163 : *cls = (Der_class)(((*p) >> 6) & 0x03);
684 34198163 : *type = (Der_type)(((*p) >> 5) & 0x01);
685 34198163 : *tag = (*p) & 0x1f;
686 34198163 : p++; len--; ret++;
687 34198163 : 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 34198163 : if(size) *size = ret;
704 32981090 : 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 34719825 : 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 34719825 : if (size)
732 34719825 : *size = 0;
733 :
734 34719825 : e = der_get_tag(p, len, &thisclass, type, &thistag, &l);
735 34719825 : 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 34195572 : if (cls != thisclass && (cls == ASN1_C_APPL || thisclass == ASN1_C_APPL))
744 0 : return ASN1_BAD_ID;
745 34195572 : if (cls != thisclass || tag != thistag)
746 1299874 : return ASN1_MISSING_FIELD;
747 32847413 : if (size) *size = l;
748 31678697 : 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 34719825 : 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 34719825 : size_t l, ret = 0;
766 1234303 : int e;
767 :
768 34719825 : e = der_match_tag2 (p, len, cls, type, tag, &l);
769 34719825 : if (e) return e;
770 32847413 : p += l;
771 32847413 : len -= l;
772 32847413 : ret += l;
773 32847413 : e = der_get_length (p, len, length_ret, &l);
774 32847413 : if (e) return e;
775 32847413 : if(size) *size = ret + l;
776 31678697 : 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 748 : der_get_bit_string (const unsigned char *p, size_t len,
807 : heim_bit_string *data, size_t *size)
808 : {
809 748 : assert(p != NULL);
810 :
811 748 : if (size)
812 748 : *size = 0;
813 :
814 748 : if (len < 1)
815 0 : return ASN1_OVERRUN;
816 748 : if (p[0] > 7)
817 0 : return ASN1_BAD_FORMAT;
818 748 : 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 748 : 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 748 : if (len - 1 > 0) {
828 748 : data->length = (len - 1) * 8;
829 748 : data->data = malloc(len - 1);
830 748 : if (data->data == NULL) {
831 0 : data->length = 0;
832 0 : return ENOMEM;
833 : }
834 748 : memcpy (data->data, p + 1, len - 1);
835 748 : data->length -= p[0];
836 : } else {
837 0 : data->data = NULL;
838 0 : data->length = 0;
839 : }
840 748 : if(size) *size = len;
841 708 : return 0;
842 : }
|