OSDN Git Service

Cleanup keystore password changing and unlocking
authorChad Brubaker <cbrubaker@google.com>
Thu, 7 May 2015 17:02:22 +0000 (10:02 -0700)
committerChad Brubaker <cbrubaker@google.com>
Fri, 8 May 2015 18:11:43 +0000 (11:11 -0700)
Add KeyStore.onUserPasswordChanged for the lockscreen to call when
the user changes their password. Keystore will then handle the logic of
deleting keys. Instead of calling Keystore.password_uid for both
unlocking and password changes the behavior has been split into
Keystore.unlock and onUserPasswordChanged.

Change-Id: I324914c00195d762cbaa8c63084e41fa796b7df8

core/java/android/security/IKeystoreService.aidl
keystore/java/android/security/KeyStore.java
keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
keystore/tests/src/android/security/AndroidKeyStoreTest.java
keystore/tests/src/android/security/KeyStoreTest.java
services/core/java/com/android/server/LockSettingsService.java

index 579cdbe..4809050 100644 (file)
@@ -37,9 +37,9 @@ interface IKeystoreService {
     int exist(String name, int uid);
     String[] saw(String namePrefix, int uid);
     int reset();
-    int password(String password);
+    int onUserPasswordChanged(int userId, String newPassword);
     int lock();
-    int unlock(String password);
+    int unlock(int userId, String userPassword);
     int zero();
     int generate(String name, int uid, int keyType, int keySize, int flags,
         in KeystoreArguments args);
index 82d328b..762be9d 100644 (file)
@@ -24,8 +24,10 @@ import android.content.Context;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.security.keymaster.ExportResult;
 import android.security.keymaster.KeyCharacteristics;
 import android.security.keymaster.KeymasterArguments;
@@ -212,15 +214,6 @@ public class KeyStore {
         }
     }
 
-    public boolean password(String password) {
-        try {
-            return mBinder.password(password) == NO_ERROR;
-        } catch (RemoteException e) {
-            Log.w(TAG, "Cannot connect to keystore", e);
-            return false;
-        }
-    }
-
     public boolean lock() {
         try {
             return mBinder.lock() == NO_ERROR;
@@ -230,9 +223,20 @@ public class KeyStore {
         }
     }
 
-    public boolean unlock(String password) {
+    /**
+     * Attempt to unlock the keystore for {@code user} with the password {@code password}.
+     * This is required before keystore entries created with FLAG_ENCRYPTED can be accessed or
+     * created.
+     *
+     * @param user Android user ID to operate on
+     * @param password user's keystore password. Should be the most recent value passed to
+     * {@link #onUserPasswordChanged} for the user.
+     *
+     * @return whether the keystore was unlocked.
+     */
+    public boolean unlock(int userId, String password) {
         try {
-            mError = mBinder.unlock(password);
+            mError = mBinder.unlock(userId, password);
             return mError == NO_ERROR;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
@@ -240,6 +244,10 @@ public class KeyStore {
         }
     }
 
+    public boolean unlock(String password) {
+        return unlock(UserHandle.getUserId(Process.myUid()), password);
+    }
+
     public boolean isEmpty() {
         try {
             return mBinder.zero() == KEY_NOT_FOUND;
@@ -540,6 +548,30 @@ public class KeyStore {
     }
 
     /**
+     * Notify keystore that a user's password has changed.
+     *
+     * @param userId the user whose password changed.
+     * @param newPassword the new password or "" if the password was removed.
+     */
+    public boolean onUserPasswordChanged(int userId, String newPassword) {
+        // Parcel.cpp doesn't support deserializing null strings and treats them as "". Make that
+        // explicit here.
+        if (newPassword == null) {
+            newPassword = "";
+        }
+        try {
+            return mBinder.onUserPasswordChanged(userId, newPassword) == NO_ERROR;
+        } catch (RemoteException e) {
+            Log.w(TAG, "Cannot connect to keystore", e);
+            return false;
+        }
+    }
+
+    public boolean onUserPasswordChanged(String newPassword) {
+        return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword);
+    }
+
+    /**
      * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error
      * code.
      */
index 95d14b7..9c2f358 100644 (file)
@@ -73,7 +73,7 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
     }
 
     private void setupPassword() {
-        assertTrue(mAndroidKeyStore.password("1111"));
+        assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
         assertTrue(mAndroidKeyStore.isUnlocked());
 
         String[] aliases = mAndroidKeyStore.saw("");
@@ -288,7 +288,7 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
             } catch (IllegalStateException expected) {
             }
 
-            assertTrue(mAndroidKeyStore.password("1111"));
+            assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
             assertTrue(mAndroidKeyStore.isUnlocked());
 
             final KeyPair pair2 = mGenerator.generateKeyPair();
index a7046dd..4b2b9b5 100644 (file)
@@ -736,7 +736,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase {
     }
 
     private void setupPassword() {
-        assertTrue(mAndroidKeyStore.password("1111"));
+        assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
         assertTrue(mAndroidKeyStore.isUnlocked());
 
         assertEquals(0, mAndroidKeyStore.saw("").length);
@@ -2089,7 +2089,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase {
             } catch (KeyStoreException success) {
             }
 
-            assertTrue(mAndroidKeyStore.password("1111"));
+            assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
             assertTrue(mAndroidKeyStore.isUnlocked());
 
             mKeyStore.setEntry(TEST_ALIAS_1, entry,
index 916b1ba..f261079 100644 (file)
@@ -152,13 +152,13 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testPassword() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
         assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
     }
 
     public void testGet() throws Exception {
         assertNull(mKeyStore.get(TEST_KEYNAME));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertNull(mKeyStore.get(TEST_KEYNAME));
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
                 KeyStore.FLAG_ENCRYPTED));
@@ -170,7 +170,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
                 KeyStore.FLAG_ENCRYPTED));
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
                 KeyStore.FLAG_ENCRYPTED));
         assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
