Skip to content

Commit 473c712

Browse files
committed
Add getmtime to Android KeyStore API
java.security.KeyStore requires that you be able to get the creation date for any given entry. We'll approximate that through using the mtime of the file in the keystore. Change-Id: I16f74354a6c2e78a1a0b4dc2ae720c5391274e6f
1 parent bc11e52 commit 473c712

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

keystore/java/android/security/KeyStore.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.nio.charset.Charsets;
2727
import java.nio.charset.ModifiedUtf8;
2828
import java.util.ArrayList;
29+
import java.util.Date;
2930

3031
/**
3132
* @hide This should not be made public in its present form because it
@@ -228,6 +229,23 @@ public boolean ungrant(String key, int uid) {
228229
return ungrant(getKeyBytes(key), getUidBytes(uid));
229230
}
230231

232+
private long getmtime(byte[] key) {
233+
final ArrayList<byte[]> values = execute('c', key);
234+
if (values == null || values.isEmpty()) {
235+
return -1L;
236+
}
237+
238+
return Long.parseLong(new String(values.get(0))) * 1000L;
239+
}
240+
241+
/**
242+
* Returns the last modification time of the key in milliseconds since the
243+
* epoch. Will return -1L if the key could not be found or other error.
244+
*/
245+
public long getmtime(String key) {
246+
return getmtime(getKeyBytes(key));
247+
}
248+
231249
public int getLastError() {
232250
return mError;
233251
}

keystore/tests/src/android/security/KeyStoreTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
import android.app.Activity;
2020
import android.security.KeyStore;
2121
import android.test.ActivityUnitTestCase;
22+
import android.test.AssertionFailedError;
2223
import android.test.suitebuilder.annotation.MediumTest;
2324
import java.nio.charset.Charsets;
2425
import java.util.Arrays;
26+
import java.util.Date;
2527
import java.util.HashSet;
2628

2729
/**
@@ -403,4 +405,52 @@ public void testUngrant_DoubleGrantUngrant_Failure() throws Exception {
403405
assertFalse("Should fail to ungrant key to other user second time",
404406
mKeyStore.ungrant(TEST_KEYNAME, 0));
405407
}
408+
409+
/**
410+
* The amount of time to allow before and after expected time for variance
411+
* in timing tests.
412+
*/
413+
private static final long SLOP_TIME_MILLIS = 15000L;
414+
415+
public void testGetmtime_Success() throws Exception {
416+
assertTrue("Password should work for keystore",
417+
mKeyStore.password(TEST_PASSWD));
418+
419+
assertTrue("Should be able to import key when unlocked",
420+
mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES));
421+
422+
long now = System.currentTimeMillis();
423+
long actual = mKeyStore.getmtime(TEST_KEYNAME);
424+
425+
long expectedAfter = now - SLOP_TIME_MILLIS;
426+
long expectedBefore = now + SLOP_TIME_MILLIS;
427+
428+
assertLessThan("Time should be close to current time", expectedBefore, actual);
429+
assertGreaterThan("Time should be close to current time", expectedAfter, actual);
430+
}
431+
432+
private static void assertLessThan(String explanation, long expectedBefore, long actual) {
433+
if (actual >= expectedBefore) {
434+
throw new AssertionFailedError(explanation + ": actual=" + actual
435+
+ ", expected before: " + expectedBefore);
436+
}
437+
}
438+
439+
private static void assertGreaterThan(String explanation, long expectedAfter, long actual) {
440+
if (actual <= expectedAfter) {
441+
throw new AssertionFailedError(explanation + ": actual=" + actual
442+
+ ", expected after: " + expectedAfter);
443+
}
444+
}
445+
446+
public void testGetmtime_NonExist_Failure() throws Exception {
447+
assertTrue("Password should work for keystore",
448+
mKeyStore.password(TEST_PASSWD));
449+
450+
assertTrue("Should be able to import key when unlocked",
451+
mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES));
452+
453+
assertEquals("-1 should be returned for non-existent key",
454+
-1L, mKeyStore.getmtime(TEST_KEYNAME2));
455+
}
406456
}

0 commit comments

Comments
 (0)