Import Upstream version 1.8.5
[hcoop/debian/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 }