Integrating keystore with keyguard (Part 1 of 4)

Summary:

frameworks/base
  keystore rewrite
  keyguard integration with keystore on keyguard entry or keyguard change
  KeyStore API simplification

packages/apps/Settings
  Removed com.android.credentials.SET_PASSWORD intent support
  Added keyguard requirement for keystore use

packages/apps/CertInstaller
  Tracking KeyStore API changes
  Fix for NPE in CertInstaller when certificate lacks basic constraints

packages/apps/KeyChain
  Tracking KeyStore API changes

Details:

frameworks/base

   Move keystore from C to C++ while rewriting password
   implementation. Removed global variables. Added many comments.

	cmds/keystore/Android.mk
	cmds/keystore/keystore.h
	cmds/keystore/keystore.c => cmds/keystore/keystore.cpp
	cmds/keystore/keystore_cli.c => cmds/keystore/keystore_cli.cpp

   Changed saveLockPattern and saveLockPassword to notify the keystore
   on changes so that the keystore master key can be reencrypted when
   the keyguard changes.

	core/java/com/android/internal/widget/LockPatternUtils.java

   Changed unlock screens to pass values for keystore unlock or initialization

	policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
	policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java

   KeyStore API changes
   - renamed test() to state(), which now return a State enum
   - made APIs with byte[] key arguments private
   - added new KeyStore.isEmpty used to determine if a keyguard is required

	keystore/java/android/security/KeyStore.java

   In addition to tracking KeyStore API changes, added new testIsEmpty
   and improved some existing tests to validate expect values.

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

packages/apps/Settings

    Removing com.android.credentials.SET_PASSWORD intent with the
    removal of the ability to set an explicit keystore password now
    that the keyguard value is used. Changed to ensure keyguard is
    enabled for keystore install or unlock. Cleaned up interwoven
    dialog handing into discrete dialog helper classes.

	AndroidManifest.xml
	src/com/android/settings/CredentialStorage.java

    Remove layout for entering new password

	res/layout/credentials_dialog.xml

    Remove enable credentials checkbox

	res/xml/security_settings_misc.xml
	src/com/android/settings/SecuritySettings.java

    Added ability to specify minimum quality key to ChooseLockGeneric
    Activity. Used by CredentialStorage, but could also be used by
    CryptKeeperSettings. Changed ChooseLockGeneric to understand
    minimum quality for keystore in addition to DPM and device
    encryption.

	src/com/android/settings/ChooseLockGeneric.java

    Changed to use getActivePasswordQuality from
    getKeyguardStoredPasswordQuality based on experience in
    CredentialStorage. Removed bogus class javadoc.

	src/com/android/settings/CryptKeeperSettings.java

    Tracking KeyStore API changes

	src/com/android/settings/vpn/VpnSettings.java
	src/com/android/settings/wifi/WifiSettings.java

   Removing now unused string resources

	res/values-af/strings.xml
	res/values-am/strings.xml
	res/values-ar/strings.xml
	res/values-bg/strings.xml
	res/values-ca/strings.xml
	res/values-cs/strings.xml
	res/values-da/strings.xml
	res/values-de/strings.xml
	res/values-el/strings.xml
	res/values-en-rGB/strings.xml
	res/values-es-rUS/strings.xml
	res/values-es/strings.xml
	res/values-fa/strings.xml
	res/values-fi/strings.xml
	res/values-fr/strings.xml
	res/values-hr/strings.xml
	res/values-hu/strings.xml
	res/values-in/strings.xml
	res/values-it/strings.xml
	res/values-iw/strings.xml
	res/values-ja/strings.xml
	res/values-ko/strings.xml
	res/values-lt/strings.xml
	res/values-lv/strings.xml
	res/values-ms/strings.xml
	res/values-nb/strings.xml
	res/values-nl/strings.xml
	res/values-pl/strings.xml
	res/values-pt-rPT/strings.xml
	res/values-pt/strings.xml
	res/values-rm/strings.xml
	res/values-ro/strings.xml
	res/values-ru/strings.xml
	res/values-sk/strings.xml
	res/values-sl/strings.xml
	res/values-sr/strings.xml
	res/values-sv/strings.xml
	res/values-sw/strings.xml
	res/values-th/strings.xml
	res/values-tl/strings.xml
	res/values-tr/strings.xml
	res/values-uk/strings.xml
	res/values-vi/strings.xml
	res/values-zh-rCN/strings.xml
	res/values-zh-rTW/strings.xml
	res/values-zu/strings.xml
	res/values/strings.xml

packages/apps/CertInstaller

  Tracking KeyStore API changes
	src/com/android/certinstaller/CertInstaller.java

  Fix for NPE in CertInstaller when certificate lacks basic constraints
	src/com/android/certinstaller/CredentialHelper.java

packages/apps/KeyChain

  Tracking KeyStore API changes
	src/com/android/keychain/KeyChainActivity.java
	src/com/android/keychain/KeyChainService.java
	support/src/com/android/keychain/tests/support/IKeyChainServiceTestSupport.aidl
	support/src/com/android/keychain/tests/support/KeyChainServiceTestSupport.java
	tests/src/com/android/keychain/tests/KeyChainServiceTest.java

Change-Id: Ic141fb5d4b43d12fe62cb1e29c7cbd891b4be35d
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 6630a4f..4582aa0 100755
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -20,6 +20,9 @@
 import android.security.KeyStore;
 import android.test.ActivityUnitTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
