From: Harald Hoyer Date: Fri, 2 Nov 2018 09:38:43 +0000 (+0100) Subject: trust/extract-jks.c: also honor SOURCE_DATE_EPOCH time X-Git-Tag: 0.23.15~16 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e81f6af7ed3b39b8df0bb7ce150619ea8178d47c;p=p11-kit trust/extract-jks.c: also honor SOURCE_DATE_EPOCH time For reproducible builds, accept a define timestamp for the java keystore. See https://reproducible-builds.org/docs/source-date-epoch/ --- diff --git a/trust/extract-jks.c b/trust/extract-jks.c index e1f1340..33554df 100644 --- a/trust/extract-jks.c +++ b/trust/extract-jks.c @@ -48,6 +48,8 @@ #include #include #include +#include +#include time_t _p11_extract_jks_timestamp = 0; @@ -247,10 +249,38 @@ prepare_jks_buffer (p11_enumerate *ex, * when this was this certificate was added to the keystore, however * we don't have that information. Java uses time in milliseconds */ - if (_p11_extract_jks_timestamp) - now = _p11_extract_jks_timestamp; - else - now = time (NULL); + { + char *source_date_epoch; + source_date_epoch = secure_getenv ("SOURCE_DATE_EPOCH"); + if (source_date_epoch) { + unsigned long long epoch; + char *endptr; + errno = 0; + epoch = strtoull (source_date_epoch, &endptr, 10); + if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) + || (errno != 0 && epoch == 0)) { + p11_message_err (errno, "Environment variable $SOURCE_DATE_EPOCH: strtoull"); + return false; + } + if (endptr == source_date_epoch) { + fprintf (stderr, "Environment variable $SOURCE_DATE_EPOCH: No digits were found: %s\n", endptr); + return false; + } + if (*endptr != '\0') { + fprintf (stderr, "Environment variable $SOURCE_DATE_EPOCH: Trailing garbage: %s\n", endptr); + return false; + } + if (epoch > ULONG_MAX) { + fprintf (stderr, "Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to %lu but was found to be: %llu \n", ULONG_MAX, epoch); + return false; + } + now = epoch; + } else if (_p11_extract_jks_timestamp) + now = _p11_extract_jks_timestamp; + else + now = time (NULL); + } + return_val_if_fail (now > 0, false); now *= 1000; /* seconds to milliseconds */