Loading keystore/java/android/security/KeyStore.java +18 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import java.io.UTFDataFormatException; import java.nio.charset.Charsets; import java.nio.charset.ModifiedUtf8; import java.util.ArrayList; import java.util.Date; /** * @hide This should not be made public in its present form because it Loading Loading @@ -228,6 +229,23 @@ public class KeyStore { return ungrant(getKeyBytes(key), getUidBytes(uid)); } private long getmtime(byte[] key) { final ArrayList<byte[]> values = execute('c', key); if (values == null || values.isEmpty()) { return -1L; } return Long.parseLong(new String(values.get(0))) * 1000L; } /** * Returns the last modification time of the key in milliseconds since the * epoch. Will return -1L if the key could not be found or other error. */ public long getmtime(String key) { return getmtime(getKeyBytes(key)); } public int getLastError() { return mError; } Loading keystore/tests/src/android/security/KeyStoreTest.java +50 −0 Original line number Diff line number Diff line Loading @@ -19,9 +19,11 @@ package android.security; import android.app.Activity; import android.security.KeyStore; import android.test.ActivityUnitTestCase; import android.test.AssertionFailedError; import android.test.suitebuilder.annotation.MediumTest; import java.nio.charset.Charsets; import java.util.Arrays; import java.util.Date; import java.util.HashSet; /** Loading Loading @@ -403,4 +405,52 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> { assertFalse("Should fail to ungrant key to other user second time", mKeyStore.ungrant(TEST_KEYNAME, 0)); } /** * The amount of time to allow before and after expected time for variance * in timing tests. */ private static final long SLOP_TIME_MILLIS = 15000L; public void testGetmtime_Success() throws Exception { assertTrue("Password should work for keystore", mKeyStore.password(TEST_PASSWD)); assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES)); long now = System.currentTimeMillis(); long actual = mKeyStore.getmtime(TEST_KEYNAME); long expectedAfter = now - SLOP_TIME_MILLIS; long expectedBefore = now + SLOP_TIME_MILLIS; assertLessThan("Time should be close to current time", expectedBefore, actual); assertGreaterThan("Time should be close to current time", expectedAfter, actual); } private static void assertLessThan(String explanation, long expectedBefore, long actual) { if (actual >= expectedBefore) { throw new AssertionFailedError(explanation + ": actual=" + actual + ", expected before: " + expectedBefore); } } private static void assertGreaterThan(String explanation, long expectedAfter, long actual) { if (actual <= expectedAfter) { throw new AssertionFailedError(explanation + ": actual=" + actual + ", expected after: " + expectedAfter); } } public void testGetmtime_NonExist_Failure() throws Exception { assertTrue("Password should work for keystore", mKeyStore.password(TEST_PASSWD)); assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES)); assertEquals("-1 should be returned for non-existent key", -1L, mKeyStore.getmtime(TEST_KEYNAME2)); } } Loading
keystore/java/android/security/KeyStore.java +18 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import java.io.UTFDataFormatException; import java.nio.charset.Charsets; import java.nio.charset.ModifiedUtf8; import java.util.ArrayList; import java.util.Date; /** * @hide This should not be made public in its present form because it Loading Loading @@ -228,6 +229,23 @@ public class KeyStore { return ungrant(getKeyBytes(key), getUidBytes(uid)); } private long getmtime(byte[] key) { final ArrayList<byte[]> values = execute('c', key); if (values == null || values.isEmpty()) { return -1L; } return Long.parseLong(new String(values.get(0))) * 1000L; } /** * Returns the last modification time of the key in milliseconds since the * epoch. Will return -1L if the key could not be found or other error. */ public long getmtime(String key) { return getmtime(getKeyBytes(key)); } public int getLastError() { return mError; } Loading
keystore/tests/src/android/security/KeyStoreTest.java +50 −0 Original line number Diff line number Diff line Loading @@ -19,9 +19,11 @@ package android.security; import android.app.Activity; import android.security.KeyStore; import android.test.ActivityUnitTestCase; import android.test.AssertionFailedError; import android.test.suitebuilder.annotation.MediumTest; import java.nio.charset.Charsets; import java.util.Arrays; import java.util.Date; import java.util.HashSet; /** Loading Loading @@ -403,4 +405,52 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> { assertFalse("Should fail to ungrant key to other user second time", mKeyStore.ungrant(TEST_KEYNAME, 0)); } /** * The amount of time to allow before and after expected time for variance * in timing tests. */ private static final long SLOP_TIME_MILLIS = 15000L; public void testGetmtime_Success() throws Exception { assertTrue("Password should work for keystore", mKeyStore.password(TEST_PASSWD)); assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES)); long now = System.currentTimeMillis(); long actual = mKeyStore.getmtime(TEST_KEYNAME); long expectedAfter = now - SLOP_TIME_MILLIS; long expectedBefore = now + SLOP_TIME_MILLIS; assertLessThan("Time should be close to current time", expectedBefore, actual); assertGreaterThan("Time should be close to current time", expectedAfter, actual); } private static void assertLessThan(String explanation, long expectedBefore, long actual) { if (actual >= expectedBefore) { throw new AssertionFailedError(explanation + ": actual=" + actual + ", expected before: " + expectedBefore); } } private static void assertGreaterThan(String explanation, long expectedAfter, long actual) { if (actual <= expectedAfter) { throw new AssertionFailedError(explanation + ": actual=" + actual + ", expected after: " + expectedAfter); } } public void testGetmtime_NonExist_Failure() throws Exception { assertTrue("Password should work for keystore", mKeyStore.password(TEST_PASSWD)); assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES)); assertEquals("-1 should be returned for non-existent key", -1L, mKeyStore.getmtime(TEST_KEYNAME2)); } }