Merge "Revisit the lifetime of the RebootEscrowProvider"
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index c01523a..90694d0 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -205,6 +205,7 @@
Slog.i(TAG, "Using server based resume on reboot");
rebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(mContext, mStorage);
} else {
+ Slog.i(TAG, "Using HAL based resume on reboot");
rebootEscrowProvider = new RebootEscrowProviderHalImpl();
}
@@ -239,7 +240,7 @@
return mKeyStoreManager;
}
- public RebootEscrowProviderInterface getRebootEscrowProvider() {
+ public RebootEscrowProviderInterface createRebootEscrowProviderIfNeeded() {
// Initialize for the provider lazily. Because the device_config and service
// implementation apps may change when system server is running.
if (mRebootEscrowProvider == null) {
@@ -249,6 +250,14 @@
return mRebootEscrowProvider;
}
+ public RebootEscrowProviderInterface getRebootEscrowProvider() {
+ return mRebootEscrowProvider;
+ }
+
+ public void clearRebootEscrowProvider() {
+ mRebootEscrowProvider = null;
+ }
+
public int getBootCount() {
return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.BOOT_COUNT,
0);
@@ -308,8 +317,6 @@
mStorage.removeRebootEscrow(user.id);
}
- // Clear the old key in keystore.
- mKeyStoreManager.clearKeyStoreEncryptionKey();
onEscrowRestoreComplete(false, attemptCount);
}
@@ -395,9 +402,6 @@
allUsersUnlocked &= restoreRebootEscrowForUser(user.id, escrowKey, kk);
}
- // Clear the old key in keystore. A new key will be generated by new RoR requests.
- mKeyStoreManager.clearKeyStoreEncryptionKey();
-
if (!allUsersUnlocked && mLoadEscrowDataErrorCode == ERROR_NONE) {
mLoadEscrowDataErrorCode = ERROR_UNLOCK_ALL_USERS;
}
@@ -473,11 +477,17 @@
if (success || (previousBootCount != -1 && bootCountDelta <= BOOT_COUNT_TOLERANCE)) {
reportMetricOnRestoreComplete(success, attemptCount);
}
+
+ // Clear the old key in keystore. A new key will be generated by new RoR requests.
+ mKeyStoreManager.clearKeyStoreEncryptionKey();
+ // Clear the saved reboot escrow provider
+ mInjector.clearRebootEscrowProvider();
clearMetricsStorage();
}
private RebootEscrowKey getAndClearRebootEscrowKey(SecretKey kk) throws IOException {
- RebootEscrowProviderInterface rebootEscrowProvider = mInjector.getRebootEscrowProvider();
+ RebootEscrowProviderInterface rebootEscrowProvider =
+ mInjector.createRebootEscrowProviderIfNeeded();
if (rebootEscrowProvider == null) {
Slog.w(TAG,
"Had reboot escrow data for users, but RebootEscrowProvider is unavailable");
@@ -529,9 +539,8 @@
return;
}
- if (mInjector.getRebootEscrowProvider() == null) {
- Slog.w(TAG,
- "Had reboot escrow data for users, but RebootEscrowProvider is unavailable");
+ if (mInjector.createRebootEscrowProviderIfNeeded() == null) {
+ Slog.w(TAG, "Not storing escrow data, RebootEscrowProvider is unavailable");
return;
}
@@ -586,13 +595,17 @@
mRebootEscrowWanted = false;
setRebootEscrowReady(false);
- RebootEscrowProviderInterface rebootEscrowProvider = mInjector.getRebootEscrowProvider();
+ // We want to clear the internal data inside the provider, so always try to create the
+ // provider.
+ RebootEscrowProviderInterface rebootEscrowProvider =
+ mInjector.createRebootEscrowProviderIfNeeded();
if (rebootEscrowProvider == null) {
Slog.w(TAG, "RebootEscrowProvider is unavailable for clear request");
} else {
rebootEscrowProvider.clearRebootEscrowKey();
}
+ mInjector.clearRebootEscrowProvider();
clearMetricsStorage();
List<UserInfo> users = mUserManager.getUsers();
@@ -610,8 +623,7 @@
RebootEscrowProviderInterface rebootEscrowProvider = mInjector.getRebootEscrowProvider();
if (rebootEscrowProvider == null) {
- Slog.w(TAG,
- "Had reboot escrow data for users, but RebootEscrowProvider is unavailable");
+ Slog.w(TAG, "Not storing escrow key, RebootEscrowProvider is unavailable");
clearRebootEscrowIfNeeded();
return ARM_REBOOT_ERROR_NO_PROVIDER;
}
@@ -677,11 +689,12 @@
}
boolean prepareRebootEscrow() {
- if (mInjector.getRebootEscrowProvider() == null) {
+ clearRebootEscrowIfNeeded();
+ if (mInjector.createRebootEscrowProviderIfNeeded() == null) {
+ Slog.w(TAG, "No reboot escrow provider, skipping resume on reboot preparation.");
return false;
}
- clearRebootEscrowIfNeeded();
mRebootEscrowWanted = true;
mEventLog.addEntry(RebootEscrowEvent.REQUESTED_LSKF);
return true;
@@ -807,6 +820,10 @@
pw.print("mPendingRebootEscrowKey is ");
pw.println(keySet ? "set" : "not set");
+ RebootEscrowProviderInterface provider = mInjector.getRebootEscrowProvider();
+ String providerType = provider == null ? "null" : String.valueOf(provider.getType());
+ pw.print("RebootEscrowProvider type is " + providerType);
+
pw.println();
pw.println("Event log:");
pw.increaseIndent();
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
index 49a54ec..aecc794 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
@@ -112,14 +112,13 @@
private MockableRebootEscrowInjected mInjected;
private RebootEscrowManager mService;
private SecretKey mAesKey;
+ private MockInjector mMockInjector;
public interface MockableRebootEscrowInjected {
int getBootCount();
long getCurrentTimeMillis();
- boolean forceServerBased();
-
void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
int escrowDurationInSeconds, int vbmetaDigestStatus, int durationSinceBootComplete);
}
@@ -127,11 +126,12 @@
static class MockInjector extends RebootEscrowManager.Injector {
private final IRebootEscrow mRebootEscrow;
private final ResumeOnRebootServiceConnection mServiceConnection;
- private final RebootEscrowProviderInterface mRebootEscrowProvider;
+ private final RebootEscrowProviderInterface mDefaultRebootEscrowProvider;
private final UserManager mUserManager;
private final MockableRebootEscrowInjected mInjected;
private final RebootEscrowKeyStoreManager mKeyStoreManager;
- private final boolean mServerBased;
+ private boolean mServerBased;
+ private RebootEscrowProviderInterface mRebootEscrowProviderInUse;
MockInjector(Context context, UserManager userManager,
IRebootEscrow rebootEscrow,
@@ -149,7 +149,7 @@
return mRebootEscrow;
}
};
- mRebootEscrowProvider = new RebootEscrowProviderHalImpl(halInjector);
+ mDefaultRebootEscrowProvider = new RebootEscrowProviderHalImpl(halInjector);
mUserManager = userManager;
mKeyStoreManager = keyStoreManager;
mInjected = injected;
@@ -166,7 +166,8 @@
mServerBased = true;
RebootEscrowProviderServerBasedImpl.Injector injector =
new RebootEscrowProviderServerBasedImpl.Injector(serviceConnection);
- mRebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(storage, injector);
+ mDefaultRebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(
+ storage, injector);
mUserManager = userManager;
mKeyStoreManager = keyStoreManager;
mInjected = injected;
@@ -184,15 +185,23 @@
@Override
public boolean serverBasedResumeOnReboot() {
- if (mInjected.forceServerBased()) {
- return true;
- }
return mServerBased;
}
@Override
+ public RebootEscrowProviderInterface createRebootEscrowProviderIfNeeded() {
+ mRebootEscrowProviderInUse = mDefaultRebootEscrowProvider;
+ return mRebootEscrowProviderInUse;
+ }
+
+ @Override
public RebootEscrowProviderInterface getRebootEscrowProvider() {
- return mRebootEscrowProvider;
+ return mRebootEscrowProviderInUse;
+ }
+
+ @Override
+ public void clearRebootEscrowProvider() {
+ mRebootEscrowProviderInUse = null;
}
@Override
@@ -264,13 +273,15 @@
when(mCallbacks.isUserSecure(NONSECURE_SECONDARY_USER_ID)).thenReturn(false);
when(mCallbacks.isUserSecure(SECURE_SECONDARY_USER_ID)).thenReturn(true);
mInjected = mock(MockableRebootEscrowInjected.class);
- mService = new RebootEscrowManager(new MockInjector(mContext, mUserManager, mRebootEscrow,
- mKeyStoreManager, mStorage, mInjected), mCallbacks, mStorage);
+ mMockInjector = new MockInjector(mContext, mUserManager, mRebootEscrow,
+ mKeyStoreManager, mStorage, mInjected);
+ mService = new RebootEscrowManager(mMockInjector, mCallbacks, mStorage);
}
private void setServerBasedRebootEscrowProvider() throws Exception {
- mService = new RebootEscrowManager(new MockInjector(mContext, mUserManager,
- mServiceConnection, mKeyStoreManager, mStorage, mInjected), mCallbacks, mStorage);
+ mMockInjector = new MockInjector(mContext, mUserManager, mServiceConnection,
+ mKeyStoreManager, mStorage, mInjected);
+ mService = new RebootEscrowManager(mMockInjector, mCallbacks, mStorage);
}
@Test
@@ -317,6 +328,7 @@
doThrow(ServiceSpecificException.class).when(mRebootEscrow).storeKey(any());
mService.clearRebootEscrow();
verify(mRebootEscrow).storeKey(eq(new byte[32]));
+ assertNull(mMockInjector.getRebootEscrowProvider());
}
@Test
@@ -785,7 +797,7 @@
assertNull(
mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM));
// Change the provider to server based, expect the reboot to fail
- when(mInjected.forceServerBased()).thenReturn(true);
+ mMockInjector.mServerBased = true;
assertEquals(ARM_REBOOT_ERROR_PROVIDER_MISMATCH, mService.armRebootEscrowIfNeeded());
assertNull(
mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM));