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