Skip to content

Commit fc7e851

Browse files
krutonAndroid (Google) Code Review
authored andcommitted
Merge "Add getmtime to Android KeyStore API" into jb-mr1-dev
2 parents 99de245 + 473c712 commit fc7e851

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)