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