@@ -181,7 +181,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
                 KeyStore.FLAG_ENCRYPTED));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
                 KeyStore.FLAG_ENCRYPTED));
         assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
@@ -192,7 +192,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
                 KeyStore.FLAG_ENCRYPTED));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
                 KeyStore.FLAG_ENCRYPTED));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
@@ -202,7 +202,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
         assertFalse(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE, KeyStore.UID_SELF,
                 KeyStore.FLAG_ENCRYPTED));
         assertFalse(mKeyStore.contains(TEST_I18N_KEY));
-        mKeyStore.password(TEST_I18N_KEY);
+        mKeyStore.onUserPasswordChanged(TEST_I18N_KEY);
         assertTrue(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE, KeyStore.UID_SELF,
                 KeyStore.FLAG_ENCRYPTED));
         assertTrue(mKeyStore.contains(TEST_I18N_KEY));
@@ -210,7 +210,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testDelete() throws Exception {
         assertFalse(mKeyStore.delete(TEST_KEYNAME));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertFalse(mKeyStore.delete(TEST_KEYNAME));
 
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
@@ -222,7 +222,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testDelete_grantedUid_Wifi() throws Exception {
         assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
 
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
@@ -234,7 +234,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testDelete_ungrantedUid_Bluetooth() throws Exception {
         assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
 
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
@@ -247,7 +247,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     public void testContains() throws Exception {
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
@@ -258,7 +258,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     public void testContains_grantedUid_Wifi() throws Exception {
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
 
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
 
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
@@ -269,7 +269,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     public void testContains_grantedUid_Bluetooth() throws Exception {
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
 
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
 
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
@@ -282,7 +282,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
         assertNotNull(emptyResult);
         assertEquals(0, emptyResult.length);
 
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
         mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
 
@@ -296,7 +296,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
         String[] results1 = mKeyStore.saw(TEST_KEYNAME, Process.BLUETOOTH_UID);
         assertEquals(0, results1.length);
 
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
         mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
 
@@ -309,7 +309,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
         assertNotNull(results1);
         assertEquals(0, results1.length);
 
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED);
         mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED);
 
@@ -324,7 +324,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
         assertNotNull(results1);
         assertEquals(0, results1.length);
 
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, Process.VPN_UID, KeyStore.FLAG_ENCRYPTED);
         mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, Process.VPN_UID, KeyStore.FLAG_ENCRYPTED);
 
@@ -337,7 +337,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     public void testLock() throws Exception {
         assertFalse(mKeyStore.lock());
 
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
 
         assertTrue(mKeyStore.lock());
@@ -345,7 +345,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testUnlock() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
         mKeyStore.lock();
 
@@ -355,7 +355,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testIsEmpty() throws Exception {
         assertTrue(mKeyStore.isEmpty());
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertTrue(mKeyStore.isEmpty());
         mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
         assertFalse(mKeyStore.isEmpty());
@@ -370,7 +370,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testGenerate_Locked_Fail() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         mKeyStore.lock();
         assertFalse("Should fail when keystore is locked",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -378,7 +378,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testGenerate_Success() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key when unlocked",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -388,7 +388,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testGenerate_grantedUid_Wifi_Success() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key when unlocked",
                 mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeConstants.EVP_PKEY_RSA,
@@ -398,7 +398,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testGenerate_ungrantedUid_Bluetooth_Failure() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID,
                     NativeConstants.EVP_PKEY_RSA, RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
@@ -408,7 +408,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testImport_Success() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -417,7 +417,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testImport_grantedUid_Wifi_Success() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED));
@@ -426,7 +426,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testImport_ungrantedUid_Bluetooth_Failure() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertFalse(mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES, Process.BLUETOOTH_UID,
                 KeyStore.FLAG_ENCRYPTED));
@@ -436,7 +436,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testImport_Failure_BadEncoding() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
 
         assertFalse("Invalid DER-encoded key should not be imported", mKeyStore.importKey(
                 TEST_KEYNAME, TEST_DATA, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -445,7 +445,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testSign_Success() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
 
         assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
@@ -456,7 +456,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testVerify_Success() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
 
         assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
@@ -475,7 +475,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testSign_NotGenerated_Failure() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
 
         assertNull("Should not be able to sign without first generating keys",
                 mKeyStore.sign(TEST_KEYNAME, TEST_DATA));
@@ -483,7 +483,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testGrant_Generated_Success() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -494,7 +494,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testGrant_Imported_Success() throws Exception {
-        assertTrue("Password should work for keystore", mKeyStore.password(TEST_PASSWD));
+        assertTrue("Password should work for keystore", mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key for testcase", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -504,7 +504,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testGrant_NoKey_Failure() throws Exception {
         assertTrue("Should be able to unlock keystore for test",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertFalse("Should not be able to grant without first initializing the keystore",
                 mKeyStore.grant(TEST_KEYNAME, 0));
@@ -517,7 +517,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testUngrant_Generated_Success() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -532,7 +532,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testUngrant_Imported_Success() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key for testcase", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -551,7 +551,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testUngrant_NoGrant_Failure() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -563,7 +563,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testUngrant_DoubleUngrant_Failure() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -581,7 +581,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testUngrant_DoubleGrantUngrant_Failure() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -601,7 +601,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testDuplicate_grantedUid_Wifi_Success() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
@@ -640,7 +640,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testDuplicate_ungrantedUid_Bluetooth_Failure() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
@@ -666,7 +666,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testGetmtime_Success() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -697,7 +697,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
 
     public void testGetmtime_NonExist_Failure() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -752,7 +752,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     }
 
     public void testGetKeyCharacteristicsSuccess() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         String name = "test";
         KeyCharacteristics gen = generateRsaKey(name);
         KeyCharacteristics call = new KeyCharacteristics();
@@ -950,4 +950,28 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
         assertEquals("Update should require authorization",
                 KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED, result.resultCode);
     }
+
+    public void testPasswordRemovalEncryptedEntry() throws Exception {
+        mKeyStore.onUserPasswordChanged("test");
+        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
+                KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mKeyStore.contains(TEST_KEYNAME));
+        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
+        mKeyStore.onUserPasswordChanged("");
+        // Removing the password should have deleted all entries using FLAG_ENCRYPTED
+        assertNull(mKeyStore.get(TEST_KEYNAME));
+        assertFalse(mKeyStore.contains(TEST_KEYNAME));
+    }
+
+    public void testPasswordRemovalUnencryptedEntry() throws Exception {
+        mKeyStore.onUserPasswordChanged("test");
+        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
+                KeyStore.FLAG_NONE));
+        assertTrue(mKeyStore.contains(TEST_KEYNAME));
+        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
+        mKeyStore.onUserPasswordChanged("");
+        // Removing the password should not delete unencrypted entries.
+        assertTrue(mKeyStore.contains(TEST_KEYNAME));
+        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
+    }
 }
index 5df74c5..ed2de4a 100644 (file)
@@ -356,28 +356,23 @@ public class LockSettingsService extends ILockSettings.Stub {
         return mStorage.hasPattern(userId);
     }
 
-    private void maybeUpdateKeystore(String password, int userHandle) {
+    private void setKeystorePassword(String password, int userHandle) {
         final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
         final KeyStore ks = KeyStore.getInstance();
 
         final List<UserInfo> profiles = um.getProfiles(userHandle);
-        boolean shouldReset = TextUtils.isEmpty(password);
-
-        // For historical reasons, don't wipe a non-empty keystore if we have a single user with a
-        // single profile.
-        if (userHandle == UserHandle.USER_OWNER && profiles.size() == 1) {
-            if (!ks.isEmpty()) {
-                shouldReset = false;
-            }
+        for (UserInfo pi : profiles) {
+            ks.onUserPasswordChanged(pi.id, password);
         }
+    }
+
+    private void unlockKeystore(String password, int userHandle) {
+        final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+        final KeyStore ks = KeyStore.getInstance();
 
+        final List<UserInfo> profiles = um.getProfiles(userHandle);
         for (UserInfo pi : profiles) {
-            final int profileUid = UserHandle.getUid(pi.id, Process.SYSTEM_UID);
-            if (shouldReset) {
-                ks.resetUid(profileUid);
-            } else {
-                ks.passwordUid(password, profileUid);
-            }
+            ks.unlock(pi.id, password);
         }
     }
 
@@ -423,7 +418,7 @@ public class LockSettingsService extends ILockSettings.Stub {
         if (pattern == null) {
             getGateKeeperService().clearSecureUserId(userId);
             mStorage.writePatternHash(null, userId);
-            maybeUpdateKeystore(null, userId);
+            setKeystorePassword(null, userId);
             return;
         }
 
@@ -451,7 +446,7 @@ public class LockSettingsService extends ILockSettings.Stub {
         if (password == null) {
             getGateKeeperService().clearSecureUserId(userId);
             mStorage.writePasswordHash(null, userId);
-            maybeUpdateKeystore(null, userId);
+            setKeystorePassword(null, userId);
             return;
         }
 
@@ -484,7 +479,7 @@ public class LockSettingsService extends ILockSettings.Stub {
                 toEnrollBytes);
 
         if (hash != null) {
-            maybeUpdateKeystore(toEnroll, userId);
+            setKeystorePassword(toEnroll, userId);
         }
 
         return hash;
@@ -530,7 +525,7 @@ public class LockSettingsService extends ILockSettings.Stub {
             byte[] hash = mLockPatternUtils.patternToHash(
                     mLockPatternUtils.stringToPattern(pattern));
             if (Arrays.equals(hash, storedHash.hash)) {
-                maybeUpdateKeystore(pattern, userId);
+                unlockKeystore(pattern, userId);
                 // migrate password to GateKeeper
                 setLockPattern(pattern, null, userId);
                 if (!hasChallenge) {
@@ -556,7 +551,7 @@ public class LockSettingsService extends ILockSettings.Stub {
         }
 
         // pattern has matched
-        maybeUpdateKeystore(pattern, userId);
+        unlockKeystore(pattern, userId);
         return token;
 
     }
@@ -599,7 +594,7 @@ public class LockSettingsService extends ILockSettings.Stub {
         if (storedHash.version == CredentialHash.VERSION_LEGACY) {
             byte[] hash = mLockPatternUtils.passwordToHash(password, userId);
             if (Arrays.equals(hash, storedHash.hash)) {
-                maybeUpdateKeystore(password, userId);
+                unlockKeystore(password, userId);
                 // migrate password to GateKeeper
                 setLockPassword(password, null, userId);
                 if (!hasChallenge) {
@@ -625,7 +620,7 @@ public class LockSettingsService extends ILockSettings.Stub {
         }
 
         // password has matched
-        maybeUpdateKeystore(password, userId);
+        unlockKeystore(password, userId);
         return token;
     }