Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44b7a50f authored by Kenny Root's avatar Kenny Root Committed by Android Git Automerger
Browse files

am 88ba79b5: am fc7e851f: Merge "Add getmtime to Android KeyStore API" into jb-mr1-dev

* commit '88ba79b5':
  Add getmtime to Android KeyStore API
parents 6963dfb2 88ba79b5
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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
@@ -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;
    }
+50 −0
Original line number Diff line number Diff line
@@ -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;

/**
@@ -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));
    }
}