7b7e67bb8fb369b4f7b92922ebbd2591a914d837
[openafs.git] / src / rxkad / v5der.c
1 #include "asn1_err.h"
2 #include <errno.h>
3 /*
4  * Copyright (c) 1997 - 2002 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("Heimdal: der_get.c,v 1.33 2002/09/03 16:21:49 nectar Exp $"); */
38
39
40 /* 
41  * All decoding functions take a pointer `p' to first position in
42  * which to read, from the left, `len' which means the maximum number
43  * of characters we are able to read, `ret' were the value will be
44  * returned and `size' where the number of used bytes is stored.
45  * Either 0 or an error code is returned.
46  */
47
48 static int
49 der_get_unsigned(const unsigned char *p, size_t len, unsigned *ret,
50                  size_t * size)
51 {
52     unsigned val = 0;
53     size_t oldlen = len;
54
55     while (len--)
56         val = val * 256 + *p++;
57     *ret = val;
58     if (size)
59         *size = oldlen;
60     return 0;
61 }
62
63 int
64 der_get_int(const unsigned char *p, size_t len, int *ret, size_t * size)
65 {
66     int val = 0;
67     size_t oldlen = len;
68
69     if (len > 0) {
70         val = (signed char)*p++;
71         while (--len)
72             val = val * 256 + *p++;
73     }
74     *ret = val;
75     if (size)
76         *size = oldlen;
77     return 0;
78 }
79
80 int
81 der_get_length(const unsigned char *p, size_t len, size_t * val,
82                size_t * size)
83 {
84     size_t v;
85
86     if (len <= 0)
87         return ASN1_OVERRUN;
88     --len;
89     v = *p++;
90     if (v < 128) {
91         *val = v;
92         if (size)
93             *size = 1;
94     } else {
95         int e;
96         size_t l;
97         unsigned tmp;
98
99         if (v == 0x80) {
100             *val = ASN1_INDEFINITE;
101             if (size)
102                 *size = 1;
103             return 0;
104         }
105         v &= 0x7F;
106         if (len < v)
107             return ASN1_OVERRUN;
108         e = der_get_unsigned(p, v, &tmp, &l);
109         if (e)
110             return e;
111         *val = tmp;
112         if (size)
113             *size = l + 1;
114     }
115     return 0;
116 }
117
118 int
119 der_get_general_string(const unsigned char *p, size_t len,
120                        general_string * str, size_t * size)
121 {
122     char *s;
123
124     s = malloc(len + 1);
125     if (s == NULL)
126         return ENOMEM;
127     memcpy(s, p, len);
128     s[len] = '\0';
129     *str = s;
130     if (size)
131         *size = len;
132     return 0;
133 }
134
135 int
136 der_get_octet_string(const unsigned char *p, size_t len, octet_string * data,
137                      size_t * size)
138 {
139     data->length = len;
140     data->data = malloc(len);
141     if (data->data == NULL && data->length != 0)
142         return ENOMEM;
143     memcpy(data->data, p, len);
144     if (size)
145         *size = len;
146     return 0;
147 }
148
149 int
150 der_get_oid(const unsigned char *p, size_t len, oid * data, size_t * size)
151 {
152     int n;
153     size_t oldlen = len;
154
155     if (len < 1)
156         return ASN1_OVERRUN;
157
158     data->components = malloc(len * sizeof(*data->components));
159     if (data->components == NULL && len != 0)
160         return ENOMEM;
161     data->components[0] = (*p) / 40;
162     data->components[1] = (*p) % 40;
163     --len;
164     ++p;
165     for (n = 2; len > 0; ++n) {
166         unsigned u = 0;
167
168         do {
169             --len;
170             u = u * 128 + (*p++ % 128);
171         } while (len > 0 && p[-1] & 0x80);
172         data->components[n] = u;
173     }
174     if (p[-1] & 0x80) {
175         free_oid(data);
176         return ASN1_OVERRUN;
177     }
178     data->length = n;
179     if (size)
180         *size = oldlen;
181     return 0;
182 }
183
184 int
185 der_get_tag(const unsigned char *p, size_t len, Der_class * class,
186             Der_type * type, int *tag, size_t * size)
187 {
188     if (len < 1)
189         return ASN1_OVERRUN;
190     *class = (Der_class) (((*p) >> 6) & 0x03);
191     *type = (Der_type) (((*p) >> 5) & 0x01);
192     *tag = (*p) & 0x1F;
193     if (size)
194         *size = 1;
195     return 0;
196 }
197
198 int
199 der_match_tag(const unsigned char *p, size_t len, Der_class class,
200               Der_type type, int tag, size_t * size)
201 {
202     size_t l;
203     Der_class thisclass;
204     Der_type thistype;
205     int thistag;
206     int e;
207
208     e = der_get_tag(p, len, &thisclass, &thistype, &thistag, &l);
209     if (e)
210         return e;
211     if (class != thisclass || type != thistype)
212         return ASN1_BAD_ID;
213     if (tag > thistag)
214         return ASN1_MISPLACED_FIELD;
215     if (tag < thistag)
216         return ASN1_MISSING_FIELD;
217     if (size)
218         *size = l;
219     return 0;
220 }
221
222 int
223 der_match_tag_and_length(const unsigned char *p, size_t len, Der_class class,
224                          Der_type type, int tag, size_t * length_ret,
225                          size_t * size)
226 {
227     size_t l, ret = 0;
228     int e;
229
230     e = der_match_tag(p, len, class, type, tag, &l);
231     if (e)
232         return e;
233     p += l;
234     len -= l;
235     ret += l;
236     e = der_get_length(p, len, length_ret, &l);
237     if (e)
238         return e;
239     p += l;
240     len -= l;
241     ret += l;
242     if (size)
243         *size = ret;
244     return 0;
245 }
246
247 int
248 decode_integer(const unsigned char *p, size_t len, int *num, size_t * size)
249 {
250     size_t ret = 0;
251     size_t l, reallen;
252     int e;
253
254     e = der_match_tag(p, len, UNIV, PRIM, UT_Integer, &l);
255     if (e)
256         return e;
257     p += l;
258     len -= l;
259     ret += l;
260     e = der_get_length(p, len, &reallen, &l);
261     if (e)
262         return e;
263     p += l;
264     len -= l;
265     ret += l;
266     if (reallen > len)
267         return ASN1_OVERRUN;
268     e = der_get_int(p, reallen, num, &l);
269     if (e)
270         return e;
271     p += l;
272     len -= l;
273     ret += l;
274     if (size)
275         *size = ret;
276     return 0;
277 }
278
279 int
280 decode_unsigned(const unsigned char *p, size_t len, unsigned *num,
281                 size_t * size)
282 {
283     size_t ret = 0;
284     size_t l, reallen;
285     int e;
286
287     e = der_match_tag(p, len, UNIV, PRIM, UT_Integer, &l);
288     if (e)
289         return e;
290     p += l;
291     len -= l;
292     ret += l;
293     e = der_get_length(p, len, &reallen, &l);
294     if (e)
295         return e;
296     p += l;
297     len -= l;
298     ret += l;
299     if (reallen > len)
300         return ASN1_OVERRUN;
301     e = der_get_unsigned(p, reallen, num, &l);
302     if (e)
303         return e;
304     p += l;
305     len -= l;
306     ret += l;
307     if (size)
308         *size = ret;
309     return 0;
310 }
311
312 int
313 decode_enumerated(const unsigned char *p, size_t len, unsigned *num,
314                   size_t * size)
315 {
316     size_t ret = 0;
317     size_t l, reallen;
318     int e;
319
320     e = der_match_tag(p, len, UNIV, PRIM, UT_Enumerated, &l);
321     if (e)
322         return e;
323     p += l;
324     len -= l;
325     ret += l;
326     e = der_get_length(p, len, &reallen, &l);
327     if (e)
328         return e;
329     p += l;
330     len -= l;
331     ret += l;
332     e = der_get_unsigned(p, reallen, num, &l);
333     if (e)
334         return e;
335     p += l;
336     len -= l;
337     ret += l;
338     if (size)
339         *size = ret;
340     return 0;
341 }
342
343 int
344 decode_general_string(const unsigned char *p, size_t len,
345                       general_string * str, size_t * size)
346 {
347     size_t ret = 0;
348     size_t l;
349     int e;
350     size_t slen;
351
352     e = der_match_tag(p, len, UNIV, PRIM, UT_GeneralString, &l);
353     if (e)
354         return e;
355     p += l;
356     len -= l;
357     ret += l;
358
359     e = der_get_length(p, len, &slen, &l);
360     if (e)
361         return e;
362     p += l;
363     len -= l;
364     ret += l;
365     if (len < slen)
366         return ASN1_OVERRUN;
367
368     e = der_get_general_string(p, slen, str, &l);
369     if (e)
370         return e;
371     p += l;
372     len -= l;
373     ret += l;
374     if (size)
375         *size = ret;
376     return 0;
377 }
378
379 int
380 decode_octet_string(const unsigned char *p, size_t len, octet_string * k,
381                     size_t * size)
382 {
383     size_t ret = 0;
384     size_t l;
385     int e;
386     size_t slen;
387
388     e = der_match_tag(p, len, UNIV, PRIM, UT_OctetString, &l);
389     if (e)
390         return e;
391     p += l;
392     len -= l;
393     ret += l;
394
395     e = der_get_length(p, len, &slen, &l);
396     if (e)
397         return e;
398     p += l;
399     len -= l;
400     ret += l;
401     if (len < slen)
402         return ASN1_OVERRUN;
403
404     e = der_get_octet_string(p, slen, k, &l);
405     if (e)
406         return e;
407     p += l;
408     len -= l;
409     ret += l;
410     if (size)
411         *size = ret;
412     return 0;
413 }
414
415 int
416 decode_oid(const unsigned char *p, size_t len, oid * k, size_t * size)
417 {
418     size_t ret = 0;
419     size_t l;
420     int e;
421     size_t slen;
422
423     e = der_match_tag(p, len, UNIV, PRIM, UT_OID, &l);
424     if (e)
425         return e;
426     p += l;
427     len -= l;
428     ret += l;
429
430     e = der_get_length(p, len, &slen, &l);
431     if (e)
432         return e;
433     p += l;
434     len -= l;
435     ret += l;
436     if (len < slen)
437         return ASN1_OVERRUN;
438
439     e = der_get_oid(p, slen, k, &l);
440     if (e)
441         return e;
442     p += l;
443     len -= l;
444     ret += l;
445     if (size)
446         *size = ret;
447     return 0;
448 }
449
450 static void
451 generalizedtime2time(const char *s, time_t * t)
452 {
453     struct tm tm;
454
455     memset(&tm, 0, sizeof(tm));
456     sscanf(s, "%04d%02d%02d%02d%02d%02dZ", &tm.tm_year, &tm.tm_mon,
457            &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
458     tm.tm_year -= 1900;
459     tm.tm_mon -= 1;
460     *t = timegm(&tm);
461 }
462
463 int
464 decode_generalized_time(const unsigned char *p, size_t len, time_t * t,
465                         size_t * size)
466 {
467     octet_string k;
468     char *times;
469     size_t ret = 0;
470     size_t l;
471     int e;
472     size_t slen;
473
474     e = der_match_tag(p, len, UNIV, PRIM, UT_GeneralizedTime, &l);
475     if (e)
476         return e;
477     p += l;
478     len -= l;
479     ret += l;
480
481     e = der_get_length(p, len, &slen, &l);
482     if (e)
483         return e;
484     p += l;
485     len -= l;
486     ret += l;
487     if (len < slen)
488         return ASN1_OVERRUN;
489     e = der_get_octet_string(p, slen, &k, &l);
490     if (e)
491         return e;
492     p += l;
493     len -= l;
494     ret += l;
495     times = realloc(k.data, k.length + 1);
496     if (times == NULL) {
497         free(k.data);
498         return ENOMEM;
499     }
500     times[k.length] = 0;
501     generalizedtime2time(times, t);
502     free(times);
503     if (size)
504         *size = ret;
505     return 0;
506 }
507
508
509 int
510 fix_dce(size_t reallen, size_t * len)
511 {
512     if (reallen == ASN1_INDEFINITE)
513         return 1;
514     if (*len < reallen)
515         return -1;
516     *len = reallen;
517     return 0;
518 }
519
520 /*
521  * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
522  * (Royal Institute of Technology, Stockholm, Sweden). 
523  * All rights reserved. 
524  *
525  * Redistribution and use in source and binary forms, with or without 
526  * modification, are permitted provided that the following conditions 
527  * are met: 
528  *
529  * 1. Redistributions of source code must retain the above copyright 
530  *    notice, this list of conditions and the following disclaimer. 
531  *
532  * 2. Redistributions in binary form must reproduce the above copyright 
533  *    notice, this list of conditions and the following disclaimer in the 
534  *    documentation and/or other materials provided with the distribution. 
535  *
536  * 3. Neither the name of the Institute nor the names of its contributors 
537  *    may be used to endorse or promote products derived from this software 
538  *    without specific prior written permission. 
539  *
540  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
541  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
542  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
543  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
544  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
545  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
546  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
547  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
548  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
549  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
550  * SUCH DAMAGE. 
551  */
552
553
554 /* RCSID("Heimdal: der_put.c,v 1.27 2001/09/25 23:37:25 assar Exp $"); */
555
556 /*
557  * All encoding functions take a pointer `p' to first position in
558  * which to write, from the right, `len' which means the maximum
559  * number of characters we are able to write.  The function returns
560  * the number of characters written in `size' (if non-NULL).
561  * The return value is 0 or an error.
562  */
563
564 static int
565 der_put_unsigned(unsigned char *p, size_t len, unsigned val, size_t * size)
566 {
567     unsigned char *base = p;
568
569     if (val) {
570         while (len > 0 && val) {
571             *p-- = val % 256;
572             val /= 256;
573             --len;
574         }
575         if (val != 0)
576             return ASN1_OVERFLOW;
577         else {
578             *size = base - p;
579             return 0;
580         }
581     } else if (len < 1)
582         return ASN1_OVERFLOW;
583     else {
584         *p = 0;
585         *size = 1;
586         return 0;
587     }
588 }
589
590 int
591 der_put_int(unsigned char *p, size_t len, int val, size_t * size)
592 {
593     unsigned char *base = p;
594
595     if (val >= 0) {
596         do {
597             if (len < 1)
598                 return ASN1_OVERFLOW;
599             *p-- = val % 256;
600             len--;
601             val /= 256;
602         } while (val);
603         if (p[1] >= 128) {
604             if (len < 1)
605                 return ASN1_OVERFLOW;
606             *p-- = 0;
607             len--;
608         }
609     } else {
610         val = ~val;
611         do {
612             if (len < 1)
613                 return ASN1_OVERFLOW;
614             *p-- = ~(val % 256);
615             len--;
616             val /= 256;
617         } while (val);
618         if (p[1] < 128) {
619             if (len < 1)
620                 return ASN1_OVERFLOW;
621             *p-- = 0xff;
622             len--;
623         }
624     }
625     *size = base - p;
626     return 0;
627 }
628
629
630 int
631 der_put_length(unsigned char *p, size_t len, size_t val, size_t * size)
632 {
633     if (len < 1)
634         return ASN1_OVERFLOW;
635     if (val < 128) {
636         *p = val;
637         *size = 1;
638         return 0;
639     } else {
640         size_t l;
641         int e;
642
643         e = der_put_unsigned(p, len - 1, val, &l);
644         if (e)
645             return e;
646         p -= l;
647         *p = 0x80 | l;
648         *size = l + 1;
649         return 0;
650     }
651 }
652
653 int
654 der_put_general_string(unsigned char *p, size_t len,
655                        const general_string * str, size_t * size)
656 {
657     size_t slen = strlen(*str);
658
659     if (len < slen)
660         return ASN1_OVERFLOW;
661     p -= slen;
662     len -= slen;
663     memcpy(p + 1, *str, slen);
664     *size = slen;
665     return 0;
666 }
667
668 int
669 der_put_octet_string(unsigned char *p, size_t len, const octet_string * data,
670                      size_t * size)
671 {
672     if (len < data->length)
673         return ASN1_OVERFLOW;
674     p -= data->length;
675     len -= data->length;
676     memcpy(p + 1, data->data, data->length);
677     *size = data->length;
678     return 0;
679 }
680
681 int
682 der_put_oid(unsigned char *p, size_t len, const oid * data, size_t * size)
683 {
684     unsigned char *base = p;
685     int n;
686
687     for (n = data->length - 1; n >= 2; --n) {
688         unsigned u = data->components[n];
689
690         if (len < 1)
691             return ASN1_OVERFLOW;
692         *p-- = u % 128;
693         u /= 128;
694         --len;
695         while (u > 0) {
696             if (len < 1)
697                 return ASN1_OVERFLOW;
698             *p-- = 128 + u % 128;
699             u /= 128;
700             --len;
701         }
702     }
703     if (len < 1)
704         return ASN1_OVERFLOW;
705     *p-- = 40 * data->components[0] + data->components[1];
706     *size = base - p;
707     return 0;
708 }
709
710 int
711 der_put_tag(unsigned char *p, size_t len, Der_class class, Der_type type,
712             int tag, size_t * size)
713 {
714     if (len < 1)
715         return ASN1_OVERFLOW;
716     *p = (class << 6) | (type << 5) | tag;      /* XXX */
717     *size = 1;
718     return 0;
719 }
720
721 int
722 der_put_length_and_tag(unsigned char *p, size_t len, size_t len_val,
723                        Der_class class, Der_type type, int tag, size_t * size)
724 {
725     size_t ret = 0;
726     size_t l;
727     int e;
728
729     e = der_put_length(p, len, len_val, &l);
730     if (e)
731         return e;
732     p -= l;
733     len -= l;
734     ret += l;
735     e = der_put_tag(p, len, class, type, tag, &l);
736     if (e)
737         return e;
738     p -= l;
739     len -= l;
740     ret += l;
741     *size = ret;
742     return 0;
743 }
744
745 int
746 encode_integer(unsigned char *p, size_t len, const int *data, size_t * size)
747 {
748     int num = *data;
749     size_t ret = 0;
750     size_t l;
751     int e;
752
753     e = der_put_int(p, len, num, &l);
754     if (e)
755         return e;
756     p -= l;
757     len -= l;
758     ret += l;
759     e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_Integer, &l);
760     if (e)
761         return e;
762     p -= l;
763     len -= l;
764     ret += l;
765     *size = ret;
766     return 0;
767 }
768
769 int
770 encode_unsigned(unsigned char *p, size_t len, const unsigned *data,
771                 size_t * size)
772 {
773     unsigned num = *data;
774     size_t ret = 0;
775     size_t l;
776     int e;
777
778     e = der_put_unsigned(p, len, num, &l);
779     if (e)
780         return e;
781     p -= l;
782     len -= l;
783     ret += l;
784     e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_Integer, &l);
785     if (e)
786         return e;
787     p -= l;
788     len -= l;
789     ret += l;
790     *size = ret;
791     return 0;
792 }
793
794 int
795 encode_enumerated(unsigned char *p, size_t len, const unsigned *data,
796                   size_t * size)
797 {
798     unsigned num = *data;
799     size_t ret = 0;
800     size_t l;
801     int e;
802
803     e = der_put_int(p, len, num, &l);
804     if (e)
805         return e;
806     p -= l;
807     len -= l;
808     ret += l;
809     e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_Enumerated, &l);
810     if (e)
811         return e;
812     p -= l;
813     len -= l;
814     ret += l;
815     *size = ret;
816     return 0;
817 }
818
819 int
820 encode_general_string(unsigned char *p, size_t len,
821                       const general_string * data, size_t * size)
822 {
823     size_t ret = 0;
824     size_t l;
825     int e;
826
827     e = der_put_general_string(p, len, data, &l);
828     if (e)
829         return e;
830     p -= l;
831     len -= l;
832     ret += l;
833     e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_GeneralString, &l);
834     if (e)
835         return e;
836     p -= l;
837     len -= l;
838     ret += l;
839     *size = ret;
840     return 0;
841 }
842
843 int
844 encode_octet_string(unsigned char *p, size_t len, const octet_string * k,
845                     size_t * size)
846 {
847     size_t ret = 0;
848     size_t l;
849     int e;
850
851     e = der_put_octet_string(p, len, k, &l);
852     if (e)
853         return e;
854     p -= l;
855     len -= l;
856     ret += l;
857     e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_OctetString, &l);
858     if (e)
859         return e;
860     p -= l;
861     len -= l;
862     ret += l;
863     *size = ret;
864     return 0;
865 }
866
867 int
868 encode_oid(unsigned char *p, size_t len, const oid * k, size_t * size)
869 {
870     size_t ret = 0;
871     size_t l;
872     int e;
873
874     e = der_put_oid(p, len, k, &l);
875     if (e)
876         return e;
877     p -= l;
878     len -= l;
879     ret += l;
880     e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_OID, &l);
881     if (e)
882         return e;
883     p -= l;
884     len -= l;
885     ret += l;
886     *size = ret;
887     return 0;
888 }
889
890 int
891 time2generalizedtime(time_t t, octet_string * s)
892 {
893     struct tm *tm;
894
895     s->data = malloc(16);
896     if (s->data == NULL)
897         return ENOMEM;
898     s->length = 15;
899     tm = gmtime(&t);
900     sprintf(s->data, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900,
901             tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
902     return 0;
903 }
904
905 int
906 encode_generalized_time(unsigned char *p, size_t len, const time_t * t,
907                         size_t * size)
908 {
909     size_t ret = 0;
910     size_t l;
911     octet_string k;
912     int e;
913
914     e = time2generalizedtime(*t, &k);
915     if (e)
916         return e;
917     e = der_put_octet_string(p, len, &k, &l);
918     free(k.data);
919     if (e)
920         return e;
921     p -= l;
922     len -= l;
923     ret += l;
924     e = der_put_length_and_tag(p, len, k.length, UNIV, PRIM,
925                                UT_GeneralizedTime, &l);
926     if (e)
927         return e;
928     p -= l;
929     len -= l;
930     ret += l;
931     *size = ret;
932     return 0;
933 }
934
935 /*
936  * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
937  * (Royal Institute of Technology, Stockholm, Sweden). 
938  * All rights reserved. 
939  *
940  * Redistribution and use in source and binary forms, with or without 
941  * modification, are permitted provided that the following conditions 
942  * are met: 
943  *
944  * 1. Redistributions of source code must retain the above copyright 
945  *    notice, this list of conditions and the following disclaimer. 
946  *
947  * 2. Redistributions in binary form must reproduce the above copyright 
948  *    notice, this list of conditions and the following disclaimer in the 
949  *    documentation and/or other materials provided with the distribution. 
950  *
951  * 3. Neither the name of the Institute nor the names of its contributors 
952  *    may be used to endorse or promote products derived from this software 
953  *    without specific prior written permission. 
954  *
955  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
956  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
957  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
958  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
959  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
960  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
961  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
962  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
963  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
964  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
965  * SUCH DAMAGE. 
966  */
967
968
969 /* RCSID("Heimdal: der_free.c,v 1.8 2001/09/25 13:39:26 assar Exp $"); */
970
971 void
972 free_general_string(general_string * str)
973 {
974     free(*str);
975 }
976
977 void
978 free_octet_string(octet_string * k)
979 {
980     free(k->data);
981 }
982
983 void
984 free_oid(oid * k)
985 {
986     free(k->components);
987 }
988
989 /*
990  * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
991  * (Royal Institute of Technology, Stockholm, Sweden). 
992  * All rights reserved. 
993  *
994  * Redistribution and use in source and binary forms, with or without 
995  * modification, are permitted provided that the following conditions 
996  * are met: 
997  *
998  * 1. Redistributions of source code must retain the above copyright 
999  *    notice, this list of conditions and the following disclaimer. 
1000  *
1001  * 2. Redistributions in binary form must reproduce the above copyright 
1002  *    notice, this list of conditions and the following disclaimer in the 
1003  *    documentation and/or other materials provided with the distribution. 
1004  *
1005  * 3. Neither the name of the Institute nor the names of its contributors 
1006  *    may be used to endorse or promote products derived from this software 
1007  *    without specific prior written permission. 
1008  *
1009  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
1010  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
1011  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
1012  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
1013  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
1014  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
1015  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
1016  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
1017  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
1018  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
1019  * SUCH DAMAGE. 
1020  */
1021
1022
1023 /* RCSID("Heimdal: der_length.c,v 1.12 2001/09/25 13:39:26 assar Exp $"); */
1024
1025 static size_t
1026 len_unsigned(unsigned val)
1027 {
1028     size_t ret = 0;
1029
1030     do {
1031         ++ret;
1032         val /= 256;
1033     } while (val);
1034     return ret;
1035 }
1036
1037 static size_t
1038 len_int(int val)
1039 {
1040     size_t ret = 0;
1041
1042     if (val == 0)
1043         return 1;
1044     while (val > 255 || val < -255) {
1045         ++ret;
1046         val /= 256;
1047     }
1048     if (val != 0) {
1049         ++ret;
1050         if ((signed char)val != val)
1051             ++ret;
1052         val /= 256;
1053     }
1054     return ret;
1055 }
1056
1057 static size_t
1058 len_oid(const oid * oid)
1059 {
1060     size_t ret = 1;
1061     int n;
1062
1063     for (n = 2; n < oid->length; ++n) {
1064         unsigned u = oid->components[n];
1065
1066         ++ret;
1067         u /= 128;
1068         while (u > 0) {
1069             ++ret;
1070             u /= 128;
1071         }
1072     }
1073     return ret;
1074 }
1075
1076 size_t
1077 length_len(size_t len)
1078 {
1079     if (len < 128)
1080         return 1;
1081     else
1082         return len_unsigned(len) + 1;
1083 }
1084
1085 size_t
1086 length_integer(const int *data)
1087 {
1088     size_t len = len_int(*data);
1089
1090     return 1 + length_len(len) + len;
1091 }
1092
1093 size_t
1094 length_unsigned(const unsigned *data)
1095 {
1096     size_t len = len_unsigned(*data);
1097
1098     return 1 + length_len(len) + len;
1099 }
1100
1101 size_t
1102 length_enumerated(const unsigned *data)
1103 {
1104     size_t len = len_int(*data);
1105
1106     return 1 + length_len(len) + len;
1107 }
1108
1109 size_t
1110 length_general_string(const general_string * data)
1111 {
1112     char *str = *data;
1113     size_t len = strlen(str);
1114     return 1 + length_len(len) + len;
1115 }
1116
1117 size_t
1118 length_octet_string(const octet_string * k)
1119 {
1120     return 1 + length_len(k->length) + k->length;
1121 }
1122
1123 size_t
1124 length_oid(const oid * k)
1125 {
1126     size_t len = len_oid(k);
1127
1128     return 1 + length_len(len) + len;
1129 }
1130
1131 size_t
1132 length_generalized_time(const time_t * t)
1133 {
1134     octet_string k;
1135     size_t ret;
1136
1137     time2generalizedtime(*t, &k);
1138     ret = 1 + length_len(k.length) + k.length;
1139     free(k.data);
1140     return ret;
1141 }
1142
1143 /*
1144  * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
1145  * (Royal Institute of Technology, Stockholm, Sweden). 
1146  * All rights reserved. 
1147  *
1148  * Redistribution and use in source and binary forms, with or without 
1149  * modification, are permitted provided that the following conditions 
1150  * are met: 
1151  *
1152  * 1. Redistributions of source code must retain the above copyright 
1153  *    notice, this list of conditions and the following disclaimer. 
1154  *
1155  * 2. Redistributions in binary form must reproduce the above copyright 
1156  *    notice, this list of conditions and the following disclaimer in the 
1157  *    documentation and/or other materials provided with the distribution. 
1158  *
1159  * 3. Neither the name of the Institute nor the names of its contributors 
1160  *    may be used to endorse or promote products derived from this software 
1161  *    without specific prior written permission. 
1162  *
1163  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
1164  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
1165  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
1166  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
1167  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
1168  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
1169  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
1170  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
1171  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
1172  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
1173  * SUCH DAMAGE. 
1174  */
1175
1176
1177 /* RCSID("Heimdal: der_copy.c,v 1.9 2001/09/25 13:39:25 assar Exp $"); */
1178
1179 int
1180 copy_general_string(const general_string * from, general_string * to)
1181 {
1182     *to = malloc(strlen(*from) + 1);
1183     if (*to == NULL)
1184         return ENOMEM;
1185     strcpy(*to, *from);
1186     return 0;
1187 }
1188
1189 int
1190 copy_octet_string(const octet_string * from, octet_string * to)
1191 {
1192     to->length = from->length;
1193     to->data = malloc(to->length);
1194     if (to->length != 0 && to->data == NULL)
1195         return ENOMEM;
1196     memcpy(to->data, from->data, to->length);
1197     return 0;
1198 }
1199
1200 int
1201 copy_oid(const oid * from, oid * to)
1202 {
1203     to->length = from->length;
1204     to->components = malloc(to->length * sizeof(*to->components));
1205     if (to->length != 0 && to->components == NULL)
1206         return ENOMEM;
1207     memcpy(to->components, from->components, to->length);
1208     return 0;
1209 }
1210
1211 /*
1212  * Copyright (c) 1997 Kungliga Tekniska Högskolan
1213  * (Royal Institute of Technology, Stockholm, Sweden). 
1214  * All rights reserved. 
1215  *
1216  * Redistribution and use in source and binary forms, with or without 
1217  * modification, are permitted provided that the following conditions 
1218  * are met: 
1219  *
1220  * 1. Redistributions of source code must retain the above copyright 
1221  *    notice, this list of conditions and the following disclaimer. 
1222  *
1223  * 2. Redistributions in binary form must reproduce the above copyright 
1224  *    notice, this list of conditions and the following disclaimer in the 
1225  *    documentation and/or other materials provided with the distribution. 
1226  *
1227  * 3. Neither the name of the Institute nor the names of its contributors 
1228  *    may be used to endorse or promote products derived from this software 
1229  *    without specific prior written permission. 
1230  *
1231  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
1232  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
1233  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
1234  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
1235  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
1236  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
1237  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
1238  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
1239  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
1240  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
1241  * SUCH DAMAGE. 
1242  */
1243
1244
1245 /* RCSID("Heimdal: timegm.c,v 1.7 1999/12/02 17:05:02 joda Exp $"); */
1246
1247 #ifndef HAVE_TIMEGM
1248
1249 static int
1250 is_leap(unsigned y)
1251 {
1252     y += 1900;
1253     return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
1254 }
1255
1256 time_t
1257 timegm(struct tm * tm)
1258 {
1259     static const unsigned ndays[2][12] = {
1260         {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
1261         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
1262     };
1263     time_t res = 0;
1264     unsigned i;
1265
1266     for (i = 70; i < tm->tm_year; ++i)
1267         res += is_leap(i) ? 366 : 365;
1268
1269     for (i = 0; i < tm->tm_mon; ++i)
1270         res += ndays[is_leap(tm->tm_year)][i];
1271     res += tm->tm_mday - 1;
1272     res *= 24;
1273     res += tm->tm_hour;
1274     res *= 60;
1275     res += tm->tm_min;
1276     res *= 60;
1277     res += tm->tm_sec;
1278     return res;
1279 }
1280
1281 #endif /* HAVE_TIMEGM */