summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/asn1
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-10-02 16:32:56 +1000
committerAndrew Bartlett <abartlet@samba.org>2010-10-03 01:15:04 +0000
commit21460dfc14acdeef69b6cd910da80f261316be63 (patch)
treefcc7b9c9b03331ae6a1117a9688fc957868e942b /source4/heimdal/lib/asn1
parenta2c4f54dfb47fa73c12ba305d52574aeb6baedd9 (diff)
downloadsamba-21460dfc14acdeef69b6cd910da80f261316be63.tar.gz
samba-21460dfc14acdeef69b6cd910da80f261316be63.tar.bz2
samba-21460dfc14acdeef69b6cd910da80f261316be63.zip
s4:heimdal: import lorikeet-heimdal-201010022046 (commit 1bea031b9404b14114b0272ecbe56e60c567af5c)
Diffstat (limited to 'source4/heimdal/lib/asn1')
-rw-r--r--source4/heimdal/lib/asn1/der_locl.h1
-rw-r--r--source4/heimdal/lib/asn1/der_put.c12
-rw-r--r--source4/heimdal/lib/asn1/timegm.c62
3 files changed, 60 insertions, 15 deletions
diff --git a/source4/heimdal/lib/asn1/der_locl.h b/source4/heimdal/lib/asn1/der_locl.h
index 0f65c50a22..a086e18fa4 100644
--- a/source4/heimdal/lib/asn1/der_locl.h
+++ b/source4/heimdal/lib/asn1/der_locl.h
@@ -56,6 +56,7 @@
#include "asn1-template.h"
time_t _der_timegm (struct tm *);
+struct tm * _der_gmtime(time_t t, struct tm *);
size_t _heim_len_unsigned (unsigned);
size_t _heim_len_int (int);
diff --git a/source4/heimdal/lib/asn1/der_put.c b/source4/heimdal/lib/asn1/der_put.c
index c8192f25fe..b8101458ad 100644
--- a/source4/heimdal/lib/asn1/der_put.c
+++ b/source4/heimdal/lib/asn1/der_put.c
@@ -426,22 +426,22 @@ der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
int
_heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
{
- struct tm *tm;
+ struct tm tm;
const size_t len = gtimep ? 15 : 13;
s->data = malloc(len + 1);
if (s->data == NULL)
return ENOMEM;
s->length = len;
- tm = gmtime (&t);
+ _der_gmtime(t, &tm);
if (gtimep)
snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
else
snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
- tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
return 0;
}
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;
}