rxkad: Improve ticket5 import from Heimdal
[openafs.git] / src / rxkad / v5der.c
1 #include <errno.h>
2 #include <limits.h>
3 /*
4  * Copyright (c) 1997 Kungliga Tekniska Högskolan
5  * (Royal Institute of Technology, Stockholm, Sweden).
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the Institute nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35
36
37 #define ASN1_MAX_YEAR   2000
38
39 static int
40 is_leap(unsigned y)
41 {
42     y += 1900;
43     return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
44 }
45
46 static const unsigned ndays[2][12] ={
47     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
48     {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
49
50 /*
51  * This is a simplifed version of timegm(3) that doesn't accept out of
52  * bound values that timegm(3) normally accepts but those are not
53  * valid in asn1 encodings.
54  */
55
56 time_t
57 _der_timegm (struct tm *tm)
58 {
59   time_t res = 0;
60   int i;
61
62   /*
63    * See comment in _der_gmtime
64    */
65   if (tm->tm_year > ASN1_MAX_YEAR)
66       return 0;
67
68   if (tm->tm_year < 0)
69       return -1;
70   if (tm->tm_mon < 0 || tm->tm_mon > 11)
71       return -1;
72   if (tm->tm_mday < 1 || tm->tm_mday > (int)ndays[is_leap(tm->tm_year)][tm->tm_mon])
73       return -1;
74   if (tm->tm_hour < 0 || tm->tm_hour > 23)
75       return -1;
76   if (tm->tm_min < 0 || tm->tm_min > 59)
77       return -1;
78   if (tm->tm_sec < 0 || tm->tm_sec > 59)
79       return -1;
80
81   for (i = 70; i < tm->tm_year; ++i)
82     res += is_leap(i) ? 366 : 365;
83
84   for (i = 0; i < tm->tm_mon; ++i)
85     res += ndays[is_leap(tm->tm_year)][i];
86   res += tm->tm_mday - 1;
87   res *= 24;
88   res += tm->tm_hour;
89   res *= 60;
90   res += tm->tm_min;
91   res *= 60;
92   res += tm->tm_sec;
93   return res;
94 }
95
96 struct tm *
97 _der_gmtime(time_t t, struct tm *tm)
98 {
99     time_t secday = t % (3600 * 24);
100     time_t days = t / (3600 * 24);
101
102     memset(tm, 0, sizeof(*tm));
103
104     tm->tm_sec = secday % 60;
105     tm->tm_min = (secday % 3600) / 60;
106     tm->tm_hour = (int)(secday / 3600);
107
108     /*
109      * Refuse to calculate time ~ 2000 years into the future, this is
110      * not possible for systems where time_t is a int32_t, however,
111      * when time_t is a int64_t, that can happen, and this becomes a
112      * denial of sevice.
113      */
114     if (days > (ASN1_MAX_YEAR * 365))
115         return NULL;
116
117     tm->tm_year = 70;
118     while(1) {
119         unsigned dayinyear = (is_leap(tm->tm_year) ? 366 : 365);
120         if (days < dayinyear)
121             break;
122         tm->tm_year += 1;
123         days -= dayinyear;
124     }
125     tm->tm_mon = 0;
126
127     while (1) {
128         unsigned daysinmonth = ndays[is_leap(tm->tm_year)][tm->tm_mon];
129         if (days < daysinmonth)
130             break;
131         days -= daysinmonth;
132         tm->tm_mon++;
133     }
134     tm->tm_mday = (int)(days + 1);
135
136     return tm;
137 }
138 /*
139  * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
140  * (Royal Institute of Technology, Stockholm, Sweden).
141  * All rights reserved.
142  *
143  * Redistribution and use in source and binary forms, with or without
144  * modification, are permitted provided that the following conditions
145  * are met:
146  *
147  * 1. Redistributions of source code must retain the above copyright
148  *    notice, this list of conditions and the following disclaimer.
149  *
150  * 2. Redistributions in binary form must reproduce the above copyright
151  *    notice, this list of conditions and the following disclaimer in the
152  *    documentation and/or other materials provided with the distribution.
153  *
154  * 3. Neither the name of the Institute nor the names of its contributors
155  *    may be used to endorse or promote products derived from this software
156  *    without specific prior written permission.
157  *
158  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
159  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
160  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
161  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
162  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
163  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
164  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
165  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
166  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
167  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
168  * SUCH DAMAGE.
169  */
170
171
172 /*
173  * All decoding functions take a pointer `p' to first position in
174  * which to read, from the left, `len' which means the maximum number
175  * of characters we are able to read, `ret' were the value will be
176  * returned and `size' where the number of used bytes is stored.
177  * Either 0 or an error code is returned.
178  */
179
180 int
181 der_get_unsigned (const unsigned char *p, size_t len,
182                   unsigned *ret, size_t *size)
183 {
184     unsigned val = 0;
185     size_t oldlen = len;
186
187     if (len == sizeof(val) + 1 && p[0] == 0)
188         ;
189     else if (len > sizeof(val))
190         return ASN1_OVERRUN;
191
192     while (len--)
193         val = val * 256 + *p++;
194     *ret = val;
195     if(size) *size = oldlen;
196     return 0;
197 }
198
199 int
200 der_get_unsigned64 (const unsigned char *p, size_t len,
201                    uint64_t *ret, size_t *size)
202 {
203     uint64_t val = 0;
204     size_t oldlen = len;
205
206     if (len == sizeof(val) + 1 && p[0] == 0)
207        ;
208     else if (len > sizeof(val))
209         return ASN1_OVERRUN;
210
211     while (len--)
212         val = val * 256 + *p++;
213     *ret = val;
214     if(size) *size = oldlen;
215     return 0;
216 }
217
218 int
219 der_get_integer (const unsigned char *p, size_t len,
220                  int *ret, size_t *size)
221 {
222     int val = 0;
223     size_t oldlen = len;
224
225     if (len > sizeof(val))
226         return ASN1_OVERRUN;
227
228     if (len > 0) {
229         val = (signed char)*p++;
230         while (--len)
231             val = val * 256 + *p++;
232     }
233     *ret = val;
234     if(size) *size = oldlen;
235     return 0;
236 }
237
238 int
239 der_get_integer64 (const unsigned char *p, size_t len,
240                    int64_t *ret, size_t *size)
241 {
242     int64_t val = 0;
243     size_t oldlen = len;
244
245     if (len > sizeof(val))
246         return ASN1_OVERRUN;
247
248     if (len > 0) {
249        val = (signed char)*p++;
250        while (--len)
251            val = val * 256 + *p++;
252     }
253     *ret = val;
254     if(size) *size = oldlen;
255     return 0;
256 }
257
258
259 int
260 der_get_length (const unsigned char *p, size_t len,
261                 size_t *val, size_t *size)
262 {
263     size_t v;
264
265     if (len <= 0)
266         return ASN1_OVERRUN;
267     --len;
268     v = *p++;
269     if (v < 128) {
270         *val = v;
271         if(size) *size = 1;
272     } else {
273         int e;
274         size_t l;
275         unsigned tmp;
276
277         if(v == 0x80){
278             *val = ASN1_INDEFINITE;
279             if(size) *size = 1;
280             return 0;
281         }
282         v &= 0x7F;
283         if (len < v)
284             return ASN1_OVERRUN;
285         e = der_get_unsigned (p, v, &tmp, &l);
286         if(e) return e;
287         *val = tmp;
288         if(size) *size = l + 1;
289     }
290     return 0;
291 }
292
293 int
294 der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
295 {
296     if(len < 1)
297         return ASN1_OVERRUN;
298     if(*p != 0)
299         *data = 1;
300     else
301         *data = 0;
302     *size = 1;
303     return 0;
304 }
305
306 int
307 der_get_general_string (const unsigned char *p, size_t len,
308                         heim_general_string *str, size_t *size)
309 {
310     const unsigned char *p1;
311     char *s;
312
313     p1 = memchr(p, 0, len);
314     if (p1 != NULL) {
315         /*
316          * Allow trailing NULs. We allow this since MIT Kerberos sends
317          * an strings in the NEED_PREAUTH case that includes a
318          * trailing NUL.
319          */
320         while ((size_t)(p1 - p) < len && *p1 == '\0')
321             p1++;
322         if ((size_t)(p1 - p) != len) {
323             *str = NULL;
324             return ASN1_BAD_CHARACTER;
325         }
326     }
327     if (len == SIZE_MAX) {
328         *str = NULL;
329         return ASN1_BAD_LENGTH;
330     }
331
332     *str = s = malloc (len + 1);
333     if (s == NULL)
334         return ENOMEM;
335     memcpy (s, p, len);
336     s[len] = '\0';
337
338     if(size) *size = len;
339     return 0;
340 }
341
342 int
343 der_get_utf8string (const unsigned char *p, size_t len,
344                     heim_utf8_string *str, size_t *size)
345 {
346     return der_get_general_string(p, len, str, size);
347 }
348
349 #define gen_data_zero(_data) \
350         do { (_data)->length = 0; (_data)->data = NULL; } while(0)
351
352 int
353 der_get_printable_string(const unsigned char *p, size_t len,
354                          heim_printable_string *str, size_t *size)
355 {
356     if (len == SIZE_MAX) {
357         gen_data_zero(str);
358         return ASN1_BAD_LENGTH;
359     }
360     str->length = len;
361     str->data = malloc(len + 1);
362     if (str->data == NULL) {
363         gen_data_zero(str);
364         return ENOMEM;
365     }
366     memcpy(str->data, p, len);
367     ((char *)str->data)[len] = '\0';
368     if(size) *size = len;
369     return 0;
370 }
371
372 int
373 der_get_ia5_string(const unsigned char *p, size_t len,
374                    heim_ia5_string *str, size_t *size)
375 {
376     return der_get_printable_string(p, len, str, size);
377 }
378
379 int
380 der_get_bmp_string (const unsigned char *p, size_t len,
381                     heim_bmp_string *data, size_t *size)
382 {
383     size_t i;
384
385     if (len & 1) {
386         gen_data_zero(data);
387         return ASN1_BAD_FORMAT;
388     }
389     data->length = len / 2;
390     if (data->length > UINT_MAX/sizeof(data->data[0])) {
391         gen_data_zero(data);
392         return ERANGE;
393     }
394     data->data = malloc(data->length * sizeof(data->data[0]));
395     if (data->data == NULL && data->length != 0) {
396         gen_data_zero(data);
397         return ENOMEM;
398     }
399
400     for (i = 0; i < data->length; i++) {
401         data->data[i] = (p[0] << 8) | p[1];
402         p += 2;
403         /* check for NUL in the middle of the string */
404         if (data->data[i] == 0 && i != (data->length - 1)) {
405             free(data->data);
406             gen_data_zero(data);
407             return ASN1_BAD_CHARACTER;
408         }
409     }
410     if (size) *size = len;
411
412     return 0;
413 }
414
415 int
416 der_get_universal_string (const unsigned char *p, size_t len,
417                           heim_universal_string *data, size_t *size)
418 {
419     size_t i;
420
421     if (len & 3) {
422         gen_data_zero(data);
423         return ASN1_BAD_FORMAT;
424     }
425     data->length = len / 4;
426     if (data->length > UINT_MAX/sizeof(data->data[0])) {
427         gen_data_zero(data);
428         return ERANGE;
429     }
430     data->data = malloc(data->length * sizeof(data->data[0]));
431     if (data->data == NULL && data->length != 0) {
432         gen_data_zero(data);
433         return ENOMEM;
434     }
435
436     for (i = 0; i < data->length; i++) {
437         data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
438         p += 4;
439         /* check for NUL in the middle of the string */
440         if (data->data[i] == 0 && i != (data->length - 1)) {
441             free(data->data);
442             gen_data_zero(data);
443             return ASN1_BAD_CHARACTER;
444         }
445     }
446     if (size) *size = len;
447     return 0;
448 }
449
450 int
451 der_get_visible_string (const unsigned char *p, size_t len,
452                         heim_visible_string *str, size_t *size)
453 {
454     return der_get_general_string(p, len, str, size);
455 }
456
457 int
458 der_get_octet_string (const unsigned char *p, size_t len,
459                       heim_octet_string *data, size_t *size)
460 {
461     data->length = len;
462     data->data = malloc(len);
463     if (data->data == NULL && data->length != 0)
464         return ENOMEM;
465     memcpy (data->data, p, len);
466     if(size) *size = len;
467     return 0;
468 }
469
470 int
471 der_get_octet_string_ber (const unsigned char *p, size_t len,
472                           heim_octet_string *data, size_t *size)
473 {
474     int e;
475     Der_type type;
476     Der_class cls;
477     unsigned int tag, depth = 0;
478     size_t l, datalen, oldlen = len;
479
480     data->length = 0;
481     data->data = NULL;
482
483     while (len) {
484         e = der_get_tag (p, len, &cls, &type, &tag, &l);
485         if (e) goto out;
486         if (cls != ASN1_C_UNIV) {
487             e = ASN1_BAD_ID;
488             goto out;
489         }
490         if (type == PRIM && tag == UT_EndOfContent) {
491             if (depth == 0)
492                 break;
493             depth--;
494         }
495         if (tag != UT_OctetString) {
496             e = ASN1_BAD_ID;
497             goto out;
498         }
499
500         p += l;
501         len -= l;
502         e = der_get_length (p, len, &datalen, &l);
503         if (e) goto out;
504         p += l;
505         len -= l;
506
507         if (datalen > len)
508             return ASN1_OVERRUN;
509
510         if (type == PRIM) {
511             void *ptr;
512
513             ptr = realloc(data->data, data->length + datalen);
514             if (ptr == NULL) {
515                 e = ENOMEM;
516                 goto out;
517             }
518             data->data = ptr;
519             memcpy(((unsigned char *)data->data) + data->length, p, datalen);
520             data->length += datalen;
521         } else
522             depth++;
523
524         p += datalen;
525         len -= datalen;
526     }
527     if (depth != 0)
528         return ASN1_INDEF_OVERRUN;
529     if(size) *size = oldlen - len;
530     return 0;
531  out:
532     free(data->data);
533     data->data = NULL;
534     data->length = 0;
535     return e;
536 }
537
538
539 int
540 der_get_heim_integer (const unsigned char *p, size_t len,
541                       heim_integer *data, size_t *size)
542 {
543     data->length = 0;
544     data->negative = 0;
545     data->data = NULL;
546
547     if (len == 0) {
548         if (size)
549             *size = 0;
550         return 0;
551     }
552     if (p[0] & 0x80) {
553         unsigned char *q;
554         int carry = 1;
555         data->negative = 1;
556
557         data->length = len;
558
559         if (p[0] == 0xff) {
560             p++;
561             data->length--;
562         }
563         data->data = malloc(data->length);
564         if (data->data == NULL) {
565             data->length = 0;
566             if (size)
567                 *size = 0;
568             return ENOMEM;
569         }
570         q = &((unsigned char*)data->data)[data->length - 1];
571         p += data->length - 1;
572         while (q >= (unsigned char*)data->data) {
573             *q = *p ^ 0xff;
574             if (carry)
575                 carry = !++*q;
576             p--;
577             q--;
578         }
579     } else {
580         data->negative = 0;
581         data->length = len;
582
583         if (p[0] == 0) {
584             p++;
585             data->length--;
586         }
587         data->data = malloc(data->length);
588         if (data->data == NULL && data->length != 0) {
589             data->length = 0;
590             if (size)
591                 *size = 0;
592             return ENOMEM;
593         }
594         memcpy(data->data, p, data->length);
595     }
596     if (size)
597         *size = len;
598     return 0;
599 }
600
601 static int
602 generalizedtime2time (const char *s, time_t *t)
603 {
604     struct tm tm;
605
606     memset(&tm, 0, sizeof(tm));
607     if (sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
608                 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
609                 &tm.tm_min, &tm.tm_sec) != 6) {
610         if (sscanf (s, "%02d%02d%02d%02d%02d%02dZ",
611                     &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
612                     &tm.tm_min, &tm.tm_sec) != 6)
613             return ASN1_BAD_TIMEFORMAT;
614         if (tm.tm_year < 50)
615             tm.tm_year += 2000;
616         else
617             tm.tm_year += 1900;
618     }
619     tm.tm_year -= 1900;
620     tm.tm_mon -= 1;
621     *t = _der_timegm (&tm);
622     return 0;
623 }
624
625 static int
626 der_get_time (const unsigned char *p, size_t len,
627               time_t *data, size_t *size)
628 {
629     char *times;
630     int e;
631
632     if (len == SIZE_MAX || len == 0)
633         return ASN1_BAD_LENGTH;
634
635     times = malloc(len + 1);
636     if (times == NULL)
637         return ENOMEM;
638     memcpy(times, p, len);
639     times[len] = '\0';
640     e = generalizedtime2time(times, data);
641     free (times);
642     if(size) *size = len;
643     return e;
644 }
645
646 int
647 der_get_generalized_time (const unsigned char *p, size_t len,
648                           time_t *data, size_t *size)
649 {
650     return der_get_time(p, len, data, size);
651 }
652
653 int
654 der_get_utctime (const unsigned char *p, size_t len,
655                           time_t *data, size_t *size)
656 {
657     return der_get_time(p, len, data, size);
658 }
659
660 int
661 der_get_oid (const unsigned char *p, size_t len,
662              heim_oid *data, size_t *size)
663 {
664     size_t n;
665     size_t oldlen = len;
666
667     if (len < 1)
668         return ASN1_OVERRUN;
669
670     if (len == SIZE_MAX)
671         return ASN1_BAD_LENGTH;
672
673     if (len + 1 > UINT_MAX/sizeof(data->components[0]))
674         return ERANGE;
675
676     data->components = malloc((len + 1) * sizeof(data->components[0]));
677     if (data->components == NULL)
678         return ENOMEM;
679     data->components[0] = (*p) / 40;
680     data->components[1] = (*p) % 40;
681     --len;
682     ++p;
683     for (n = 2; len > 0; ++n) {
684         unsigned u = 0, u1;
685
686         do {
687             --len;
688             u1 = u * 128 + (*p++ % 128);
689             /* check that we don't overflow the element */
690             if (u1 < u) {
691                 der_free_oid(data);
692                 return ASN1_OVERRUN;
693             }
694             u = u1;
695         } while (len > 0 && p[-1] & 0x80);
696         data->components[n] = u;
697     }
698     if (n > 2 && p[-1] & 0x80) {
699         der_free_oid (data);
700         return ASN1_OVERRUN;
701     }
702     data->length = n;
703     if (size)
704         *size = oldlen;
705     return 0;
706 }
707
708 int
709 der_get_tag (const unsigned char *p, size_t len,
710              Der_class *cls, Der_type *type,
711              unsigned int *tag, size_t *size)
712 {
713     size_t ret = 0;
714     if (len < 1)
715         return ASN1_OVERRUN;
716     *cls = (Der_class)(((*p) >> 6) & 0x03);
717     *type = (Der_type)(((*p) >> 5) & 0x01);
718     *tag = (*p) & 0x1f;
719     p++; len--; ret++;
720     if(*tag == 0x1f) {
721         unsigned int continuation;
722         unsigned int tag1;
723         *tag = 0;
724         do {
725             if(len < 1)
726                 return ASN1_OVERRUN;
727             continuation = *p & 128;
728             tag1 = *tag * 128 + (*p % 128);
729             /* check that we don't overflow the tag */
730             if (tag1 < *tag)
731                 return ASN1_OVERFLOW;
732             *tag = tag1;
733             p++; len--; ret++;
734         } while(continuation);
735     }
736     if(size) *size = ret;
737     return 0;
738 }
739
740 int
741 der_match_tag (const unsigned char *p, size_t len,
742                Der_class cls, Der_type type,
743                unsigned int tag, size_t *size)
744 {
745     Der_type thistype;
746     int e;
747
748     e = der_match_tag2(p, len, cls, &thistype, tag, size);
749     if (e) return e;
750     if (thistype != type) return ASN1_BAD_ID;
751     return 0;
752 }
753
754 int
755 der_match_tag2 (const unsigned char *p, size_t len,
756                 Der_class cls, Der_type *type,
757                 unsigned int tag, size_t *size)
758 {
759     size_t l;
760     Der_class thisclass;
761     unsigned int thistag;
762     int e;
763
764     e = der_get_tag (p, len, &thisclass, type, &thistag, &l);
765     if (e) return e;
766     if (cls != thisclass)
767         return ASN1_BAD_ID;
768     if(tag > thistag)
769         return ASN1_MISPLACED_FIELD;
770     if(tag < thistag)
771         return ASN1_MISSING_FIELD;
772     if(size) *size = l;
773     return 0;
774 }
775
776 int
777 der_match_tag_and_length (const unsigned char *p, size_t len,
778                           Der_class cls, Der_type *type, unsigned int tag,
779                           size_t *length_ret, size_t *size)
780 {
781     size_t l, ret = 0;
782     int e;
783
784     e = der_match_tag2 (p, len, cls, type, tag, &l);
785     if (e) return e;
786     p += l;
787     len -= l;
788     ret += l;
789     e = der_get_length (p, len, length_ret, &l);
790     if (e) return e;
791     if(size) *size = ret + l;
792     return 0;
793 }
794
795
796
797 /*
798  * Old versions of DCE was based on a very early beta of the MIT code,
799  * which used MAVROS for ASN.1 encoding. MAVROS had the interesting
800  * feature that it encoded data in the forward direction, which has
801  * it's problems, since you have no idea how long the data will be
802  * until after you're done. MAVROS solved this by reserving one byte
803  * for length, and later, if the actual length was longer, it reverted
804  * to indefinite, BER style, lengths. The version of MAVROS used by
805  * the DCE people could apparently generate correct X.509 DER encodings, and
806  * did this by making space for the length after encoding, but
807  * unfortunately this feature wasn't used with Kerberos.
808  */
809
810 int
811 _heim_fix_dce(size_t reallen, size_t *len)
812 {
813     if(reallen == ASN1_INDEFINITE)
814         return 1;
815     if(*len < reallen)
816         return -1;
817     *len = reallen;
818     return 0;
819 }
820
821 int
822 der_get_bit_string (const unsigned char *p, size_t len,
823                     heim_bit_string *data, size_t *size)
824 {
825     if (len < 1)
826         return ASN1_OVERRUN;
827     if (p[0] > 7)
828         return ASN1_BAD_FORMAT;
829     if (len - 1 == 0 && p[0] != 0)
830         return ASN1_BAD_FORMAT;
831     /* check if any of the three upper bits are set
832      * any of them will cause a interger overrun */
833     if ((len - 1) >> (sizeof(len) * 8 - 3))
834         return ASN1_OVERRUN;
835     /*
836      * If there is data to copy, do that now.
837      */
838     if (len - 1 > 0) {
839         data->length = (len - 1) * 8;
840         data->data = malloc(len - 1);
841         if (data->data == NULL)
842             return ENOMEM;
843         memcpy (data->data, p + 1, len - 1);
844         data->length -= p[0];
845     } else {
846         data->data = NULL;
847         data->length = 0;
848     }
849     if(size) *size = len;
850     return 0;
851 }
852 /*
853  * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
854  * (Royal Institute of Technology, Stockholm, Sweden).
855  * All rights reserved.
856  *
857  * Redistribution and use in source and binary forms, with or without
858  * modification, are permitted provided that the following conditions
859  * are met:
860  *
861  * 1. Redistributions of source code must retain the above copyright
862  *    notice, this list of conditions and the following disclaimer.
863  *
864  * 2. Redistributions in binary form must reproduce the above copyright
865  *    notice, this list of conditions and the following disclaimer in the
866  *    documentation and/or other materials provided with the distribution.
867  *
868  * 3. Neither the name of the Institute nor the names of its contributors
869  *    may be used to endorse or promote products derived from this software
870  *    without specific prior written permission.
871  *
872  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
873  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
874  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
875  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
876  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
877  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
878  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
879  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
880  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
881  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
882  * SUCH DAMAGE.
883  */
884
885
886 /* RCSID("$Id$"); */
887
888 /*
889  * All encoding functions take a pointer `p' to first position in
890  * which to write, from the right, `len' which means the maximum
891  * number of characters we are able to write.  The function returns
892  * the number of characters written in `size' (if non-NULL).
893  * The return value is 0 or an error.
894  */
895
896 int
897 der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size)
898 {
899     unsigned char *base = p;
900     unsigned val = *v;
901
902     if (val) {
903         while (len > 0 && val) {
904             *p-- = val % 256;
905             val /= 256;
906             --len;
907         }
908         if (val != 0)
909             return ASN1_OVERFLOW;
910         else {
911             if(p[1] >= 128) {
912                 if(len < 1)
913                     return ASN1_OVERFLOW;
914                 *p-- = 0;
915             }
916             *size = base - p;
917             return 0;
918         }
919     } else if (len < 1)
920         return ASN1_OVERFLOW;
921     else {
922         *p    = 0;
923         *size = 1;
924         return 0;
925     }
926 }
927
928 int
929 der_put_unsigned64 (unsigned char *p, size_t len, const uint64_t *v, size_t *size)
930 {
931     unsigned char *base = p;
932     uint64_t val = *v;
933
934     if (val) {
935        while (len > 0 && val) {
936            *p-- = val % 256;
937            val /= 256;
938            --len;
939        }
940        if (val != 0)
941            return ASN1_OVERFLOW;
942        else {
943            if(p[1] >= 128) {
944                if(len < 1)
945                    return ASN1_OVERFLOW;
946                *p-- = 0;
947            }
948            *size = base - p;
949            return 0;
950        }
951     } else if (len < 1)
952        return ASN1_OVERFLOW;
953     else {
954        *p    = 0;
955        *size = 1;
956        return 0;
957     }
958 }
959
960 int
961 der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size)
962 {
963     unsigned char *base = p;
964     int val = *v;
965
966     if(val >= 0) {
967         do {
968             if(len < 1)
969                 return ASN1_OVERFLOW;
970             *p-- = val % 256;
971             len--;
972             val /= 256;
973         } while(val);
974         if(p[1] >= 128) {
975             if(len < 1)
976                 return ASN1_OVERFLOW;
977             *p-- = 0;
978             len--;
979         }
980     } else {
981         val = ~val;
982         do {
983             if(len < 1)
984                 return ASN1_OVERFLOW;
985             *p-- = ~(val % 256);
986             len--;
987             val /= 256;
988         } while(val);
989         if(p[1] < 128) {
990             if(len < 1)
991                 return ASN1_OVERFLOW;
992             *p-- = 0xff;
993             len--;
994         }
995     }
996     *size = base - p;
997     return 0;
998 }
999
1000 int
1001 der_put_integer64 (unsigned char *p, size_t len, const int64_t *v, size_t *size)
1002 {
1003     unsigned char *base = p;
1004     int64_t val = *v;
1005
1006     if(val >= 0) {
1007        do {
1008            if(len < 1)
1009                return ASN1_OVERFLOW;
1010            *p-- = val % 256;
1011            len--;
1012            val /= 256;
1013        } while(val);
1014        if(p[1] >= 128) {
1015            if(len < 1)
1016                return ASN1_OVERFLOW;
1017            *p-- = 0;
1018            len--;
1019        }
1020     } else {
1021        val = ~val;
1022        do {
1023            if(len < 1)
1024                return ASN1_OVERFLOW;
1025            *p-- = ~(val % 256);
1026            len--;
1027            val /= 256;
1028        } while(val);
1029        if(p[1] < 128) {
1030            if(len < 1)
1031                return ASN1_OVERFLOW;
1032            *p-- = 0xff;
1033            len--;
1034        }
1035     }
1036     *size = base - p;
1037     return 0;
1038 }
1039
1040
1041 int
1042 der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
1043 {
1044     if (len < 1)
1045         return ASN1_OVERFLOW;
1046
1047     if (val < 128) {
1048         *p = val;
1049         *size = 1;
1050     } else {
1051         size_t l = 0;
1052
1053         while(val > 0) {
1054             if(len < 2)
1055                 return ASN1_OVERFLOW;
1056             *p-- = val % 256;
1057             val /= 256;
1058             len--;
1059             l++;
1060         }
1061         *p = 0x80 | l;
1062         if(size)
1063             *size = l + 1;
1064     }
1065     return 0;
1066 }
1067
1068 int
1069 der_put_boolean(unsigned char *p, size_t len, const int *data, size_t *size)
1070 {
1071     if(len < 1)
1072         return ASN1_OVERFLOW;
1073     if(*data != 0)
1074         *p = 0xff;
1075     else
1076         *p = 0;
1077     *size = 1;
1078     return 0;
1079 }
1080
1081 int
1082 der_put_general_string (unsigned char *p, size_t len,
1083                         const heim_general_string *str, size_t *size)
1084 {
1085     size_t slen = strlen(*str);
1086
1087     if (len < slen)
1088         return ASN1_OVERFLOW;
1089     p -= slen;
1090     memcpy (p+1, *str, slen);
1091     *size = slen;
1092     return 0;
1093 }
1094
1095 int
1096 der_put_utf8string (unsigned char *p, size_t len,
1097                     const heim_utf8_string *str, size_t *size)
1098 {
1099     return der_put_general_string(p, len, str, size);
1100 }
1101
1102 int
1103 der_put_printable_string (unsigned char *p, size_t len,
1104                           const heim_printable_string *str, size_t *size)
1105 {
1106     return der_put_octet_string(p, len, str, size);
1107 }
1108
1109 int
1110 der_put_ia5_string (unsigned char *p, size_t len,
1111                     const heim_ia5_string *str, size_t *size)
1112 {
1113     return der_put_octet_string(p, len, str, size);
1114 }
1115
1116 int
1117 der_put_bmp_string (unsigned char *p, size_t len,
1118                     const heim_bmp_string *data, size_t *size)
1119 {
1120     size_t i;
1121     if (len / 2 < data->length)
1122         return ASN1_OVERFLOW;
1123     p -= data->length * 2;
1124     for (i = 0; i < data->length; i++) {
1125         p[1] = (data->data[i] >> 8) & 0xff;
1126         p[2] = data->data[i] & 0xff;
1127         p += 2;
1128     }
1129     if (size) *size = data->length * 2;
1130     return 0;
1131 }
1132
1133 int
1134 der_put_universal_string (unsigned char *p, size_t len,
1135                           const heim_universal_string *data, size_t *size)
1136 {
1137     size_t i;
1138     if (len / 4 < data->length)
1139         return ASN1_OVERFLOW;
1140     p -= data->length * 4;
1141     for (i = 0; i < data->length; i++) {
1142         p[1] = (data->data[i] >> 24) & 0xff;
1143         p[2] = (data->data[i] >> 16) & 0xff;
1144         p[3] = (data->data[i] >> 8) & 0xff;
1145         p[4] = data->data[i] & 0xff;
1146         p += 4;
1147     }
1148     if (size) *size = data->length * 4;
1149     return 0;
1150 }
1151
1152 int
1153 der_put_visible_string (unsigned char *p, size_t len,
1154                          const heim_visible_string *str, size_t *size)
1155 {
1156     return der_put_general_string(p, len, str, size);
1157 }
1158
1159 int
1160 der_put_octet_string (unsigned char *p, size_t len,
1161                       const heim_octet_string *data, size_t *size)
1162 {
1163     if (len < data->length)
1164         return ASN1_OVERFLOW;
1165     p -= data->length;
1166     memcpy (p+1, data->data, data->length);
1167     *size = data->length;
1168     return 0;
1169 }
1170
1171 int
1172 der_put_heim_integer (unsigned char *p, size_t len,
1173                      const heim_integer *data, size_t *size)
1174 {
1175     unsigned char *buf = data->data;
1176     int hibitset = 0;
1177
1178     if (data->length == 0) {
1179         if (len < 1)
1180             return ASN1_OVERFLOW;
1181         *p-- = 0;
1182         if (size)
1183             *size = 1;
1184         return 0;
1185     }
1186     if (len < data->length)
1187         return ASN1_OVERFLOW;
1188
1189     len -= data->length;
1190
1191     if (data->negative) {
1192         ssize_t i;
1193         int carry;
1194         for (i = data->length - 1, carry = 1; i >= 0; i--) {
1195             *p = buf[i] ^ 0xff;
1196             if (carry)
1197                 carry = !++*p;
1198             p--;
1199         }
1200         if (p[1] < 128) {
1201             if (len < 1)
1202                 return ASN1_OVERFLOW;
1203             *p-- = 0xff;
1204             len--;
1205             hibitset = 1;
1206         }
1207     } else {
1208         p -= data->length;
1209         memcpy(p + 1, buf, data->length);
1210
1211         if (p[1] >= 128) {
1212             if (len < 1)
1213                 return ASN1_OVERFLOW;
1214             p[0] = 0;
1215             len--;
1216             hibitset = 1;
1217         }
1218     }
1219     if (size)
1220         *size = data->length + hibitset;
1221     return 0;
1222 }
1223
1224 int
1225 der_put_generalized_time (unsigned char *p, size_t len,
1226                           const time_t *data, size_t *size)
1227 {
1228     heim_octet_string k;
1229     size_t l;
1230     int e;
1231
1232     e = _heim_time2generalizedtime (*data, &k, 1);
1233     if (e)
1234         return e;
1235     e = der_put_octet_string(p, len, &k, &l);
1236     free(k.data);
1237     if(e)
1238         return e;
1239     if(size)
1240         *size = l;
1241     return 0;
1242 }
1243
1244 int
1245 der_put_utctime (unsigned char *p, size_t len,
1246                  const time_t *data, size_t *size)
1247 {
1248     heim_octet_string k;
1249     size_t l;
1250     int e;
1251
1252     e = _heim_time2generalizedtime (*data, &k, 0);
1253     if (e)
1254         return e;
1255     e = der_put_octet_string(p, len, &k, &l);
1256     free(k.data);
1257     if(e)
1258         return e;
1259     if(size)
1260         *size = l;
1261     return 0;
1262 }
1263
1264 int
1265 der_put_oid (unsigned char *p, size_t len,
1266              const heim_oid *data, size_t *size)
1267 {
1268     unsigned char *base = p;
1269     size_t n;
1270
1271     for (n = data->length - 1; n >= 2; --n) {
1272         unsigned u = data->components[n];
1273
1274         if (len < 1)
1275             return ASN1_OVERFLOW;
1276         *p-- = u % 128;
1277         u /= 128;
1278         --len;
1279         while (u > 0) {
1280             if (len < 1)
1281                 return ASN1_OVERFLOW;
1282             *p-- = 128 + u % 128;
1283             u /= 128;
1284             --len;
1285         }
1286     }
1287     if (len < 1)
1288         return ASN1_OVERFLOW;
1289     *p-- = 40 * data->components[0] + data->components[1];
1290     *size = base - p;
1291     return 0;
1292 }
1293
1294 int
1295 der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
1296              unsigned int tag, size_t *size)
1297 {
1298     if (tag <= 30) {
1299         if (len < 1)
1300             return ASN1_OVERFLOW;
1301         *p = MAKE_TAG(class, type, tag);
1302         *size = 1;
1303     } else {
1304         size_t ret = 0;
1305         unsigned int continuation = 0;
1306
1307         do {
1308             if (len < 1)
1309                 return ASN1_OVERFLOW;
1310             *p-- = tag % 128 | continuation;
1311             len--;
1312             ret++;
1313             tag /= 128;
1314             continuation = 0x80;
1315         } while(tag > 0);
1316         if (len < 1)
1317             return ASN1_OVERFLOW;
1318         *p-- = MAKE_TAG(class, type, 0x1f);
1319         ret++;
1320         *size = ret;
1321     }
1322     return 0;
1323 }
1324
1325 int
1326 der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
1327                         Der_class class, Der_type type,
1328                         unsigned int tag, size_t *size)
1329 {
1330     size_t ret = 0;
1331     size_t l;
1332     int e;
1333
1334     e = der_put_length (p, len, len_val, &l);
1335     if(e)
1336         return e;
1337     p -= l;
1338     len -= l;
1339     ret += l;
1340     e = der_put_tag (p, len, class, type, tag, &l);
1341     if(e)
1342         return e;
1343
1344     ret += l;
1345     *size = ret;
1346     return 0;
1347 }
1348
1349 int
1350 _heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
1351 {
1352      struct tm tm;
1353      const size_t len = gtimep ? 15 : 13;
1354
1355      s->data = NULL;
1356      s->length = 0;
1357      if (_der_gmtime(t, &tm) == NULL)
1358          return ASN1_BAD_TIMEFORMAT;
1359      s->data = malloc(len + 1);
1360      if (s->data == NULL)
1361          return ENOMEM;
1362      s->length = len;
1363      if (gtimep)
1364          snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
1365                    tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
1366                    tm.tm_hour, tm.tm_min, tm.tm_sec);
1367      else
1368          snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
1369                    tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
1370                    tm.tm_hour, tm.tm_min, tm.tm_sec);
1371
1372      return 0;
1373 }
1374
1375 int
1376 der_put_bit_string (unsigned char *p, size_t len,
1377                     const heim_bit_string *data, size_t *size)
1378 {
1379     size_t data_size = (data->length + 7) / 8;
1380     if (len < data_size + 1)
1381         return ASN1_OVERFLOW;
1382     p -= data_size + 1;
1383
1384     memcpy (p+2, data->data, data_size);
1385     if (data->length && (data->length % 8) != 0)
1386         p[1] = 8 - (data->length % 8);
1387     else
1388         p[1] = 0;
1389     *size = data_size + 1;
1390     return 0;
1391 }
1392
1393 int
1394 _heim_der_set_sort(const void *a1, const void *a2)
1395 {
1396     const heim_octet_string *s1 = a1, *s2 = a2;
1397     int ret;
1398
1399     ret = memcmp(s1->data, s2->data,
1400                  s1->length < s2->length ? s1->length : s2->length);
1401     if(ret)
1402         return ret;
1403     return (int)(s1->length - s2->length);
1404 }
1405 /*
1406  * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
1407  * (Royal Institute of Technology, Stockholm, Sweden).
1408  * All rights reserved.
1409  *
1410  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
1411  *
1412  * Redistribution and use in source and binary forms, with or without
1413  * modification, are permitted provided that the following conditions
1414  * are met:
1415  *
1416  * 1. Redistributions of source code must retain the above copyright
1417  *    notice, this list of conditions and the following disclaimer.
1418  *
1419  * 2. Redistributions in binary form must reproduce the above copyright
1420  *    notice, this list of conditions and the following disclaimer in the
1421  *    documentation and/or other materials provided with the distribution.
1422  *
1423  * 3. Neither the name of the Institute nor the names of its contributors
1424  *    may be used to endorse or promote products derived from this software
1425  *    without specific prior written permission.
1426  *
1427  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
1428  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1429  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1430  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
1431  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1432  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1433  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1434  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1435  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1436  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1437  * SUCH DAMAGE.
1438  */
1439
1440
1441 /* RCSID("$Id$"); */
1442
1443 void
1444 der_free_general_string (heim_general_string *str)
1445 {
1446     free(*str);
1447     *str = NULL;
1448 }
1449
1450 void
1451 der_free_integer (int *i)
1452 {
1453     *i = 0;
1454 }
1455
1456 void
1457 der_free_integer64 (int64_t *i)
1458 {
1459     *i = 0;
1460 }
1461
1462 void
1463 der_free_unsigned (unsigned *u)
1464 {
1465     *u = 0;
1466 }
1467
1468 void
1469 der_free_unsigned64 (uint64_t *u)
1470 {
1471     *u = 0;
1472 }
1473
1474 void
1475 der_free_generalized_time(time_t *t)
1476 {
1477     *t = 0;
1478 }
1479
1480 void
1481 der_free_utctime(time_t *t)
1482 {
1483     *t = 0;
1484 }
1485
1486
1487 void
1488 der_free_utf8string (heim_utf8_string *str)
1489 {
1490     free(*str);
1491     *str = NULL;
1492 }
1493
1494 void
1495 der_free_printable_string (heim_printable_string *str)
1496 {
1497     der_free_octet_string(str);
1498 }
1499
1500 void
1501 der_free_ia5_string (heim_ia5_string *str)
1502 {
1503     der_free_octet_string(str);
1504 }
1505
1506 void
1507 der_free_bmp_string (heim_bmp_string *k)
1508 {
1509     free(k->data);
1510     k->data = NULL;
1511     k->length = 0;
1512 }
1513
1514 void
1515 der_free_universal_string (heim_universal_string *k)
1516 {
1517     free(k->data);
1518     k->data = NULL;
1519     k->length = 0;
1520 }
1521
1522 void
1523 der_free_visible_string (heim_visible_string *str)
1524 {
1525     free(*str);
1526     *str = NULL;
1527 }
1528
1529 void
1530 der_free_octet_string (heim_octet_string *k)
1531 {
1532     free(k->data);
1533     k->data = NULL;
1534     k->length = 0;
1535 }
1536
1537 void
1538 der_free_heim_integer (heim_integer *k)
1539 {
1540     free(k->data);
1541     k->data = NULL;
1542     k->length = 0;
1543 }
1544
1545 void
1546 der_free_oid (heim_oid *k)
1547 {
1548     free(k->components);
1549     k->components = NULL;
1550     k->length = 0;
1551 }
1552
1553 void
1554 der_free_bit_string (heim_bit_string *k)
1555 {
1556     free(k->data);
1557     k->data = NULL;
1558     k->length = 0;
1559 }
1560 /*
1561  * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
1562  * (Royal Institute of Technology, Stockholm, Sweden).
1563  * All rights reserved.
1564  *
1565  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
1566  *
1567  * Redistribution and use in source and binary forms, with or without
1568  * modification, are permitted provided that the following conditions
1569  * are met:
1570  *
1571  * 1. Redistributions of source code must retain the above copyright
1572  *    notice, this list of conditions and the following disclaimer.
1573  *
1574  * 2. Redistributions in binary form must reproduce the above copyright
1575  *    notice, this list of conditions and the following disclaimer in the
1576  *    documentation and/or other materials provided with the distribution.
1577  *
1578  * 3. Neither the name of the Institute nor the names of its contributors
1579  *    may be used to endorse or promote products derived from this software
1580  *    without specific prior written permission.
1581  *
1582  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
1583  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1584  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1585  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
1586  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1587  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1588  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1589  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1590  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1591  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1592  * SUCH DAMAGE.
1593  */
1594
1595
1596 /* RCSID("$Id$"); */
1597
1598 size_t
1599 _heim_len_unsigned (unsigned val)
1600 {
1601     size_t ret = 0;
1602     int last_val_gt_128;
1603
1604     do {
1605         ++ret;
1606         last_val_gt_128 = (val >= 128);
1607         val /= 256;
1608     } while (val);
1609
1610     if(last_val_gt_128)
1611         ret++;
1612
1613     return ret;
1614 }
1615
1616 size_t
1617 _heim_len_unsigned64 (uint64_t val)
1618 {
1619     size_t ret = 0;
1620     int last_val_gt_128;
1621
1622     do {
1623         ++ret;
1624         last_val_gt_128 = (val >= 128);
1625         val /= 256;
1626     } while (val);
1627
1628     if(last_val_gt_128)
1629         ret++;
1630
1631     return ret;
1632 }
1633
1634 size_t
1635 _heim_len_int (int val)
1636 {
1637     unsigned char q;
1638     size_t ret = 0;
1639
1640     if (val >= 0) {
1641         do {
1642             q = val % 256;
1643             ret++;
1644             val /= 256;
1645         } while(val);
1646         if(q >= 128)
1647             ret++;
1648     } else {
1649         val = ~val;
1650         do {
1651             q = ~(val % 256);
1652             ret++;
1653             val /= 256;
1654         } while(val);
1655         if(q < 128)
1656             ret++;
1657     }
1658     return ret;
1659 }
1660
1661 size_t
1662 _heim_len_int64 (int64_t val)
1663 {
1664     unsigned char q;
1665     size_t ret = 0;
1666
1667     if (val >= 0) {
1668         do {
1669             q = val % 256;
1670             ret++;
1671             val /= 256;
1672         } while(val);
1673         if(q >= 128)
1674             ret++;
1675     } else {
1676         val = ~val;
1677         do {
1678             q = ~(val % 256);
1679             ret++;
1680             val /= 256;
1681         } while(val);
1682         if(q < 128)
1683             ret++;
1684     }
1685     return ret;
1686 }
1687
1688 static size_t
1689 len_oid (const heim_oid *oid)
1690 {
1691     size_t ret = 1;
1692     size_t n;
1693
1694     for (n = 2; n < oid->length; ++n) {
1695         unsigned u = oid->components[n];
1696
1697         do {
1698             ++ret;
1699             u /= 128;
1700         } while(u > 0);
1701     }
1702     return ret;
1703 }
1704
1705 size_t
1706 der_length_len (size_t len)
1707 {
1708     if (len < 128)
1709         return 1;
1710     else {
1711         int ret = 0;
1712         do {
1713             ++ret;
1714             len /= 256;
1715         } while (len);
1716         return ret + 1;
1717     }
1718 }
1719
1720 size_t
1721 der_length_tag(unsigned int tag)
1722 {
1723     size_t len = 0;
1724
1725     if(tag <= 30)
1726         return 1;
1727     while(tag) {
1728         tag /= 128;
1729         len++;
1730     }
1731     return len + 1;
1732 }
1733
1734 size_t
1735 der_length_integer (const int *data)
1736 {
1737     return _heim_len_int (*data);
1738 }
1739
1740 size_t
1741 der_length_integer64 (const int64_t *data)
1742 {
1743     return _heim_len_int64 (*data);
1744 }
1745
1746 size_t
1747 der_length_unsigned (const unsigned *data)
1748 {
1749     return _heim_len_unsigned(*data);
1750 }
1751
1752 size_t
1753 der_length_unsigned64 (const uint64_t *data)
1754 {
1755     return _heim_len_unsigned64(*data);
1756 }
1757
1758 size_t
1759 der_length_enumerated (const unsigned *data)
1760 {
1761   return _heim_len_int (*data);
1762 }
1763
1764 size_t
1765 der_length_general_string (const heim_general_string *data)
1766 {
1767     return strlen(*data);
1768 }
1769
1770 size_t
1771 der_length_utf8string (const heim_utf8_string *data)
1772 {
1773     return strlen(*data);
1774 }
1775
1776 size_t
1777 der_length_printable_string (const heim_printable_string *data)
1778 {
1779     return data->length;
1780 }
1781
1782 size_t
1783 der_length_ia5_string (const heim_ia5_string *data)
1784 {
1785     return data->length;
1786 }
1787
1788 size_t
1789 der_length_bmp_string (const heim_bmp_string *data)
1790 {
1791     return data->length * 2;
1792 }
1793
1794 size_t
1795 der_length_universal_string (const heim_universal_string *data)
1796 {
1797     return data->length * 4;
1798 }
1799
1800 size_t
1801 der_length_visible_string (const heim_visible_string *data)
1802 {
1803     return strlen(*data);
1804 }
1805
1806 size_t
1807 der_length_octet_string (const heim_octet_string *k)
1808 {
1809     return k->length;
1810 }
1811
1812 size_t
1813 der_length_heim_integer (const heim_integer *k)
1814 {
1815     if (k->length == 0)
1816         return 1;
1817     if (k->negative)
1818         return k->length + (((~(((unsigned char *)k->data)[0])) & 0x80) ? 0 : 1);
1819     else
1820         return k->length + ((((unsigned char *)k->data)[0] & 0x80) ? 1 : 0);
1821 }
1822
1823 size_t
1824 der_length_oid (const heim_oid *k)
1825 {
1826     return len_oid (k);
1827 }
1828
1829 size_t
1830 der_length_generalized_time (const time_t *t)
1831 {
1832     heim_octet_string k;
1833     size_t ret;
1834
1835     _heim_time2generalizedtime (*t, &k, 1);
1836     ret = k.length;
1837     free(k.data);
1838     return ret;
1839 }
1840
1841 size_t
1842 der_length_utctime (const time_t *t)
1843 {
1844     heim_octet_string k;
1845     size_t ret;
1846
1847     _heim_time2generalizedtime (*t, &k, 0);
1848     ret = k.length;
1849     free(k.data);
1850     return ret;
1851 }
1852
1853 size_t
1854 der_length_boolean (const int *k)
1855 {
1856     return 1;
1857 }
1858
1859 size_t
1860 der_length_bit_string (const heim_bit_string *k)
1861 {
1862     return (k->length + 7) / 8 + 1;
1863 }
1864 /*
1865  * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
1866  * (Royal Institute of Technology, Stockholm, Sweden).
1867  * All rights reserved.
1868  *
1869  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
1870  *
1871  * Redistribution and use in source and binary forms, with or without
1872  * modification, are permitted provided that the following conditions
1873  * are met:
1874  *
1875  * 1. Redistributions of source code must retain the above copyright
1876  *    notice, this list of conditions and the following disclaimer.
1877  *
1878  * 2. Redistributions in binary form must reproduce the above copyright
1879  *    notice, this list of conditions and the following disclaimer in the
1880  *    documentation and/or other materials provided with the distribution.
1881  *
1882  * 3. Neither the name of the Institute nor the names of its contributors
1883  *    may be used to endorse or promote products derived from this software
1884  *    without specific prior written permission.
1885  *
1886  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
1887  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1888  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1889  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
1890  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1891  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1892  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1893  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1894  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1895  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1896  * SUCH DAMAGE.
1897  */
1898
1899
1900 /* RCSID("$Id$"); */
1901
1902 int
1903 der_copy_general_string (const heim_general_string *from,
1904                          heim_general_string *to)
1905 {
1906     *to = strdup(*from);
1907     if(*to == NULL)
1908         return ENOMEM;
1909     return 0;
1910 }
1911
1912 int
1913 der_copy_integer (const int *from, int *to)
1914 {
1915     *to = *from;
1916     return 0;
1917 }
1918
1919 int
1920 der_copy_integer64 (const int64_t *from, int64_t *to)
1921 {
1922     *to = *from;
1923     return 0;
1924 }
1925
1926 int
1927 der_copy_unsigned (const unsigned *from, unsigned *to)
1928 {
1929     *to = *from;
1930     return 0;
1931 }
1932
1933 int
1934 der_copy_unsigned64 (const uint64_t *from, uint64_t *to)
1935 {
1936     *to = *from;
1937     return 0;
1938 }
1939
1940 int
1941 der_copy_generalized_time (const time_t *from, time_t *to)
1942 {
1943     *to = *from;
1944     return 0;
1945 }
1946
1947 int
1948 der_copy_utctime (const time_t *from, time_t *to)
1949 {
1950     *to = *from;
1951     return 0;
1952 }
1953
1954 int
1955 der_copy_utf8string (const heim_utf8_string *from, heim_utf8_string *to)
1956 {
1957     return der_copy_general_string(from, to);
1958 }
1959
1960 int
1961 der_copy_printable_string (const heim_printable_string *from,
1962                        heim_printable_string *to)
1963 {
1964     to->length = from->length;
1965     to->data   = malloc(to->length + 1);
1966     if(to->data == NULL)
1967         return ENOMEM;
1968     memcpy(to->data, from->data, to->length);
1969     ((char *)to->data)[to->length] = '\0';
1970     return 0;
1971 }
1972
1973 int
1974 der_copy_ia5_string (const heim_ia5_string *from,
1975                      heim_ia5_string *to)
1976 {
1977     return der_copy_printable_string(from, to);
1978 }
1979
1980 int
1981 der_copy_bmp_string (const heim_bmp_string *from, heim_bmp_string *to)
1982 {
1983     to->length = from->length;
1984     to->data   = malloc(to->length * sizeof(to->data[0]));
1985     if(to->length != 0 && to->data == NULL)
1986         return ENOMEM;
1987     memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
1988     return 0;
1989 }
1990
1991 int
1992 der_copy_universal_string (const heim_universal_string *from,
1993                            heim_universal_string *to)
1994 {
1995     to->length = from->length;
1996     to->data   = malloc(to->length * sizeof(to->data[0]));
1997     if(to->length != 0 && to->data == NULL)
1998         return ENOMEM;
1999     memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
2000     return 0;
2001 }
2002
2003 int
2004 der_copy_visible_string (const heim_visible_string *from,
2005                          heim_visible_string *to)
2006 {
2007     return der_copy_general_string(from, to);
2008 }
2009
2010 int
2011 der_copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
2012 {
2013     to->length = from->length;
2014     to->data   = malloc(to->length);
2015     if(to->length != 0 && to->data == NULL)
2016         return ENOMEM;
2017     memcpy(to->data, from->data, to->length);
2018     return 0;
2019 }
2020
2021 int
2022 der_copy_heim_integer (const heim_integer *from, heim_integer *to)
2023 {
2024     to->length = from->length;
2025     to->data   = malloc(to->length);
2026     if(to->length != 0 && to->data == NULL)
2027         return ENOMEM;
2028     memcpy(to->data, from->data, to->length);
2029     to->negative = from->negative;
2030     return 0;
2031 }
2032
2033 int
2034 der_copy_oid (const heim_oid *from, heim_oid *to)
2035 {
2036     to->length     = from->length;
2037     to->components = malloc(to->length * sizeof(*to->components));
2038     if (to->length != 0 && to->components == NULL)
2039         return ENOMEM;
2040     memcpy(to->components, from->components,
2041            to->length * sizeof(*to->components));
2042     return 0;
2043 }
2044
2045 int
2046 der_copy_bit_string (const heim_bit_string *from, heim_bit_string *to)
2047 {
2048     size_t len;
2049
2050     len = (from->length + 7) / 8;
2051     to->length = from->length;
2052     to->data   = malloc(len);
2053     if(len != 0 && to->data == NULL)
2054         return ENOMEM;
2055     memcpy(to->data, from->data, len);
2056     return 0;
2057 }