summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Brubaker <cbrubaker@google.com>2015-05-07 10:02:22 -0700
committerChad Brubaker <cbrubaker@google.com>2015-05-08 11:11:43 -0700
commita91a8504191d91d288c55821caa5bf00c9be26a2 (patch)
treee7eece5120d2c08ca3321d58507d979eeca63e45
parent1bc3c849ba5e9f23dd7e93012c4b5800b78c221b (diff)
Cleanup keystore password changing and unlocking
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
-rw-r--r--core/java/android/security/IKeystoreService.aidl4
-rw-r--r--keystore/java/android/security/KeyStore.java54
-rw-r--r--keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java4
-rw-r--r--keystore/tests/src/android/security/AndroidKeyStoreTest.java4
-rw-r--r--keystore/tests/src/android/security/KeyStoreTest.java110
-rw-r--r--services/core/java/com/android/server/LockSettingsService.java39
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;
}