diff options
Diffstat (limited to 'android/security/keystore/RecoveryController.java')
-rw-r--r-- | android/security/keystore/RecoveryController.java | 467 |
1 files changed, 0 insertions, 467 deletions
diff --git a/android/security/keystore/RecoveryController.java b/android/security/keystore/RecoveryController.java deleted file mode 100644 index ca67e35b..00000000 --- a/android/security/keystore/RecoveryController.java +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright (C) 2017 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 android.security.keystore; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.PendingIntent; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.RemoteException; -import android.os.ServiceSpecificException; -import android.util.Log; - -import com.android.internal.widget.ILockSettings; - -import java.util.List; -import java.util.Map; - -/** - * @deprecated Use {@link android.security.keystore.recovery.RecoveryController}. - * @hide - */ -public class RecoveryController { - private static final String TAG = "RecoveryController"; - - /** Key has been successfully synced. */ - public static final int RECOVERY_STATUS_SYNCED = 0; - /** Waiting for recovery agent to sync the key. */ - public static final int RECOVERY_STATUS_SYNC_IN_PROGRESS = 1; - /** Recovery account is not available. */ - public static final int RECOVERY_STATUS_MISSING_ACCOUNT = 2; - /** Key cannot be synced. */ - public static final int RECOVERY_STATUS_PERMANENT_FAILURE = 3; - - /** - * Failed because no snapshot is yet pending to be synced for the user. - * - * @hide - */ - public static final int ERROR_NO_SNAPSHOT_PENDING = 21; - - /** - * Failed due to an error internal to the recovery service. This is unexpected and indicates - * either a problem with the logic in the service, or a problem with a dependency of the - * service (such as AndroidKeyStore). - * - * @hide - */ - public static final int ERROR_SERVICE_INTERNAL_ERROR = 22; - - /** - * Failed because the user does not have a lock screen set. - * - * @hide - */ - public static final int ERROR_INSECURE_USER = 23; - - /** - * Error thrown when attempting to use a recovery session that has since been closed. - * - * @hide - */ - public static final int ERROR_SESSION_EXPIRED = 24; - - /** - * Failed because the provided certificate was not a valid X509 certificate. - * - * @hide - */ - public static final int ERROR_BAD_CERTIFICATE_FORMAT = 25; - - /** - * Error thrown if decryption failed. This might be because the tag is wrong, the key is wrong, - * the data has become corrupted, the data has been tampered with, etc. - * - * @hide - */ - public static final int ERROR_DECRYPTION_FAILED = 26; - - - private final ILockSettings mBinder; - - private RecoveryController(ILockSettings binder) { - mBinder = binder; - } - - /** - * Deprecated. - * Gets a new instance of the class. - */ - public static RecoveryController getInstance() { - throw new UnsupportedOperationException("using Deprecated RecoveryController version"); - } - - /** - * Initializes key recovery service for the calling application. RecoveryController - * randomly chooses one of the keys from the list and keeps it to use for future key export - * operations. Collection of all keys in the list must be signed by the provided {@code - * rootCertificateAlias}, which must also be present in the list of root certificates - * preinstalled on the device. The random selection allows RecoveryController to select - * which of a set of remote recovery service devices will be used. - * - * <p>In addition, RecoveryController enforces a delay of three months between - * consecutive initialization attempts, to limit the ability of an attacker to often switch - * remote recovery devices and significantly increase number of recovery attempts. - * - * @param rootCertificateAlias alias of a root certificate preinstalled on the device - * @param signedPublicKeyList binary blob a list of X509 certificates and signature - * @throws BadCertificateFormatException if the {@code signedPublicKeyList} is in a bad format. - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - public void initRecoveryService( - @NonNull String rootCertificateAlias, @NonNull byte[] signedPublicKeyList) - throws BadCertificateFormatException, InternalRecoveryServiceException { - throw new UnsupportedOperationException("Deprecated initRecoveryService method called"); - - } - - /** - * Returns data necessary to store all recoverable keys for given account. Key material is - * encrypted with user secret and recovery public key. - * - * @param account specific to Recovery agent. - * @return Data necessary to recover keystore. - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - public @NonNull KeychainSnapshot getRecoveryData(@NonNull byte[] account) - throws InternalRecoveryServiceException { - try { - return BackwardsCompat.toLegacyKeychainSnapshot(mBinder.getKeyChainSnapshot()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - if (e.errorCode == ERROR_NO_SNAPSHOT_PENDING) { - return null; - } - throw wrapUnexpectedServiceSpecificException(e); - } - } - - /** - * Sets a listener which notifies recovery agent that new recovery snapshot is available. {@link - * #getRecoveryData} can be used to get the snapshot. Note that every recovery agent can have at - * most one registered listener at any time. - * - * @param intent triggered when new snapshot is available. Unregisters listener if the value is - * {@code null}. - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - public void setSnapshotCreatedPendingIntent(@Nullable PendingIntent intent) - throws InternalRecoveryServiceException { - try { - mBinder.setSnapshotCreatedPendingIntent(intent); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - throw wrapUnexpectedServiceSpecificException(e); - } - } - - /** - * Returns a map from recovery agent accounts to corresponding KeyStore recovery snapshot - * version. Version zero is used, if no snapshots were created for the account. - * - * @return Map from recovery agent accounts to snapshot versions. - * @see KeychainSnapshot#getSnapshotVersion - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - public @NonNull Map<byte[], Integer> getRecoverySnapshotVersions() - throws InternalRecoveryServiceException { - throw new UnsupportedOperationException(); - } - - /** - * Server parameters used to generate new recovery key blobs. This value will be included in - * {@code KeychainSnapshot.getEncryptedRecoveryKeyBlob()}. The same value must be included - * in vaultParams {@link #startRecoverySession} - * - * @param serverParams included in recovery key blob. - * @see #getRecoveryData - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - public void setServerParams(byte[] serverParams) throws InternalRecoveryServiceException { - try { - mBinder.setServerParams(serverParams); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - throw wrapUnexpectedServiceSpecificException(e); - } - } - - /** - * Updates recovery status for given keys. It is used to notify keystore that key was - * successfully stored on the server or there were an error. Application can check this value - * using {@code getRecoveyStatus}. - * - * @param packageName Application whose recoverable keys' statuses are to be updated. - * @param aliases List of application-specific key aliases. If the array is empty, updates the - * status for all existing recoverable keys. - * @param status Status specific to recovery agent. - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - public void setRecoveryStatus( - @NonNull String packageName, @Nullable String[] aliases, int status) - throws NameNotFoundException, InternalRecoveryServiceException { - try { - for (String alias : aliases) { - mBinder.setRecoveryStatus(alias, status); - } - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - throw wrapUnexpectedServiceSpecificException(e); - } - } - - /** - * Returns a {@code Map} from Application's KeyStore key aliases to their recovery status. - * Negative status values are reserved for recovery agent specific codes. List of common codes: - * - * <ul> - * <li>{@link #RECOVERY_STATUS_SYNCED} - * <li>{@link #RECOVERY_STATUS_SYNC_IN_PROGRESS} - * <li>{@link #RECOVERY_STATUS_MISSING_ACCOUNT} - * <li>{@link #RECOVERY_STATUS_PERMANENT_FAILURE} - * </ul> - * - * @return {@code Map} from KeyStore alias to recovery status. - * @see #setRecoveryStatus - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - public Map<String, Integer> getRecoveryStatus() throws InternalRecoveryServiceException { - try { - // IPC doesn't support generic Maps. - @SuppressWarnings("unchecked") - Map<String, Integer> result = - (Map<String, Integer>) mBinder.getRecoveryStatus(); - return result; - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - throw wrapUnexpectedServiceSpecificException(e); - } - } - - /** - * Specifies a set of secret types used for end-to-end keystore encryption. Knowing all of them - * is necessary to recover data. - * - * @param secretTypes {@link KeychainProtectionParams#TYPE_LOCKSCREEN} or {@link - * KeychainProtectionParams#TYPE_CUSTOM_PASSWORD} - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - public void setRecoverySecretTypes( - @NonNull @KeychainProtectionParams.UserSecretType int[] secretTypes) - throws InternalRecoveryServiceException { - try { - mBinder.setRecoverySecretTypes(secretTypes); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - throw wrapUnexpectedServiceSpecificException(e); - } - } - - /** - * Defines a set of secret types used for end-to-end keystore encryption. Knowing all of them is - * necessary to generate KeychainSnapshot. - * - * @return list of recovery secret types - * @see KeychainSnapshot - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - public @NonNull @KeychainProtectionParams.UserSecretType int[] getRecoverySecretTypes() - throws InternalRecoveryServiceException { - try { - return mBinder.getRecoverySecretTypes(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - throw wrapUnexpectedServiceSpecificException(e); - } - } - - /** - * Returns a list of recovery secret types, necessary to create a pending recovery snapshot. - * When user enters a secret of a pending type {@link #recoverySecretAvailable} should be - * called. - * - * @return list of recovery secret types - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - @NonNull - public @KeychainProtectionParams.UserSecretType int[] getPendingRecoverySecretTypes() - throws InternalRecoveryServiceException { - throw new UnsupportedOperationException(); - } - - /** - * Initializes recovery session and returns a blob with proof of recovery secrets possession. - * The method generates symmetric key for a session, which trusted remote device can use to - * return recovery key. - * - * @param verifierPublicKey Encoded {@code java.security.cert.X509Certificate} with Public key - * used to create the recovery blob on the source device. - * Keystore will verify the certificate using root of trust. - * @param vaultParams Must match the parameters in the corresponding field in the recovery blob. - * Used to limit number of guesses. - * @param vaultChallenge Data passed from server for this recovery session and used to prevent - * replay attacks - * @param secrets Secrets provided by user, the method only uses type and secret fields. - * @return The recovery claim. Claim provides a b binary blob with recovery claim. It is - * encrypted with verifierPublicKey and contains a proof of user secrets, session symmetric - * key and parameters necessary to identify the counter with the number of failed recovery - * attempts. - * @throws BadCertificateFormatException if the {@code verifierPublicKey} is in an incorrect - * format. - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - @NonNull public RecoveryClaim startRecoverySession( - @NonNull byte[] verifierPublicKey, - @NonNull byte[] vaultParams, - @NonNull byte[] vaultChallenge, - @NonNull List<KeychainProtectionParams> secrets) - throws BadCertificateFormatException, InternalRecoveryServiceException { - try { - RecoverySession recoverySession = RecoverySession.newInstance(this); - byte[] recoveryClaim = - mBinder.startRecoverySession( - recoverySession.getSessionId(), - verifierPublicKey, - vaultParams, - vaultChallenge, - BackwardsCompat.fromLegacyKeychainProtectionParams(secrets)); - return new RecoveryClaim(recoverySession, recoveryClaim); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - if (e.errorCode == ERROR_BAD_CERTIFICATE_FORMAT) { - throw new BadCertificateFormatException(e.getMessage()); - } - throw wrapUnexpectedServiceSpecificException(e); - } - } - - /** - * Imports keys. - * - * @param session Related recovery session, as originally created by invoking - * {@link #startRecoverySession(byte[], byte[], byte[], List)}. - * @param recoveryKeyBlob Recovery blob encrypted by symmetric key generated for this session. - * @param applicationKeys Application keys. Key material can be decrypted using recoveryKeyBlob - * and session. KeyStore only uses package names from the application info in {@link - * WrappedApplicationKey}. Caller is responsibility to perform certificates check. - * @return Map from alias to raw key material. - * @throws SessionExpiredException if {@code session} has since been closed. - * @throws DecryptionFailedException if unable to decrypt the snapshot. - * @throws InternalRecoveryServiceException if an error occurs internal to the recovery service. - */ - public Map<String, byte[]> recoverKeys( - @NonNull RecoverySession session, - @NonNull byte[] recoveryKeyBlob, - @NonNull List<WrappedApplicationKey> applicationKeys) - throws SessionExpiredException, DecryptionFailedException, - InternalRecoveryServiceException { - try { - return (Map<String, byte[]>) mBinder.recoverKeys( - session.getSessionId(), - recoveryKeyBlob, - BackwardsCompat.fromLegacyWrappedApplicationKeys(applicationKeys)); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - if (e.errorCode == ERROR_DECRYPTION_FAILED) { - throw new DecryptionFailedException(e.getMessage()); - } - if (e.errorCode == ERROR_SESSION_EXPIRED) { - throw new SessionExpiredException(e.getMessage()); - } - throw wrapUnexpectedServiceSpecificException(e); - } - } - - /** - * Deletes all data associated with {@code session}. Should not be invoked directly but via - * {@link RecoverySession#close()}. - * - * @hide - */ - void closeSession(RecoverySession session) { - try { - mBinder.closeSession(session.getSessionId()); - } catch (RemoteException | ServiceSpecificException e) { - Log.e(TAG, "Unexpected error trying to close session", e); - } - } - - /** - * Generates a key called {@code alias} and loads it into the recoverable key store. Returns the - * raw material of the key. - * - * @param alias The key alias. - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - * @throws LockScreenRequiredException if the user has not set a lock screen. This is required - * to generate recoverable keys, as the snapshots are encrypted using a key derived from the - * lock screen. - */ - public byte[] generateAndStoreKey(@NonNull String alias) - throws InternalRecoveryServiceException, LockScreenRequiredException { - throw new UnsupportedOperationException(); - } - - /** - * Removes a key called {@code alias} from the recoverable key store. - * - * @param alias The key alias. - * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery - * service. - */ - public void removeKey(@NonNull String alias) throws InternalRecoveryServiceException { - try { - mBinder.removeKey(alias); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - throw wrapUnexpectedServiceSpecificException(e); - } - } - - private InternalRecoveryServiceException wrapUnexpectedServiceSpecificException( - ServiceSpecificException e) { - if (e.errorCode == ERROR_SERVICE_INTERNAL_ERROR) { - return new InternalRecoveryServiceException(e.getMessage()); - } - - // Should never happen. If it does, it's a bug, and we need to update how the method that - // called this throws its exceptions. - return new InternalRecoveryServiceException("Unexpected error code for method: " - + e.errorCode, e); - } -} |