FreeBSD does not provide a global timezone variable containing the
offset to UTC. Instead, FreeBSD's libc includes a legacy timezone
function dating back to Version 7 AT&T UNIX. As a result,
asn1_string_to_time_t currently fails to compile on FreeBSD as it
subtracts a function from a time_t value:
../crypto/asn1/a_time.c:625:37: error: invalid operands to binary expression ('time_t' (aka 'long') and 'char *(int, int)')
timestamp_utc = timestamp_local - timezone;
~~~~~~~~~~~~~~~ ^ ~~~~~~~~
1 error generated.
However, FreeBSD's libc does include a non-standard (but widely
available) timegm function which converts a struct tm directly to a
UTC time_t value. Use this on FreeBSD instead of mktime.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17765)
# define timezone _timezone
#endif
+#ifdef __FreeBSD__
+# define USE_TIMEGM
+#endif
+
time_t asn1_string_to_time_t(const char *asn1_string)
{
ASN1_TIME *timestamp_asn1 = NULL;
struct tm *timestamp_tm = NULL;
+#ifndef USE_TIMEGM
time_t timestamp_local;
+#endif
time_t timestamp_utc;
timestamp_asn1 = ASN1_TIME_new();
return -1;
}
+#ifdef USE_TIMEGM
+ timestamp_utc = timegm(timestamp_tm);
+ OPENSSL_free(timestamp_tm);
+#else
timestamp_local = mktime(timestamp_tm);
OPENSSL_free(timestamp_tm);
timestamp_utc = timestamp_local - timezone;
+#endif
ASN1_TIME_free(timestamp_asn1);
return timestamp_utc;