Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1a00d5e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use better names for associated classes of RecoveryManager"

parents eb7c473f 5f138701
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -17,4 +17,4 @@
package android.security.keystore;
package android.security.keystore;


/* @hide */
/* @hide */
parcelable RecoveryData;
parcelable KeychainProtectionParameter;
+30 −16
Original line number Original line Diff line number Diff line
@@ -28,12 +28,26 @@ import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Arrays;


/**
/**
 * Helper class with data necessary to recover Keystore on a new device.
 * A {@link KeychainSnapshot} is protected with a key derived from the user's lock screen. This
 * It defines UI shown to the user and a way to derive a cryptographic key from user output.
 * class wraps all the data necessary to derive the same key on a recovering device:
 *
 * <ul>
 *     <li>UI parameters for the user's lock screen - so that if e.g., the user was using a pattern,
 *         the recovering device can display the pattern UI to the user when asking them to enter
 *         the lock screen from their previous device.
 *     <li>The algorithm used to derive a key from the user's lock screen, e.g. SHA-256 with a salt.
 * </ul>
 *
 * <p>As such, this data is sent along with the {@link KeychainSnapshot} when syncing the current
 * version of the keychain.
 *
 * <p>For now, the recoverable keychain only supports a single layer of protection, which is the
 * user's lock screen. In the future, the keychain will support multiple layers of protection
 * (e.g. an additional keychain password, along with the lock screen).
 *
 *
 * @hide
 * @hide
 */
 */
