mirror of https://github.com/getdnsapi/getdns.git
Remove dependency on timegm() when using OpenSSL < 1.0.2.
Convert dates to Julian and diff. This is basically what ASN1_TIME_diff() does internally. And that's quite enough near-pointless polishing here.
This commit is contained in:
parent
00c17dca14
commit
add818fea2
|
@ -128,7 +128,33 @@ static const char *rcode_text(int rcode)
|
||||||
return text[rcode];
|
return text[rcode];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Thanks to:
|
#if OPENSSL_VERSION_NUMBER < 0x10002000
|
||||||
|
/*
|
||||||
|
* Convert date to Julian day.
|
||||||
|
* See https://en.wikipedia.org/wiki/Julian_day
|
||||||
|
*/
|
||||||
|
static long julian_day(const struct tm *tm)
|
||||||
|
{
|
||||||
|
long dd, mm, yyyy;
|
||||||
|
|
||||||
|
dd = tm->tm_mday;
|
||||||
|
mm = tm->tm_mon + 1;
|
||||||
|
yyyy = tm->tm_year + 1900;
|
||||||
|
|
||||||
|
return (1461 * (yyyy + 4800 + (mm - 14) / 12)) / 4 +
|
||||||
|
(367 * (mm - 2 - 12 * ((mm - 14) / 12))) / 12 -
|
||||||
|
(3 * ((yyyy + 4900 + (mm - 14) / 12) / 100)) / 4 +
|
||||||
|
dd - 32075;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long secs_in_day(const struct tm *tm)
|
||||||
|
{
|
||||||
|
return ((tm->tm_hour * 60) + tm->tm_min) * 60 + tm->tm_sec;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Thanks to:
|
||||||
* https://zakird.com/2013/10/13/certificate-parsing-with-openssl
|
* https://zakird.com/2013/10/13/certificate-parsing-with-openssl
|
||||||
*/
|
*/
|
||||||
static bool extract_cert_expiry(const unsigned char *data, size_t len, time_t *t)
|
static bool extract_cert_expiry(const unsigned char *data, size_t len, time_t *t)
|
||||||
|
@ -137,8 +163,12 @@ static bool extract_cert_expiry(const unsigned char *data, size_t len, time_t *t
|
||||||
if (!cert)
|
if (!cert)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
int day_diff, sec_diff;
|
||||||
|
const long SECS_IN_DAY = 60 * 60 * 24;
|
||||||
ASN1_TIME *not_after = X509_get_notAfter(cert);
|
ASN1_TIME *not_after = X509_get_notAfter(cert);
|
||||||
|
|
||||||
|
*t = time(NULL);
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10002000
|
#if OPENSSL_VERSION_NUMBER < 0x10002000
|
||||||
/*
|
/*
|
||||||
* OpenSSL before 1.0.2 does not support ASN1_TIME_diff().
|
* OpenSSL before 1.0.2 does not support ASN1_TIME_diff().
|
||||||
|
@ -147,8 +177,9 @@ static bool extract_cert_expiry(const unsigned char *data, size_t len, time_t *t
|
||||||
* but 'Mar 15 11:58:50 2018 GMT'. Note the month name is not
|
* but 'Mar 15 11:58:50 2018 GMT'. Note the month name is not
|
||||||
* locale-dependent but always English, so strptime() to parse
|
* locale-dependent but always English, so strptime() to parse
|
||||||
* isn't going to work. It also *appears* to always end 'GMT'.
|
* isn't going to work. It also *appears* to always end 'GMT'.
|
||||||
* timegm() is a glibc-ism, but there is no sensible
|
* Ideally one could then convert this UTC time to a time_t, but
|
||||||
* alternative. Patches welcome...
|
* there's no way to do that in standard C/POSIX. So follow the
|
||||||
|
* lead of OpenSSL, convert to Julian days and use the difference.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char buf[40];
|
char buf[40];
|
||||||
|
@ -194,21 +225,25 @@ static bool extract_cert_expiry(const unsigned char *data, size_t len, time_t *t
|
||||||
if (tm.tm_mon > 11)
|
if (tm.tm_mon > 11)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*t = timegm(&tm);
|
struct tm tm_now;
|
||||||
return true;
|
gmtime_r(t, &tm_now);
|
||||||
|
|
||||||
|
day_diff = julian_day(&tm) - julian_day(&tm_now);
|
||||||
|
sec_diff = secs_in_day(&tm) - secs_in_day(&tm_now);
|
||||||
|
if (sec_diff < 0) {
|
||||||
|
sec_diff += SECS_IN_DAY;
|
||||||
|
--day_diff;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* Use ASN1_TIME_diff to get a time delta between now and expiry.
|
* Use ASN1_TIME_diff to get a time delta between now and expiry.
|
||||||
* This is much easier than trying to parse the time.
|
* This is much easier than trying to parse the time.
|
||||||
*/
|
*/
|
||||||
int day, sec;
|
ASN1_TIME_diff(&day_diff, &sec_diff, NULL, not_after);
|
||||||
*t = time(NULL);
|
|
||||||
ASN1_TIME_diff(&day, &sec, NULL, not_after);
|
|
||||||
*t += day * 86400 + sec;
|
|
||||||
|
|
||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
return true;
|
|
||||||
#endif
|
#endif
|
||||||
|
*t += day_diff * SECS_IN_DAY + sec_diff;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exit_tidy()
|
static void exit_tidy()
|
||||||
|
|
Loading…
Reference in New Issue