KeyChain: Remove Screenlock dependency

In coordination with KeyChain changes, stop using FLAG_ENCRYPTED when
importing keys into KeyStore and remove the requirement that a screen
lock is present.

The change to this package removes the checks for KeyStore state and
Keyguard presence. See the KeyChain change for more detailed
explanation.

Test: atest CtsDevicePolicyManagerTestCases:com.android.cts.devicepolicy.MixedProfileOwnerTest#testKeyManagement
Bug: 120901345
Change-Id: I82f1c18e84dd4a63d55017fa4b7be31c45f7ef14
This commit is contained in:
Eran Messeri
2019-01-16 05:49:04 -08:00
parent dbaa5459b8
commit fa7f75abd9

View File

@@ -55,40 +55,7 @@ import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId; import sun.security.x509.AlgorithmId;
/** /**
* CredentialStorage handles KeyStore reset, unlock, and install. * CredentialStorage handles resetting and installing keys into KeyStore.
*
* CredentialStorage has a pretty convoluted state machine to migrate
* from the old style separate keystore password to a new key guard
* based password, as well as to deal with setting up the key guard if
* necessary.
*
* KeyStore: UNINITALIZED
* KeyGuard: OFF
* Action: set up key guard
* Notes: factory state
*
* KeyStore: UNINITALIZED
* KeyGuard: ON
* Action: confirm key guard
* Notes: user had key guard but no keystore and upgraded from pre-ICS
* OR user had key guard and pre-ICS keystore password which was then reset
*
* KeyStore: LOCKED
* KeyGuard: OFF/ON
* Action: confirm key guard
* Notes: request normal unlock to unlock the keystore.
* if unlock, ensure key guard before install.
* if reset, treat as UNINITALIZED/OFF
*
* KeyStore: UNLOCKED
* KeyGuard: OFF
* Action: set up key guard
* Notes: ensure key guard, then proceed
*
* KeyStore: UNLOCKED
* keyguard: ON
* Action: normal unlock/install
* Notes: this is the common case
*/ */
public final class CredentialStorage extends FragmentActivity { public final class CredentialStorage extends FragmentActivity {
@@ -102,8 +69,7 @@ public final class CredentialStorage extends FragmentActivity {
// lower than this, keystore should not be activated. // lower than this, keystore should not be activated.
public static final int MIN_PASSWORD_QUALITY = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; public static final int MIN_PASSWORD_QUALITY = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
private static final int CONFIRM_KEY_GUARD_REQUEST = 1; private static final int CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST = 1;
private static final int CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST = 2;
private final KeyStore mKeyStore = KeyStore.getInstance(); private final KeyStore mKeyStore = KeyStore.getInstance();
private LockPatternUtils mUtils; private LockPatternUtils mUtils;
@@ -133,75 +99,26 @@ public final class CredentialStorage extends FragmentActivity {
if (ACTION_INSTALL.equals(action) && checkCallerIsCertInstallerOrSelfInProfile()) { if (ACTION_INSTALL.equals(action) && checkCallerIsCertInstallerOrSelfInProfile()) {
mInstallBundle = intent.getExtras(); mInstallBundle = intent.getExtras();
} }
// ACTION_UNLOCK also handled here in addition to ACTION_INSTALL handleInstall();
handleUnlockOrInstall();
} }
} else { } else {
// Users can set a screen lock if there is none even if they can't modify the finish();
// credentials store.
if (ACTION_UNLOCK.equals(action) && mKeyStore.state() == KeyStore.State.UNINITIALIZED) {
ensureKeyGuard();
} else {
finish();
}
} }
} }
/** /**
* Based on the current state of the KeyStore and key guard, try to * Install credentials from mInstallBundle into Keystore.
* make progress on unlocking or installing to the keystore.
*/ */
private void handleUnlockOrInstall() { private void handleInstall() {
// something already decided we are done, do not proceed // something already decided we are done, do not proceed
if (isFinishing()) { if (isFinishing()) {
return; return;
} }
switch (mKeyStore.state()) { if (installIfAvailable()) {
case UNINITIALIZED: { finish();
ensureKeyGuard();
return;
}
case LOCKED: {
// Force key guard confirmation
confirmKeyGuard(CONFIRM_KEY_GUARD_REQUEST);
return;
}
case UNLOCKED: {
if (!mUtils.isSecure(UserHandle.myUserId())) {
final ConfigureKeyGuardDialog dialog = new ConfigureKeyGuardDialog();
dialog.show(getSupportFragmentManager(), ConfigureKeyGuardDialog.TAG);
return;
}
if (installIfAvailable()) {
finish();
}
return;
}
} }
} }
/**
* Make sure the user enters the key guard to set or change the
* keystore password. This can be used in UNINITIALIZED to set the
* keystore password or UNLOCKED to change the password (as is the
* case after unlocking with an old-style password).
*/
private void ensureKeyGuard() {
if (!mUtils.isSecure(UserHandle.myUserId())) {
// key guard not setup, doing so will initialize keystore
final ConfigureKeyGuardDialog dialog = new ConfigureKeyGuardDialog();
dialog.show(getSupportFragmentManager(), ConfigureKeyGuardDialog.TAG);
// will return to onResume after Activity
return;
}
// force key guard confirmation
if (confirmKeyGuard(CONFIRM_KEY_GUARD_REQUEST)) {
// will return password value via onActivityResult
return;
}
finish();
}
private boolean isHardwareBackedKey(byte[] keyData) { private boolean isHardwareBackedKey(byte[] keyData) {
try { try {
final ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(keyData)); final ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(keyData));
@@ -254,15 +171,7 @@ public final class CredentialStorage extends FragmentActivity {
final String key = bundle.getString(Credentials.EXTRA_USER_PRIVATE_KEY_NAME); final String key = bundle.getString(Credentials.EXTRA_USER_PRIVATE_KEY_NAME);
final byte[] value = bundle.getByteArray(Credentials.EXTRA_USER_PRIVATE_KEY_DATA); final byte[] value = bundle.getByteArray(Credentials.EXTRA_USER_PRIVATE_KEY_DATA);
int flags = KeyStore.FLAG_ENCRYPTED; if (!mKeyStore.importKey(key, value, uid, KeyStore.FLAG_NONE)) {
if (uid == Process.WIFI_UID && isHardwareBackedKey(value)) {
// Hardware backed keystore is secure enough to allow for WIFI stack
// to enable access to secure networks without user intervention
Log.d(TAG, "Saving private key with FLAG_NONE for WIFI_UID");
flags = KeyStore.FLAG_NONE;
}
if (!mKeyStore.importKey(key, value, uid, flags)) {
Log.e(TAG, "Failed to install " + key + " as uid " + uid); Log.e(TAG, "Failed to install " + key + " as uid " + uid);
return true; return true;
} }
@@ -475,20 +384,7 @@ public final class CredentialStorage extends FragmentActivity {
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
// Receive key guard password initiated by confirmKeyGuard. if (requestCode == CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST) {
if (requestCode == CONFIRM_KEY_GUARD_REQUEST) {
if (resultCode == Activity.RESULT_OK) {
final String password = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
if (!TextUtils.isEmpty(password)) {
// success
mKeyStore.unlock(password);
// return to onResume
return;
}
}
// failed confirmation, bail
finish();
} else if (requestCode == CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
new ResetKeyStoreAndKeyChain().execute(); new ResetKeyStoreAndKeyChain().execute();
return; return;