diff options
6 files changed, 133 insertions, 82 deletions
diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl index 579cdbeb40f4..4809050f3197 100644 --- a/core/java/android/security/IKeystoreService.aidl +++ b/core/java/android/security/IKeystoreService.aidl @@ -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); diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 82d328b0b71f..762be9dae5d0 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -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. */ diff --git a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java index 95d14b77fffd..9c2f3586e03f 100644 --- a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java +++ b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java @@ -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(); diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/AndroidKeyStoreTest.java index a7046dd29cec..4b2b9b5ac243 100644 --- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java +++ b/keystore/tests/src/android/security/AndroidKeyStoreTest.java @@ -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, diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java index 916b1ba9ac46..f261079bd6c9 100644 --- a/keystore/tests/src/android/security/KeyStoreTest.java +++ b/keystore/tests/src/android/security/KeyStoreTest.java @@ -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))); + } } diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index 5df74c5edd05..ed2de4a9e485 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -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; } |