/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.backup.encryption.tasks; import android.content.Context; import android.security.keystore.recovery.InternalRecoveryServiceException; import android.security.keystore.recovery.LockScreenRequiredException; import android.security.keystore.recovery.RecoveryController; import android.util.Slog; import com.android.server.backup.encryption.CryptoSettings; import com.android.server.backup.encryption.client.CryptoBackupServer; import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey; import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager; import java.security.InvalidKeyException; import java.security.UnrecoverableKeyException; import java.util.Collections; import java.util.Optional; /** * Initializes the device for encrypted backup, through generating a secondary key, and setting its * alias in the settings. * *
If the device is already initialized, this is a no-op. */ public class InitializeRecoverableSecondaryKeyTask { private static final String TAG = "InitializeRecoverableSecondaryKeyTask"; private final Context mContext; private final CryptoSettings mCryptoSettings; private final RecoverableKeyStoreSecondaryKeyManager mSecondaryKeyManager; private final CryptoBackupServer mBackupServer; /** * A new instance. * * @param cryptoSettings Settings to store the active key alias. * @param secondaryKeyManager Key manager to generate the new active secondary key. * @param backupServer Server with which to sync the active key alias. */ public InitializeRecoverableSecondaryKeyTask( Context context, CryptoSettings cryptoSettings, RecoverableKeyStoreSecondaryKeyManager secondaryKeyManager, CryptoBackupServer backupServer) { mContext = context; mCryptoSettings = cryptoSettings; mSecondaryKeyManager = secondaryKeyManager; mBackupServer = backupServer; } /** * Initializes the device for encrypted backup, by generating a recoverable secondary key, then * sending that alias to the backup server and saving it in local settings. * *
If there is already an active secondary key then does nothing. If the active secondary key * is destroyed then throws {@link InvalidKeyException}. * *
If a key rotation is pending and able to finish (i.e., the new key has synced with the
* remote trusted hardware module), then it completes the rotation before returning the key.
*
* @return The active secondary key.
* @throws InvalidKeyException if the secondary key is in a bad state.
*/
public RecoverableKeyStoreSecondaryKey run()
throws InvalidKeyException, LockScreenRequiredException, UnrecoverableKeyException,
InternalRecoveryServiceException {
// Complete any pending key rotations
new RotateSecondaryKeyTask(
mContext,
mSecondaryKeyManager,
mBackupServer,
mCryptoSettings,
RecoveryController.getInstance(mContext))
.run();
return runInternal();
}
private RecoverableKeyStoreSecondaryKey runInternal()
throws InvalidKeyException, LockScreenRequiredException, UnrecoverableKeyException,
InternalRecoveryServiceException {
Optional