+import java.nio.charset.Charsets;
+import java.util.Arrays;
+import java.util.HashSet;
 
 /**
  * Junit / Instrumentation test case for KeyStore class
@@ -31,16 +34,15 @@
 @MediumTest
 public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     private static final String TEST_PASSWD = "12345678";
-    private static final String TEST_EMPTY_PASSWD = "";
-    private static final String TEST_SHORT_PASSWD = "short";
     private static final String TEST_PASSWD2 = "87654321";
     private static final String TEST_KEYNAME = "testkey";
     private static final String TEST_KEYNAME1 = "testkey1";
     private static final String TEST_KEYNAME2 = "testkey2";
-    private static final String TEST_KEYVALUE = "test value";
+    private static final byte[] TEST_KEYVALUE = "test value".getBytes(Charsets.UTF_8);
 
     // "Hello, World" in Chinese
-    private static final String TEST_I18N = "\u4F60\u597D, \u4E16\u754C";
+    private static final String TEST_I18N_KEY = "\u4F60\u597D, \u4E16\u754C";
+    private static final byte[] TEST_I18N_VALUE = TEST_I18N_KEY.getBytes(Charsets.UTF_8);
 
     private KeyStore mKeyStore = null;
 
@@ -51,8 +53,10 @@
     @Override
     protected void setUp() throws Exception {
         mKeyStore = KeyStore.getInstance();
-        if (mKeyStore.test() != KeyStore.UNINITIALIZED) mKeyStore.reset();
-        assertEquals(KeyStore.UNINITIALIZED, mKeyStore.test());
+        if (mKeyStore.state() != KeyStore.State.UNINITIALIZED) {
+            mKeyStore.reset();
+        }
+        assertEquals(KeyStore.State.UNINITIALIZED, mKeyStore.state());
         super.setUp();
     }
 
@@ -62,21 +66,13 @@
         super.tearDown();
     }
 
-    public void testTest() throws Exception {
-        assertEquals(KeyStore.UNINITIALIZED, mKeyStore.test());
+    public void teststate() throws Exception {
+        assertEquals(KeyStore.State.UNINITIALIZED, mKeyStore.state());
     }
 
     public void testPassword() throws Exception {
-        //assertFalse(mKeyStore.password(TEST_EMPTY_PASSWD));
-        //assertFalse(mKeyStore.password(TEST_SHORT_PASSWD));
-
         assertTrue(mKeyStore.password(TEST_PASSWD));
-        assertEquals(KeyStore.NO_ERROR, mKeyStore.test());
-
-        assertFalse(mKeyStore.password(TEST_PASSWD2, TEST_PASSWD2));
-        //assertFalse(mKeyStore.password(TEST_PASSWD, TEST_SHORT_PASSWD));
-
-        assertTrue(mKeyStore.password(TEST_PASSWD, TEST_PASSWD2));
+        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
     }
 
     public void testPut() throws Exception {
@@ -87,11 +83,11 @@
     }
 
     public void testI18n() throws Exception {
-        assertFalse(mKeyStore.put(TEST_I18N, TEST_I18N));
-        assertFalse(mKeyStore.contains(TEST_I18N));
-        mKeyStore.password(TEST_I18N);
-        assertTrue(mKeyStore.put(TEST_I18N, TEST_I18N));
-        assertTrue(mKeyStore.contains(TEST_I18N));
+        assertFalse(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE));
+        assertFalse(mKeyStore.contains(TEST_I18N_KEY));
+        mKeyStore.password(TEST_I18N_KEY);
+        assertTrue(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE));
+        assertTrue(mKeyStore.contains(TEST_I18N_KEY));
     }
 
     public void testDelete() throws Exception {
@@ -114,33 +110,46 @@
     }
 
     public void testSaw() throws Exception {
-        String[] results = mKeyStore.saw(TEST_KEYNAME);
-        assertEquals(0, results.length);
+        String[] emptyResult = mKeyStore.saw(TEST_KEYNAME);
+        assertNotNull(emptyResult);
+        assertEquals(0, emptyResult.length);
 
         mKeyStore.password(TEST_PASSWD);
         mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE);
         mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE);
 
-        results = mKeyStore.saw(TEST_KEYNAME);
-        assertEquals(2, results.length);
+        String[] results = mKeyStore.saw(TEST_KEYNAME);
+        assertEquals(new HashSet(Arrays.asList(TEST_KEYNAME1.substring(TEST_KEYNAME.length()),
+                                               TEST_KEYNAME2.substring(TEST_KEYNAME.length()))),
+                     new HashSet(Arrays.asList(results)));
     }
 
     public void testLock() throws Exception {
         assertFalse(mKeyStore.lock());
 
         mKeyStore.password(TEST_PASSWD);
-        assertEquals(KeyStore.NO_ERROR, mKeyStore.test());
+        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
 
         assertTrue(mKeyStore.lock());
-        assertEquals(KeyStore.LOCKED, mKeyStore.test());
+        assertEquals(KeyStore.State.LOCKED, mKeyStore.state());
     }
 
     public void testUnlock() throws Exception {
         mKeyStore.password(TEST_PASSWD);
-        assertEquals(KeyStore.NO_ERROR, mKeyStore.test());
+        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
         mKeyStore.lock();
 
         assertFalse(mKeyStore.unlock(TEST_PASSWD2));
         assertTrue(mKeyStore.unlock(TEST_PASSWD));
     }
+
+    public void testIsEmpty() throws Exception {
+        assertTrue(mKeyStore.isEmpty());
+        mKeyStore.password(TEST_PASSWD);
+        assertTrue(mKeyStore.isEmpty());
+        mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE);
+        assertFalse(mKeyStore.isEmpty());
+        mKeyStore.reset();
+        assertTrue(mKeyStore.isEmpty());
+    }
 }