summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}