summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Klyubin <klyubin@google.com>2015-06-23 09:44:45 -0700
committerAlex Klyubin <klyubin@google.com>2015-06-23 11:14:32 -0700
commit53752414eab95d31d76db4bb088ac1d5499b5aae (patch)
tree23934b1a1531e080f44fbd26c452932b12a6d0b5
parent9221bff2f13451ef330135bb32ea96de2a8b09cc (diff)
downloadandroid_system_security-53752414eab95d31d76db4bb088ac1d5499b5aae.tar.gz
android_system_security-53752414eab95d31d76db4bb088ac1d5499b5aae.tar.bz2
android_system_security-53752414eab95d31d76db4bb088ac1d5499b5aae.zip
Fully support uint64 key validity dates.
This fixes the issue where, on 32-bit platforms, keys expiring after about 2^31 - 1 seconds since epoch (Jan 19 2038) might be treated as already expired. The issue was caused by using time_t (signed 32-bit on 32-bit platforms) as current time and downcasting uint64 activation and expiration time instants to time_t to compare them to current time. This downcasting could make future time instants appear to be in the past on 32-bit platforms. Bug: 22015107 Change-Id: Iae12019c3c019beb92d791fda80b622fa5c4ac4e
-rw-r--r--keystore/keystore_keymaster_enforcement.h35
1 files changed, 29 insertions, 6 deletions
diff --git a/keystore/keystore_keymaster_enforcement.h b/keystore/keystore_keymaster_enforcement.h
index 904bf66..f7703eb 100644
--- a/keystore/keystore_keymaster_enforcement.h
+++ b/keystore/keystore_keymaster_enforcement.h
@@ -38,15 +38,38 @@ class KeystoreKeymasterEnforcement : public keymaster::KeymasterEnforcement {
}
bool activation_date_valid(uint64_t activation_date) const override {
- // Convert java date to time_t, non-portably.
- time_t activation_time = activation_date / 1000;
- return difftime(time(NULL), activation_time) >= 0;
+ time_t now = time(NULL);
+ if (now == static_cast<time_t>(-1)) {
+ // Failed to obtain current time -- fail safe: activation_date hasn't yet occurred.
+ return false;
+ } else if (now < 0) {
+ // Current time is prior to start of the epoch -- activation_date hasn't yet occurred.
+ return false;
+ }
+
+ // time(NULL) returns seconds since epoch and "loses" milliseconds information. We thus add
+ // 999 ms to now_date to avoid a situation where an activation_date of up to 999ms in the
+ // past may still be considered to still be in the future. This can be removed once
+ // time(NULL) is replaced by a millisecond-precise source of time.
+ uint64_t now_date = static_cast<uint64_t>(now) * 1000 + 999;
+ return now_date >= activation_date;
}
bool expiration_date_passed(uint64_t expiration_date) const override {
- // Convert jave date to time_t, non-portably.
- time_t expiration_time = expiration_date / 1000;
- return difftime(time(NULL), expiration_time) > 0;
+ time_t now = time(NULL);
+ if (now == static_cast<time_t>(-1)) {
+ // Failed to obtain current time -- fail safe: expiration_date has passed.
+ return true;
+ } else if (now < 0) {
+ // Current time is prior to start of the epoch: expiration_date hasn't yet occurred.
+ return false;
+ }
+
+ // time(NULL) returns seconds since epoch and "loses" milliseconds information. As a result,
+ // expiration_date of up to 999 ms in the past may still be considered in the future. This
+ // is OK.
+ uint64_t now_date = static_cast<uint64_t>(now) * 1000;
+ return now_date > expiration_date;
}
bool auth_token_timed_out(const hw_auth_token_t&, uint32_t) const {