public final class RecoveryMetadata implements Parcelable {
public final class KeychainProtectionParameter implements Parcelable {
    /** @hide */
    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({TYPE_LOCKSCREEN, TYPE_CUSTOM_PASSWORD})
    @IntDef({TYPE_LOCKSCREEN, TYPE_CUSTOM_PASSWORD})
@@ -88,7 +102,7 @@ public final class RecoveryMetadata implements Parcelable {
     * @link {#clearSecret} to overwrite its value in memory.
     * @link {#clearSecret} to overwrite its value in memory.
     * @hide
     * @hide
     */
     */
    public RecoveryMetadata(@UserSecretType int userSecretType,
    public KeychainProtectionParameter(@UserSecretType int userSecretType,
            @LockScreenUiFormat int lockScreenUiFormat,
            @LockScreenUiFormat int lockScreenUiFormat,
            @NonNull KeyDerivationParams keyDerivationParams,
            @NonNull KeyDerivationParams keyDerivationParams,
            @NonNull byte[] secret) {
            @NonNull byte[] secret) {
@@ -98,7 +112,7 @@ public final class RecoveryMetadata implements Parcelable {
        mSecret = Preconditions.checkNotNull(secret);
        mSecret = Preconditions.checkNotNull(secret);
    }
    }


    private RecoveryMetadata() {
    private KeychainProtectionParameter() {


    }
    }


@@ -141,10 +155,10 @@ public final class RecoveryMetadata implements Parcelable {
    }
    }


    /**
    /**
     * Builder for creating {@link RecoveryMetadata}.
     * Builder for creating {@link KeychainProtectionParameter}.
     */
     */
    public static class Builder {
    public static class Builder {
        private RecoveryMetadata mInstance = new RecoveryMetadata();
        private KeychainProtectionParameter mInstance = new KeychainProtectionParameter();


        /**
        /**
         * Sets user secret type.
         * Sets user secret type.
@@ -198,14 +212,14 @@ public final class RecoveryMetadata implements Parcelable {




        /**
        /**
         * Creates a new {@link RecoveryMetadata} instance.
         * Creates a new {@link KeychainProtectionParameter} instance.
         * The instance will include default values, if {@link setSecret}
         * The instance will include default values, if {@link setSecret}
         * or {@link setUserSecretType} were not called.
         * or {@link setUserSecretType} were not called.
         *
         *
         * @return new instance
         * @return new instance
         * @throws NullPointerException if some required fields were not set.
         * @throws NullPointerException if some required fields were not set.
         */
         */
        public @NonNull RecoveryMetadata build() {
        @NonNull public KeychainProtectionParameter build() {
            if (mInstance.mUserSecretType == null) {
            if (mInstance.mUserSecretType == null) {
                mInstance.mUserSecretType = TYPE_LOCKSCREEN;
                mInstance.mUserSecretType = TYPE_LOCKSCREEN;
            }
            }
@@ -235,14 +249,14 @@ public final class RecoveryMetadata implements Parcelable {
        Arrays.fill(mSecret, (byte) 0);
        Arrays.fill(mSecret, (byte) 0);
    }
    }


    public static final Parcelable.Creator<RecoveryMetadata> CREATOR =
    public static final Parcelable.Creator<KeychainProtectionParameter> CREATOR =
            new Parcelable.Creator<RecoveryMetadata>() {
            new Parcelable.Creator<KeychainProtectionParameter>() {
        public RecoveryMetadata createFromParcel(Parcel in) {
        public KeychainProtectionParameter createFromParcel(Parcel in) {
            return new RecoveryMetadata(in);
            return new KeychainProtectionParameter(in);
        }
        }


        public RecoveryMetadata[] newArray(int length) {
        public KeychainProtectionParameter[] newArray(int length) {
            return new RecoveryMetadata[length];
            return new KeychainProtectionParameter[length];
        }
        }
    };
    };


@@ -260,7 +274,7 @@ public final class RecoveryMetadata implements Parcelable {
    /**
    /**
     * @hide
     * @hide
     */
     */
    protected RecoveryMetadata(Parcel in) {
    protected KeychainProtectionParameter(Parcel in) {
        mUserSecretType = in.readInt();
        mUserSecretType = in.readInt();
        mLockScreenUiFormat = in.readInt();
        mLockScreenUiFormat = in.readInt();
        mKeyDerivationParams = in.readTypedObject(KeyDerivationParams.CREATOR);
        mKeyDerivationParams = in.readTypedObject(KeyDerivationParams.CREATOR);
+1 −1
Original line number Original line Diff line number Diff line
@@ -17,4 +17,4 @@
package android.security.keystore;
package android.security.keystore;


/* @hide */
/* @hide */
parcelable RecoveryMetadata;
parcelable KeychainSnapshot;
+45 −38
Original line number Original line Diff line number Diff line
@@ -25,42 +25,48 @@ import com.android.internal.util.Preconditions;
import java.util.List;
import java.util.List;


/**
/**
 * Helper class which returns data necessary to recover keys.
 * A snapshot of a version of the keystore. Two events can trigger the generation of a new snapshot:
 * Contains
 *
 *
 * <ul>
 * <ul>
 * <li>Snapshot version.
 *     <li>The user's lock screen changes. (A key derived from the user's lock screen is used to
 * <li>Recovery metadata with UI and key derivation parameters.
 *         protected the keychain, which is why this forces a new snapshot.)
 * <li>List of application keys encrypted by recovery key.
 *     <li>A key is added to or removed from the recoverable keychain.
 * <li>Encrypted recovery key.
 * </ul>
 * </ul>
 *
 *
 * <p>The snapshot data is also encrypted with the remote trusted hardware's public key, so even
 * the recovery agent itself should not be able to decipher the data. The recovery agent sends an
 * instance of this to the remote trusted hardware whenever a new snapshot is generated. During a
 * recovery flow, the recovery agent retrieves a snapshot from the remote trusted hardware. It then
 * sends it to the framework, where it is decrypted using the user's lock screen from their previous
 * device.
 *
 * @hide
 * @hide
 */
 */
public final class RecoveryData implements Parcelable {
public final class KeychainSnapshot implements Parcelable {
    private int mSnapshotVersion;
    private int mSnapshotVersion;
    private List<RecoveryMetadata> mRecoveryMetadata;
    private List<KeychainProtectionParameter> mKeychainProtectionParams;
    private List<EntryRecoveryData> mEntryRecoveryData;
    private List<WrappedApplicationKey> mEntryRecoveryData;
    private byte[] mEncryptedRecoveryKeyBlob;
    private byte[] mEncryptedRecoveryKeyBlob;


    /**
    /**
     * @hide
     * @hide
     * Deprecated, consider using builder.
     * Deprecated, consider using builder.
     */
     */
    public RecoveryData(
    public KeychainSnapshot(
            int snapshotVersion,
            int snapshotVersion,
            @NonNull List<RecoveryMetadata> recoveryMetadata,
            @NonNull List<KeychainProtectionParameter> keychainProtectionParams,
            @NonNull List<EntryRecoveryData> entryRecoveryData,
            @NonNull List<WrappedApplicationKey> wrappedApplicationKeys,
            @NonNull byte[] encryptedRecoveryKeyBlob) {
            @NonNull byte[] encryptedRecoveryKeyBlob) {
        mSnapshotVersion = snapshotVersion;
        mSnapshotVersion = snapshotVersion;
        mRecoveryMetadata =
        mKeychainProtectionParams =
                Preconditions.checkCollectionElementsNotNull(recoveryMetadata, "recoveryMetadata");
                Preconditions.checkCollectionElementsNotNull(keychainProtectionParams,
        mEntryRecoveryData = Preconditions.checkCollectionElementsNotNull(entryRecoveryData,
                        "keychainProtectionParams");
                "entryRecoveryData");
        mEntryRecoveryData = Preconditions.checkCollectionElementsNotNull(wrappedApplicationKeys,
                "wrappedApplicationKeys");
        mEncryptedRecoveryKeyBlob = Preconditions.checkNotNull(encryptedRecoveryKeyBlob);
        mEncryptedRecoveryKeyBlob = Preconditions.checkNotNull(encryptedRecoveryKeyBlob);
    }
    }


    private RecoveryData() {
    private KeychainSnapshot() {


    }
    }


@@ -75,15 +81,15 @@ public final class RecoveryData implements Parcelable {
    /**
    /**
     * UI and key derivation parameters. Note that combination of secrets may be used.
     * UI and key derivation parameters. Note that combination of secrets may be used.
     */
     */
    public @NonNull List<RecoveryMetadata> getRecoveryMetadata() {
    public @NonNull List<KeychainProtectionParameter> getKeychainProtectionParams() {
        return mRecoveryMetadata;
        return mKeychainProtectionParams;
    }
    }


    /**
    /**
     * List of application keys, with key material encrypted by
     * List of application keys, with key material encrypted by
     * the recovery key ({@link #getEncryptedRecoveryKeyBlob}).
     * the recovery key ({@link #getEncryptedRecoveryKeyBlob}).
     */
     */
    public @NonNull List<EntryRecoveryData> getEntryRecoveryData() {
    public @NonNull List<WrappedApplicationKey> getWrappedApplicationKeys() {
        return mEntryRecoveryData;
        return mEntryRecoveryData;
    }
    }


@@ -94,22 +100,22 @@ public final class RecoveryData implements Parcelable {
        return mEncryptedRecoveryKeyBlob;
        return mEncryptedRecoveryKeyBlob;
    }
    }


    public static final Parcelable.Creator<RecoveryData> CREATOR =
    public static final Parcelable.Creator<KeychainSnapshot> CREATOR =
            new Parcelable.Creator<RecoveryData>() {
            new Parcelable.Creator<KeychainSnapshot>() {
        public RecoveryData createFromParcel(Parcel in) {
        public KeychainSnapshot createFromParcel(Parcel in) {
            return new RecoveryData(in);
            return new KeychainSnapshot(in);
        }
        }


        public RecoveryData[] newArray(int length) {
        public KeychainSnapshot[] newArray(int length) {
            return new RecoveryData[length];
            return new KeychainSnapshot[length];
        }
        }
    };
    };


    /**
    /**
     * Builder for creating {@link RecoveryData}.
     * Builder for creating {@link KeychainSnapshot}.
     */
     */
    public static class Builder {
    public static class Builder {
        private RecoveryData mInstance = new RecoveryData();
        private KeychainSnapshot mInstance = new KeychainSnapshot();


        /**
        /**
         * Snapshot version for given account.
         * Snapshot version for given account.
@@ -128,8 +134,9 @@ public final class RecoveryData implements Parcelable {
         * @param recoveryMetadata The UI and key derivation parameters
         * @param recoveryMetadata The UI and key derivation parameters
         * @return This builder.
         * @return This builder.
         */
         */
        public Builder setRecoveryMetadata(@NonNull List<RecoveryMetadata> recoveryMetadata) {
        public Builder setKeychainProtectionParams(
            mInstance.mRecoveryMetadata = recoveryMetadata;
                @NonNull List<KeychainProtectionParameter> recoveryMetadata) {
            mInstance.mKeychainProtectionParams = recoveryMetadata;
            return this;
            return this;
        }
        }


@@ -139,7 +146,7 @@ public final class RecoveryData implements Parcelable {
         * @param entryRecoveryData List of application keys
         * @param entryRecoveryData List of application keys
         * @return This builder.
         * @return This builder.
         */
         */
        public Builder setEntryRecoveryData(List<EntryRecoveryData> entryRecoveryData) {
        public Builder setWrappedApplicationKeys(List<WrappedApplicationKey> entryRecoveryData) {
            mInstance.mEntryRecoveryData = entryRecoveryData;
            mInstance.mEntryRecoveryData = entryRecoveryData;
            return this;
            return this;
        }
        }
@@ -157,13 +164,13 @@ public final class RecoveryData implements Parcelable {




        /**
        /**
         * Creates a new {@link RecoveryData} instance.
         * Creates a new {@link KeychainSnapshot} instance.
         *
         *
         * @return new instance
         * @return new instance
         * @throws NullPointerException if some required fields were not set.
         * @throws NullPointerException if some required fields were not set.
         */
         */
        public @NonNull RecoveryData build() {
        @NonNull public KeychainSnapshot build() {
            Preconditions.checkCollectionElementsNotNull(mInstance.mRecoveryMetadata,
            Preconditions.checkCollectionElementsNotNull(mInstance.mKeychainProtectionParams,
                    "recoveryMetadata");
                    "recoveryMetadata");
            Preconditions.checkCollectionElementsNotNull(mInstance.mEntryRecoveryData,
            Preconditions.checkCollectionElementsNotNull(mInstance.mEntryRecoveryData,
                    "entryRecoveryData");
                    "entryRecoveryData");
@@ -178,7 +185,7 @@ public final class RecoveryData implements Parcelable {
    @Override
    @Override
    public void writeToParcel(Parcel out, int flags) {
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mSnapshotVersion);
        out.writeInt(mSnapshotVersion);
        out.writeTypedList(mRecoveryMetadata);
        out.writeTypedList(mKeychainProtectionParams);
        out.writeByteArray(mEncryptedRecoveryKeyBlob);
        out.writeByteArray(mEncryptedRecoveryKeyBlob);
        out.writeTypedList(mEntryRecoveryData);
        out.writeTypedList(mEntryRecoveryData);
    }
    }
@@ -186,11 +193,11 @@ public final class RecoveryData implements Parcelable {
    /**
    /**
     * @hide
     * @hide
     */
     */
    protected RecoveryData(Parcel in) {
    protected KeychainSnapshot(Parcel in) {
        mSnapshotVersion = in.readInt();
        mSnapshotVersion = in.readInt();
        mRecoveryMetadata = in.createTypedArrayList(RecoveryMetadata.CREATOR);
        mKeychainProtectionParams = in.createTypedArrayList(KeychainProtectionParameter.CREATOR);
        mEncryptedRecoveryKeyBlob = in.createByteArray();
        mEncryptedRecoveryKeyBlob = in.createByteArray();
        mEntryRecoveryData = in.createTypedArrayList(EntryRecoveryData.CREATOR);
        mEntryRecoveryData = in.createTypedArrayList(WrappedApplicationKey.CREATOR);
    }
    }


    @Override
    @Override
+18 −17
Original line number Original line Diff line number Diff line
@@ -99,11 +99,11 @@ public class RecoveryManager {
     * @return Data necessary to recover keystore.
     * @return Data necessary to recover keystore.
     * @hide
     * @hide
     */
     */
    public @NonNull RecoveryData getRecoveryData(@NonNull byte[] account)
    @NonNull public KeychainSnapshot getRecoveryData(@NonNull byte[] account)
            throws RecoveryManagerException {
            throws RecoveryManagerException {
        try {
        try {
            RecoveryData recoveryData = mBinder.getRecoveryData(account);
            KeychainSnapshot keychainSnapshot = mBinder.getRecoveryData(account);
            return recoveryData;
            return keychainSnapshot;
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        } catch (ServiceSpecificException e) {
        } catch (ServiceSpecificException e) {
@@ -136,7 +136,7 @@ public class RecoveryManager {
     * version. Version zero is used, if no snapshots were created for the account.
     * version. Version zero is used, if no snapshots were created for the account.
     *
     *
     * @return Map from recovery agent accounts to snapshot versions.
     * @return Map from recovery agent accounts to snapshot versions.
     * @see RecoveryData#getSnapshotVersion
     * @see KeychainSnapshot#getSnapshotVersion
     * @hide
     * @hide
     */
     */
    public @NonNull Map<byte[], Integer> getRecoverySnapshotVersions()
    public @NonNull Map<byte[], Integer> getRecoverySnapshotVersions()
@@ -156,7 +156,7 @@ public class RecoveryManager {


    /**
    /**
     * Server parameters used to generate new recovery key blobs. This value will be included in
     * Server parameters used to generate new recovery key blobs. This value will be included in
     * {@code RecoveryData.getEncryptedRecoveryKeyBlob()}. The same value must be included
     * {@code KeychainSnapshot.getEncryptedRecoveryKeyBlob()}. The same value must be included
     * in vaultParams {@link #startRecoverySession}
     * in vaultParams {@link #startRecoverySession}
     *
     *
     * @param serverParams included in recovery key blob.
     * @param serverParams included in recovery key blob.
@@ -230,11 +230,11 @@ public class RecoveryManager {
     * Specifies a set of secret types used for end-to-end keystore encryption. Knowing all of them
     * Specifies a set of secret types used for end-to-end keystore encryption. Knowing all of them
     * is necessary to recover data.
     * is necessary to recover data.
     *
     *
     * @param secretTypes {@link RecoveryMetadata#TYPE_LOCKSCREEN} or {@link
     * @param secretTypes {@link KeychainProtectionParameter#TYPE_LOCKSCREEN} or {@link
     *     RecoveryMetadata#TYPE_CUSTOM_PASSWORD}
     *     KeychainProtectionParameter#TYPE_CUSTOM_PASSWORD}
     */
     */
    public void setRecoverySecretTypes(
    public void setRecoverySecretTypes(
            @NonNull @RecoveryMetadata.UserSecretType int[] secretTypes)
            @NonNull @KeychainProtectionParameter.UserSecretType int[] secretTypes)
            throws RecoveryManagerException {
            throws RecoveryManagerException {
        try {
        try {
            mBinder.setRecoverySecretTypes(secretTypes);
            mBinder.setRecoverySecretTypes(secretTypes);
@@ -247,12 +247,12 @@ public class RecoveryManager {


    /**
    /**
     * Defines a set of secret types used for end-to-end keystore encryption. Knowing all of them is
     * Defines a set of secret types used for end-to-end keystore encryption. Knowing all of them is
     * necessary to generate RecoveryData.
     * necessary to generate KeychainSnapshot.
     *
     *
     * @return list of recovery secret types
     * @return list of recovery secret types
     * @see RecoveryData
     * @see KeychainSnapshot
     */
     */
    public @NonNull @RecoveryMetadata.UserSecretType int[] getRecoverySecretTypes()
    @NonNull public @KeychainProtectionParameter.UserSecretType int[] getRecoverySecretTypes()
            throws RecoveryManagerException {
            throws RecoveryManagerException {
        try {
        try {
            return mBinder.getRecoverySecretTypes();
            return mBinder.getRecoverySecretTypes();
@@ -271,7 +271,8 @@ public class RecoveryManager {
     * @return list of recovery secret types
     * @return list of recovery secret types
     * @hide
     * @hide
     */
     */
    public @NonNull @RecoveryMetadata.UserSecretType int[] getPendingRecoverySecretTypes()
    @NonNull
    public @KeychainProtectionParameter.UserSecretType int[] getPendingRecoverySecretTypes()
            throws RecoveryManagerException {
            throws RecoveryManagerException {
        try {
        try {
            return mBinder.getPendingRecoverySecretTypes();
            return mBinder.getPendingRecoverySecretTypes();
@@ -285,14 +286,14 @@ public class RecoveryManager {
    /**
    /**
     * Method notifies KeyStore that a user-generated secret is available. This method generates a
     * Method notifies KeyStore that a user-generated secret is available. This method generates a
     * symmetric session key which a trusted remote device can use to return a recovery key. Caller
     * symmetric session key which a trusted remote device can use to return a recovery key. Caller
     * should use {@link RecoveryMetadata#clearSecret} to override the secret value in
     * should use {@link KeychainProtectionParameter#clearSecret} to override the secret value in
     * memory.
     * memory.
     *
     *
     * @param recoverySecret user generated secret together with parameters necessary to regenerate
     * @param recoverySecret user generated secret together with parameters necessary to regenerate
     *     it on a new device.
     *     it on a new device.
     * @hide
     * @hide
     */
     */
    public void recoverySecretAvailable(@NonNull RecoveryMetadata recoverySecret)
    public void recoverySecretAvailable(@NonNull KeychainProtectionParameter recoverySecret)
            throws RecoveryManagerException {
            throws RecoveryManagerException {
        try {
        try {
            mBinder.recoverySecretAvailable(recoverySecret);
            mBinder.recoverySecretAvailable(recoverySecret);
@@ -326,7 +327,7 @@ public class RecoveryManager {
            @NonNull byte[] verifierPublicKey,
            @NonNull byte[] verifierPublicKey,
            @NonNull byte[] vaultParams,
            @NonNull byte[] vaultParams,
            @NonNull byte[] vaultChallenge,
            @NonNull byte[] vaultChallenge,
            @NonNull List<RecoveryMetadata> secrets)
            @NonNull List<KeychainProtectionParameter> secrets)
            throws RecoveryManagerException {
            throws RecoveryManagerException {
        try {
        try {
            byte[] recoveryClaim =
            byte[] recoveryClaim =
@@ -352,13 +353,13 @@ public class RecoveryManager {
     * @param recoveryKeyBlob Recovery blob encrypted by symmetric key generated for this session.
     * @param recoveryKeyBlob Recovery blob encrypted by symmetric key generated for this session.
     * @param applicationKeys Application keys. Key material can be decrypted using recoveryKeyBlob
     * @param applicationKeys Application keys. Key material can be decrypted using recoveryKeyBlob
     *     and session. KeyStore only uses package names from the application info in {@link
     *     and session. KeyStore only uses package names from the application info in {@link
     *     EntryRecoveryData}. Caller is responsibility to perform certificates check.
     *     WrappedApplicationKey}. Caller is responsibility to perform certificates check.
     * @return Map from alias to raw key material.
     * @return Map from alias to raw key material.
     */
     */
    public Map<String, byte[]> recoverKeys(
    public Map<String, byte[]> recoverKeys(
            @NonNull String sessionId,
            @NonNull String sessionId,
            @NonNull byte[] recoveryKeyBlob,
            @NonNull byte[] recoveryKeyBlob,
            @NonNull List<EntryRecoveryData> applicationKeys)
            @NonNull List<WrappedApplicationKey> applicationKeys)
            throws RecoveryManagerException {
            throws RecoveryManagerException {
        try {
        try {
            return (Map<String, byte[]>) mBinder.recoverKeys(
            return (Map<String, byte[]>) mBinder.recoverKeys(
Loading