summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/asn1/timegm.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/asn1/timegm.c')
-rw-r--r--source4/heimdal/lib/asn1/timegm.c62
1 files changed, 53 insertions, 9 deletions
diff --git a/source4/heimdal/lib/asn1/timegm.c b/source4/heimdal/lib/asn1/timegm.c
index 83f0e33fb8..b569478413 100644
--- a/source4/heimdal/lib/asn1/timegm.c
+++ b/source4/heimdal/lib/asn1/timegm.c
@@ -42,6 +42,10 @@ is_leap(unsigned y)
return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
}
+static const unsigned ndays[2][12] ={
+ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+ {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
+
/*
* This is a simplifed version of timegm(3) that doesn't accept out of
* bound values that timegm(3) normally accepts but those are not
@@ -51,9 +55,8 @@ is_leap(unsigned y)
time_t
_der_timegm (struct tm *tm)
{
- static const unsigned ndays[2][12] ={
- {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
- {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
+ time_t res = 0;
+ unsigned i;
if (tm->tm_year < 0)
return -1;
@@ -68,10 +71,51 @@ _der_timegm (struct tm *tm)
if (tm->tm_sec < 0 || tm->tm_sec > 59)
return -1;
- /* now call to the libc timegm(). This code used to do the
- * calculation itself, but that calculation didn't account for the
- * difference between UTC and GMT, which is 24 seconds in 2010. That
- * caused a mutual authentication failure
- */
- return timegm(tm);
+ for (i = 70; i < tm->tm_year; ++i)
+ res += is_leap(i) ? 366 : 365;
+
+ for (i = 0; i < tm->tm_mon; ++i)
+ res += ndays[is_leap(tm->tm_year)][i];
+ res += tm->tm_mday - 1;
+ res *= 24;
+ res += tm->tm_hour;
+ res *= 60;
+ res += tm->tm_min;
+ res *= 60;
+ res += tm->tm_sec;
+ return res;
+}
+
+struct tm *
+_der_gmtime(time_t t, struct tm *tm)
+{
+ time_t secday = t % (3600 * 24);
+ time_t days = t / (3600 * 24);
+
+ memset(tm, 0, sizeof(*tm));
+
+ tm->tm_sec = secday % 60;
+ tm->tm_min = (secday % 3600) / 60;
+ tm->tm_hour = secday / 3600;
+
+ tm->tm_year = 70;
+ while(1) {
+ unsigned dayinyear = (is_leap(tm->tm_year) ? 366 : 365);
+ if (days < dayinyear)
+ break;
+ tm->tm_year += 1;
+ days -= dayinyear;
+ }
+ tm->tm_mon = 0;
+
+ while (1) {
+ unsigned daysinmonth = ndays[is_leap(tm->tm_year)][tm->tm_mon];
+ if (days < daysinmonth)
+ break;
+ days -= daysinmonth;
+ tm->tm_mon++;
+ }
+ tm->tm_mday = days + 1;
+
+ return tm;
}