4 * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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.
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.
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
37 /* RCSID("Heimdal: der_get.c,v 1.33 2002/09/03 16:21:49 nectar Exp $"); */
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.
49 der_get_unsigned (const unsigned char *p, size_t len,
50 unsigned *ret, size_t *size)
56 val = val * 256 + *p++;
58 if(size) *size = oldlen;
63 der_get_int (const unsigned char *p, size_t len,
64 int *ret, size_t *size)
70 val = (signed char)*p++;
72 val = val * 256 + *p++;
75 if(size) *size = oldlen;
80 der_get_length (const unsigned char *p, size_t len,
81 size_t *val, size_t *size)
98 *val = ASN1_INDEFINITE;
105 e = der_get_unsigned (p, v, &tmp, &l);
108 if(size) *size = l + 1;
114 der_get_general_string (const unsigned char *p, size_t len,
115 general_string *str, size_t *size)
119 s = malloc (len + 1);
125 if(size) *size = len;
130 der_get_octet_string (const unsigned char *p, size_t len,
131 octet_string *data, size_t *size)
134 data->data = malloc(len);
135 if (data->data == NULL && data->length != 0)
137 memcpy (data->data, p, len);
138 if(size) *size = len;
143 der_get_oid (const unsigned char *p, size_t len,
144 oid *data, size_t *size)
152 data->components = malloc(len * sizeof(*data->components));
153 if (data->components == NULL && len != 0)
155 data->components[0] = (*p) / 40;
156 data->components[1] = (*p) % 40;
159 for (n = 2; len > 0; ++n) {
164 u = u * 128 + (*p++ % 128);
165 } while (len > 0 && p[-1] & 0x80);
166 data->components[n] = u;
179 der_get_tag (const unsigned char *p, size_t len,
180 Der_class *class, Der_type *type,
181 int *tag, size_t *size)
185 *class = (Der_class)(((*p) >> 6) & 0x03);
186 *type = (Der_type)(((*p) >> 5) & 0x01);
193 der_match_tag (const unsigned char *p, size_t len,
194 Der_class class, Der_type type,
195 int tag, size_t *size)
203 e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l);
205 if (class != thisclass || type != thistype)
208 return ASN1_MISPLACED_FIELD;
210 return ASN1_MISSING_FIELD;
216 der_match_tag_and_length (const unsigned char *p, size_t len,
217 Der_class class, Der_type type, int tag,
218 size_t *length_ret, size_t *size)
223 e = der_match_tag (p, len, class, type, tag, &l);
228 e = der_get_length (p, len, length_ret, &l);
233 if(size) *size = ret;
238 decode_integer (const unsigned char *p, size_t len,
239 int *num, size_t *size)
245 e = der_match_tag (p, len, UNIV, PRIM, UT_Integer, &l);
250 e = der_get_length (p, len, &reallen, &l);
257 e = der_get_int (p, reallen, num, &l);
262 if(size) *size = ret;
267 decode_unsigned (const unsigned char *p, size_t len,
268 unsigned *num, size_t *size)
274 e = der_match_tag (p, len, UNIV, PRIM, UT_Integer, &l);
279 e = der_get_length (p, len, &reallen, &l);
286 e = der_get_unsigned (p, reallen, num, &l);
291 if(size) *size = ret;
296 decode_enumerated (const unsigned char *p, size_t len,
297 unsigned *num, size_t *size)
303 e = der_match_tag (p, len, UNIV, PRIM, UT_Enumerated, &l);
308 e = der_get_length (p, len, &reallen, &l);
313 e = der_get_int (p, reallen, num, &l);
318 if(size) *size = ret;
323 decode_general_string (const unsigned char *p, size_t len,
324 general_string *str, size_t *size)
331 e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralString, &l);
337 e = der_get_length (p, len, &slen, &l);
345 e = der_get_general_string (p, slen, str, &l);
350 if(size) *size = ret;
355 decode_octet_string (const unsigned char *p, size_t len,
356 octet_string *k, size_t *size)
363 e = der_match_tag (p, len, UNIV, PRIM, UT_OctetString, &l);
369 e = der_get_length (p, len, &slen, &l);
377 e = der_get_octet_string (p, slen, k, &l);
382 if(size) *size = ret;
387 decode_oid (const unsigned char *p, size_t len,
388 oid *k, size_t *size)
395 e = der_match_tag (p, len, UNIV, PRIM, UT_OID, &l);
401 e = der_get_length (p, len, &slen, &l);
409 e = der_get_oid (p, slen, k, &l);
414 if(size) *size = ret;
419 generalizedtime2time (const char *s, time_t *t)
423 memset(&tm, 0, sizeof(tm));
424 sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
425 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
426 &tm.tm_min, &tm.tm_sec);
433 decode_generalized_time (const unsigned char *p, size_t len,
434 time_t *t, size_t *size)
443 e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralizedTime, &l);
449 e = der_get_length (p, len, &slen, &l);
456 e = der_get_octet_string (p, slen, &k, &l);
461 times = realloc(k.data, k.length + 1);
467 generalizedtime2time (times, t);
469 if(size) *size = ret;
475 fix_dce(size_t reallen, size_t *len)
477 if(reallen == ASN1_INDEFINITE)
485 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
486 * (Royal Institute of Technology, Stockholm, Sweden).
487 * All rights reserved.
489 * Redistribution and use in source and binary forms, with or without
490 * modification, are permitted provided that the following conditions
493 * 1. Redistributions of source code must retain the above copyright
494 * notice, this list of conditions and the following disclaimer.
496 * 2. Redistributions in binary form must reproduce the above copyright
497 * notice, this list of conditions and the following disclaimer in the
498 * documentation and/or other materials provided with the distribution.
500 * 3. Neither the name of the Institute nor the names of its contributors
501 * may be used to endorse or promote products derived from this software
502 * without specific prior written permission.
504 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
505 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
506 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
507 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
508 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
509 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
510 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
511 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
512 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
513 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
518 /* RCSID("Heimdal: der_put.c,v 1.27 2001/09/25 23:37:25 assar Exp $"); */
521 * All encoding functions take a pointer `p' to first position in
522 * which to write, from the right, `len' which means the maximum
523 * number of characters we are able to write. The function returns
524 * the number of characters written in `size' (if non-NULL).
525 * The return value is 0 or an error.
529 der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
531 unsigned char *base = p;
534 while (len > 0 && val) {
540 return ASN1_OVERFLOW;
546 return ASN1_OVERFLOW;
555 der_put_int (unsigned char *p, size_t len, int val, size_t *size)
557 unsigned char *base = p;
562 return ASN1_OVERFLOW;
569 return ASN1_OVERFLOW;
577 return ASN1_OVERFLOW;
584 return ASN1_OVERFLOW;
595 der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
598 return ASN1_OVERFLOW;
607 e = der_put_unsigned (p, len - 1, val, &l);
618 der_put_general_string (unsigned char *p, size_t len,
619 const general_string *str, size_t *size)
621 size_t slen = strlen(*str);
624 return ASN1_OVERFLOW;
627 memcpy (p+1, *str, slen);
633 der_put_octet_string (unsigned char *p, size_t len,
634 const octet_string *data, size_t *size)
636 if (len < data->length)
637 return ASN1_OVERFLOW;
640 memcpy (p+1, data->data, data->length);
641 *size = data->length;
646 der_put_oid (unsigned char *p, size_t len,
647 const oid *data, size_t *size)
649 unsigned char *base = p;
652 for (n = data->length - 1; n >= 2; --n) {
653 unsigned u = data->components[n];
656 return ASN1_OVERFLOW;
662 return ASN1_OVERFLOW;
663 *p-- = 128 + u % 128;
669 return ASN1_OVERFLOW;
670 *p-- = 40 * data->components[0] + data->components[1];
676 der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
677 int tag, size_t *size)
680 return ASN1_OVERFLOW;
681 *p = (class << 6) | (type << 5) | tag; /* XXX */
687 der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
688 Der_class class, Der_type type, int tag, size_t *size)
694 e = der_put_length (p, len, len_val, &l);
700 e = der_put_tag (p, len, class, type, tag, &l);
711 encode_integer (unsigned char *p, size_t len, const int *data, size_t *size)
718 e = der_put_int (p, len, num, &l);
724 e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_Integer, &l);
735 encode_unsigned (unsigned char *p, size_t len, const unsigned *data,
738 unsigned num = *data;
743 e = der_put_unsigned (p, len, num, &l);
749 e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_Integer, &l);
760 encode_enumerated (unsigned char *p, size_t len, const unsigned *data,
763 unsigned num = *data;
768 e = der_put_int (p, len, num, &l);
774 e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_Enumerated, &l);
785 encode_general_string (unsigned char *p, size_t len,
786 const general_string *data, size_t *size)
792 e = der_put_general_string (p, len, data, &l);
798 e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_GeneralString, &l);
809 encode_octet_string (unsigned char *p, size_t len,
810 const octet_string *k, size_t *size)
816 e = der_put_octet_string (p, len, k, &l);
822 e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_OctetString, &l);
833 encode_oid(unsigned char *p, size_t len,
834 const oid *k, size_t *size)
840 e = der_put_oid (p, len, k, &l);
846 e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_OID, &l);
857 time2generalizedtime (time_t t, octet_string *s)
861 s->data = malloc(16);
866 sprintf (s->data, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900,
867 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
873 encode_generalized_time (unsigned char *p, size_t len,
874 const time_t *t, size_t *size)
881 e = time2generalizedtime (*t, &k);
884 e = der_put_octet_string (p, len, &k, &l);
891 e = der_put_length_and_tag (p, len, k.length, UNIV, PRIM,
892 UT_GeneralizedTime, &l);
902 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
903 * (Royal Institute of Technology, Stockholm, Sweden).
904 * All rights reserved.
906 * Redistribution and use in source and binary forms, with or without
907 * modification, are permitted provided that the following conditions
910 * 1. Redistributions of source code must retain the above copyright
911 * notice, this list of conditions and the following disclaimer.
913 * 2. Redistributions in binary form must reproduce the above copyright
914 * notice, this list of conditions and the following disclaimer in the
915 * documentation and/or other materials provided with the distribution.
917 * 3. Neither the name of the Institute nor the names of its contributors
918 * may be used to endorse or promote products derived from this software
919 * without specific prior written permission.
921 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
922 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
923 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
924 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
925 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
926 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
927 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
928 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
929 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
930 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
935 /* RCSID("Heimdal: der_free.c,v 1.8 2001/09/25 13:39:26 assar Exp $"); */
938 free_general_string (general_string *str)
944 free_octet_string (octet_string *k)
955 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
956 * (Royal Institute of Technology, Stockholm, Sweden).
957 * All rights reserved.
959 * Redistribution and use in source and binary forms, with or without
960 * modification, are permitted provided that the following conditions
963 * 1. Redistributions of source code must retain the above copyright
964 * notice, this list of conditions and the following disclaimer.
966 * 2. Redistributions in binary form must reproduce the above copyright
967 * notice, this list of conditions and the following disclaimer in the
968 * documentation and/or other materials provided with the distribution.
970 * 3. Neither the name of the Institute nor the names of its contributors
971 * may be used to endorse or promote products derived from this software
972 * without specific prior written permission.
974 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
975 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
976 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
977 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
978 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
979 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
980 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
981 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
982 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
983 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
988 /* RCSID("Heimdal: der_length.c,v 1.12 2001/09/25 13:39:26 assar Exp $"); */
991 len_unsigned (unsigned val)
1009 while (val > 255 || val < -255) {
1015 if ((signed char)val != val)
1023 len_oid (const oid *oid)
1028 for (n = 2; n < oid->length; ++n) {
1029 unsigned u = oid->components[n];
1042 length_len (size_t len)
1047 return len_unsigned (len) + 1;
1051 length_integer (const int *data)
1053 size_t len = len_int (*data);
1055 return 1 + length_len(len) + len;
1059 length_unsigned (const unsigned *data)
1061 size_t len = len_unsigned (*data);
1063 return 1 + length_len(len) + len;
1067 length_enumerated (const unsigned *data)
1069 size_t len = len_int (*data);
1071 return 1 + length_len(len) + len;
1075 length_general_string (const general_string *data)
1078 size_t len = strlen(str);
1079 return 1 + length_len(len) + len;
1083 length_octet_string (const octet_string *k)
1085 return 1 + length_len(k->length) + k->length;
1089 length_oid (const oid *k)
1091 size_t len = len_oid (k);
1093 return 1 + length_len(len) + len;
1097 length_generalized_time (const time_t *t)
1102 time2generalizedtime (*t, &k);
1103 ret = 1 + length_len(k.length) + k.length;
1108 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
1109 * (Royal Institute of Technology, Stockholm, Sweden).
1110 * All rights reserved.
1112 * Redistribution and use in source and binary forms, with or without
1113 * modification, are permitted provided that the following conditions
1116 * 1. Redistributions of source code must retain the above copyright
1117 * notice, this list of conditions and the following disclaimer.
1119 * 2. Redistributions in binary form must reproduce the above copyright
1120 * notice, this list of conditions and the following disclaimer in the
1121 * documentation and/or other materials provided with the distribution.
1123 * 3. Neither the name of the Institute nor the names of its contributors
1124 * may be used to endorse or promote products derived from this software
1125 * without specific prior written permission.
1127 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
1128 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1129 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1130 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
1131 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1132 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1133 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1134 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1135 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1136 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1141 /* RCSID("Heimdal: der_copy.c,v 1.9 2001/09/25 13:39:25 assar Exp $"); */
1144 copy_general_string (const general_string *from, general_string *to)
1146 *to = malloc(strlen(*from) + 1);
1154 copy_octet_string (const octet_string *from, octet_string *to)
1156 to->length = from->length;
1157 to->data = malloc(to->length);
1158 if(to->length != 0 && to->data == NULL)
1160 memcpy(to->data, from->data, to->length);
1165 copy_oid (const oid *from, oid *to)
1167 to->length = from->length;
1168 to->components = malloc(to->length * sizeof(*to->components));
1169 if (to->length != 0 && to->components == NULL)
1171 memcpy(to->components, from->components, to->length);
1175 * Copyright (c) 1997 Kungliga Tekniska Högskolan
1176 * (Royal Institute of Technology, Stockholm, Sweden).
1177 * All rights reserved.
1179 * Redistribution and use in source and binary forms, with or without
1180 * modification, are permitted provided that the following conditions
1183 * 1. Redistributions of source code must retain the above copyright
1184 * notice, this list of conditions and the following disclaimer.
1186 * 2. Redistributions in binary form must reproduce the above copyright
1187 * notice, this list of conditions and the following disclaimer in the
1188 * documentation and/or other materials provided with the distribution.
1190 * 3. Neither the name of the Institute nor the names of its contributors
1191 * may be used to endorse or promote products derived from this software
1192 * without specific prior written permission.
1194 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
1195 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1196 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1197 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
1198 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1199 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1200 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1201 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1202 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1203 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1208 /* RCSID("Heimdal: timegm.c,v 1.7 1999/12/02 17:05:02 joda Exp $"); */
1216 return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
1220 timegm (struct tm *tm)
1222 static const unsigned ndays[2][12] ={
1223 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
1224 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
1228 for (i = 70; i < tm->tm_year; ++i)
1229 res += is_leap(i) ? 366 : 365;
1231 for (i = 0; i < tm->tm_mon; ++i)
1232 res += ndays[is_leap(tm->tm_year)][i];
1233 res += tm->tm_mday - 1;
1243 #endif /* HAVE_TIMEGM */