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