OSDN Git Service

Big RecoverableKeyStoreLoader refactoring.
authorDmitry Dementyev <dementyev@google.com>
Thu, 11 Jan 2018 21:53:52 +0000 (13:53 -0800)
committerDmitry Dementyev <dementyev@google.com>
Fri, 12 Jan 2018 02:39:18 +0000 (18:39 -0800)
The change is based on API review.
1) package and class names update
2) Builders for Parcelables.
3) Use Constant for RECOVER_KEYSTORE permission defined in
android.Manifest.

Bug: 66499222
Test: adb shell am instrument -w -e package \
com.android.server.locksettings.recoverablekeystore \
com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner

Change-Id: I49f80acbb6dc0eb6d049e18e8cb0d1aa326dadb2

24 files changed:
core/java/android/security/keystore/EntryRecoveryData.aidl [moved from core/java/android/security/recoverablekeystore/KeyStoreRecoveryData.aidl with 88% similarity]
core/java/android/security/keystore/EntryRecoveryData.java [new file with mode: 0644]
core/java/android/security/keystore/KeyDerivationParameters.aidl [moved from core/java/android/security/recoverablekeystore/KeyDerivationParameters.aidl with 93% similarity]
core/java/android/security/keystore/KeyDerivationParameters.java [moved from core/java/android/security/recoverablekeystore/KeyDerivationParameters.java with 96% similarity]
core/java/android/security/keystore/RecoveryData.aidl [moved from core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.aidl with 88% similarity]
core/java/android/security/keystore/RecoveryData.java [new file with mode: 0644]
core/java/android/security/keystore/RecoveryManager.java [moved from core/java/android/security/recoverablekeystore/RecoverableKeyStoreLoader.java with 75% similarity]
core/java/android/security/keystore/RecoveryMetadata.aidl [moved from core/java/android/security/recoverablekeystore/KeyStoreRecoveryMetadata.aidl with 88% similarity]
core/java/android/security/keystore/RecoveryMetadata.java [moved from core/java/android/security/recoverablekeystore/KeyStoreRecoveryMetadata.java with 53% similarity]
core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.java [deleted file]
core/java/android/security/recoverablekeystore/KeyStoreRecoveryData.java [deleted file]
core/java/com/android/internal/widget/ILockSettings.aidl
services/core/java/com/android/server/locksettings/LockSettingsService.java
services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java
services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java
services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java
services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbContract.java
services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverySnapshotStorage.java
services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverySnapshotStorageTest.java

@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security.recoverablekeystore;
+package android.security.keystore;
 
 /* @hide */
-parcelable KeyStoreRecoveryData;
+parcelable EntryRecoveryData;
diff --git a/core/java/android/security/keystore/EntryRecoveryData.java b/core/java/android/security/keystore/EntryRecoveryData.java
new file mode 100644 (file)
index 0000000..aaca3fe
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * 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.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Helper class with data necessary recover a single application key, given a recovery key.
+ *
+ * <ul>
+ *   <li>Alias - Keystore alias of the key.
+ *   <li>Encrypted key material.
+ * </ul>
+ *
+ * Note that Application info is not included. Recovery Agent can only make its own keys
+ * recoverable.
+ *
+ * @hide
+ */
+public final class EntryRecoveryData implements Parcelable {
+    private String mAlias;
+    // The only supported format is AES-256 symmetric key.
+    private byte[] mEncryptedKeyMaterial;
+
+    /**
+     * Builder for creating {@link EntryRecoveryData}.
+     */
+    public static class Builder {
+        private EntryRecoveryData mInstance = new EntryRecoveryData();
+
+        /**
+         * Sets Application-specific alias of the key.
+         *
+         * @param alias The alias.
+         * @return This builder.
+         */
+        public Builder setAlias(@NonNull String alias) {
+            mInstance.mAlias = alias;
+            return this;
+        }
+
+        /**
+         * Sets key material encrypted by recovery key.
+         *
+         * @param encryptedKeyMaterial The key material
+         * @return This builder
+         */
+
+        public Builder setEncryptedKeyMaterial(@NonNull byte[] encryptedKeyMaterial) {
+            mInstance.mEncryptedKeyMaterial = encryptedKeyMaterial;
+            return this;
+        }
+
+        /**
+         * Creates a new {@link EntryRecoveryData} instance.
+         *
+         * @return new instance
+         * @throws NullPointerException if some required fields were not set.
+         */
+        public @NonNull EntryRecoveryData build() {
+            Preconditions.checkNotNull(mInstance.mAlias);
+            Preconditions.checkNotNull(mInstance.mEncryptedKeyMaterial);
+            return mInstance;
+        }
+    }
+
+    private EntryRecoveryData() {
+
+    }
+
+    /**
+     * Deprecated - consider using Builder.
+     * @hide
+     */
+    public EntryRecoveryData(@NonNull String alias, @NonNull byte[] encryptedKeyMaterial) {
+        mAlias = Preconditions.checkNotNull(alias);
+        mEncryptedKeyMaterial = Preconditions.checkNotNull(encryptedKeyMaterial);
+    }
+
+    /**
+     * Application-specific alias of the key.
+     *
+     * @see java.security.KeyStore.aliases
+     */
+    public @NonNull String getAlias() {
+        return mAlias;
+    }
+
+    /** Key material encrypted by recovery key. */
+    public @NonNull byte[] getEncryptedKeyMaterial() {
+        return mEncryptedKeyMaterial;
+    }
+
+    public static final Parcelable.Creator<EntryRecoveryData> CREATOR =
+            new Parcelable.Creator<EntryRecoveryData>() {
+                public EntryRecoveryData createFromParcel(Parcel in) {
+                    return new EntryRecoveryData(in);
+                }
+
+                public EntryRecoveryData[] newArray(int length) {
+                    return new EntryRecoveryData[length];
+                }
+            };
+
+    /**
+     * @hide
+     */
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mAlias);
+        out.writeByteArray(mEncryptedKeyMaterial);
+    }
+
+    /**
+     * @hide
+     */
+    protected EntryRecoveryData(Parcel in) {
+        mAlias = in.readString();
+        mEncryptedKeyMaterial = in.createByteArray();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security.recoverablekeystore;
+package android.security.keystore;
 
 /* @hide */
 parcelable KeyDerivationParameters;
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security.recoverablekeystore;
+package android.security.keystore;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -48,11 +48,13 @@ public final class KeyDerivationParameters implements Parcelable {
 
     /**
      * Salted SHA256
+     * @hide
      */
     public static final int ALGORITHM_SHA256 = 1;
 
     /**
      * Argon2ID
+     * @hide
      */
     // TODO: add Argon2ID support.
     public static final int ALGORITHM_ARGON2ID = 2;
@@ -94,12 +96,18 @@ public final class KeyDerivationParameters implements Parcelable {
         }
     };
 
+    /**
+     * @hide
+     */
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mAlgorithm);
         out.writeByteArray(mSalt);
     }
 
+    /**
+     * @hide
+     */
     protected KeyDerivationParameters(Parcel in) {
         mAlgorithm = in.readInt();
         mSalt = in.createByteArray();
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security.recoverablekeystore;
+package android.security.keystore;
 
 /* @hide */
-parcelable KeyEntryRecoveryData;
+parcelable RecoveryData;
diff --git a/core/java/android/security/keystore/RecoveryData.java b/core/java/android/security/keystore/RecoveryData.java
new file mode 100644 (file)
index 0000000..c717d9a
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * 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.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.List;
+
+/**
+ * Helper class which returns data necessary to recover keys.
+ * Contains
+ *
+ * <ul>
+ * <li>Snapshot version.
+ * <li>Recovery metadata with UI and key derivation parameters.
+ * <li>List of application keys encrypted by recovery key.
+ * <li>Encrypted recovery key.
+ * </ul>
+ *
+ * @hide
+ */
+public final class RecoveryData implements Parcelable {
+    private Integer mSnapshotVersion;
+    private List<RecoveryMetadata> mRecoveryMetadata;
+    private List<EntryRecoveryData> mEntryRecoveryData;
+    private byte[] mEncryptedRecoveryKeyBlob;
+
+    /**
+     * @hide
+     * Deprecated, consider using builder.
+     */
+    public RecoveryData(
+            int snapshotVersion,
+            @NonNull List<RecoveryMetadata> recoveryMetadata,
+            @NonNull List<EntryRecoveryData> entryRecoveryData,
+            @NonNull byte[] encryptedRecoveryKeyBlob) {
+        mSnapshotVersion = snapshotVersion;
+        mRecoveryMetadata =
+                Preconditions.checkCollectionElementsNotNull(recoveryMetadata, "recoveryMetadata");
+        mEntryRecoveryData = Preconditions.checkCollectionElementsNotNull(entryRecoveryData,
+                "entryRecoveryData");
+        mEncryptedRecoveryKeyBlob = Preconditions.checkNotNull(encryptedRecoveryKeyBlob);
+    }
+
+    private RecoveryData() {
+
+    }
+
+    /**
+     * Snapshot version for given account. It is incremented when user secret or list of application
+     * keys changes.
+     */
+    public int getSnapshotVersion() {
+        return mSnapshotVersion;
+    }
+
+    /**
+     * UI and key derivation parameters. Note that combination of secrets may be used.
+     */
+    public @NonNull List<RecoveryMetadata> getRecoveryMetadata() {
+        return mRecoveryMetadata;
+    }
+
+    /**
+     * List of application keys, with key material encrypted by
+     * the recovery key ({@link #getEncryptedRecoveryKeyBlob}).
+     */
+    public @NonNull List<EntryRecoveryData> getEntryRecoveryData() {
+        return mEntryRecoveryData;
+    }
+
+    /**
+     * Recovery key blob, encrypted by user secret and recovery service public key.
+     */
+    public @NonNull byte[] getEncryptedRecoveryKeyBlob() {
+        return mEncryptedRecoveryKeyBlob;
+    }
+
+    public static final Parcelable.Creator<RecoveryData> CREATOR =
+            new Parcelable.Creator<RecoveryData>() {
+        public RecoveryData createFromParcel(Parcel in) {
+            return new RecoveryData(in);
+        }
+
+        public RecoveryData[] newArray(int length) {
+            return new RecoveryData[length];
+        }
+    };
+
+    /**
+     * Builder for creating {@link RecoveryData}.
+     */
+    public static class Builder {
+        private RecoveryData mInstance = new RecoveryData();
+
+        /**
+         * Snapshot version for given account.
+         *
+         * @param snapshotVersion The snapshot version
+         * @return This builder.
+         */
+        public Builder setSnapshotVersion(int snapshotVersion) {
+            mInstance.mSnapshotVersion = snapshotVersion;
+            return this;
+        }
+
+        /**
+         * Sets UI and key derivation parameters
+         *
+         * @param recoveryMetadata The UI and key derivation parameters
+         * @return This builder.
+         */
+        public Builder setRecoveryMetadata(@NonNull List<RecoveryMetadata> recoveryMetadata) {
+            mInstance.mRecoveryMetadata = recoveryMetadata;
+            return this;
+        }
+
+        /**
+         * List of application keys.
+         *
+         * @param entryRecoveryData List of application keys
+         * @return This builder.
+         */
+        public Builder setEntryRecoveryData(List<EntryRecoveryData> entryRecoveryData) {
+            mInstance.mEntryRecoveryData = entryRecoveryData;
+            return this;
+        }
+
+        /**
+         * Sets recovery key blob
+         *
+         * @param encryptedRecoveryKeyBlob The recovery key blob.
+         * @return This builder.
+         */
+        public Builder setEncryptedRecoveryKeyBlob(@NonNull byte[] encryptedRecoveryKeyBlob) {
+            mInstance.mEncryptedRecoveryKeyBlob = encryptedRecoveryKeyBlob;
+            return this;
+        }
+
+
+        /**
+         * Creates a new {@link RecoveryData} instance.
+         *
+         * @return new instance
+         * @throws NullPointerException if some required fields were not set.
+         */
+        public @NonNull RecoveryData build() {
+            Preconditions.checkNotNull(mInstance.mSnapshotVersion);
+            Preconditions.checkCollectionElementsNotNull(mInstance.mRecoveryMetadata,
+                    "recoveryMetadata");
+            Preconditions.checkCollectionElementsNotNull(mInstance.mEntryRecoveryData,
+                    "entryRecoveryData");
+            Preconditions.checkNotNull(mInstance.mEncryptedRecoveryKeyBlob);
+            return mInstance;
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mSnapshotVersion);
+        out.writeTypedList(mRecoveryMetadata);
+        out.writeByteArray(mEncryptedRecoveryKeyBlob);
+        out.writeTypedList(mEntryRecoveryData);
+    }
+
+    /**
+     * @hide
+     */
+    protected RecoveryData(Parcel in) {
+        mSnapshotVersion = in.readInt();
+        mRecoveryMetadata = in.createTypedArrayList(RecoveryMetadata.CREATOR);
+        mEncryptedRecoveryKeyBlob = in.createByteArray();
+        mEntryRecoveryData = in.createTypedArrayList(EntryRecoveryData.CREATOR);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security.recoverablekeystore;
+package android.security.keystore;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -37,9 +37,7 @@ import java.util.Map;
  *
  * @hide
  */
-public class RecoverableKeyStoreLoader {
-
-    public static final String PERMISSION_RECOVER_KEYSTORE = "android.permission.RECOVER_KEYSTORE";
+public class RecoveryManager {
 
     public static final int NO_ERROR = KeyStore.NO_ERROR;
     public static final int SYSTEM_ERROR = KeyStore.SYSTEM_ERROR;
@@ -110,50 +108,50 @@ public class RecoverableKeyStoreLoader {
 
     private final ILockSettings mBinder;
 
-    private RecoverableKeyStoreLoader(ILockSettings binder) {
+    private RecoveryManager(ILockSettings binder) {
         mBinder = binder;
     }
 
-    /** @hide */
-    public static RecoverableKeyStoreLoader getInstance() {
+    /**
+     * Gets a new instance of the class.
+     */
+    public static RecoveryManager getInstance() {
         ILockSettings lockSettings =
                 ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings"));
-        return new RecoverableKeyStoreLoader(lockSettings);
+        return new RecoveryManager(lockSettings);
     }
 
     /**
-     * Exceptions returned by {@link RecoverableKeyStoreLoader}.
-     *
-     * @hide
+     * Exceptions returned by {@link RecoveryManager}.
      */
-    public static class RecoverableKeyStoreLoaderException extends AndroidException {
+    public static class RecoveryManagerException extends AndroidException {
         private int mErrorCode;
 
         /**
-         * Creates new {@link #RecoverableKeyStoreLoaderException} instance from the error code.
+         * Creates new {@link #RecoveryManagerException} instance from the error code.
          *
          * @param errorCode An error code, as listed at the top of this file.
          * @param message The associated error message.
          * @hide
          */
-        public static RecoverableKeyStoreLoaderException fromErrorCode(
+        public static RecoveryManagerException fromErrorCode(
                 int errorCode, String message) {
-            return new RecoverableKeyStoreLoaderException(errorCode, message);
+            return new RecoveryManagerException(errorCode, message);
         }
 
         /**
-         * Creates new {@link #RecoverableKeyStoreLoaderException} from {@link
+         * Creates new {@link #RecoveryManagerException} from {@link
          * ServiceSpecificException}.
          *
          * @param e exception thrown on service side.
          * @hide
          */
-        static RecoverableKeyStoreLoaderException fromServiceSpecificException(
-                ServiceSpecificException e) throws RecoverableKeyStoreLoaderException {
-            throw RecoverableKeyStoreLoaderException.fromErrorCode(e.errorCode, e.getMessage());
+        static RecoveryManagerException fromServiceSpecificException(
+                ServiceSpecificException e) throws RecoveryManagerException {
+            throw RecoveryManagerException.fromErrorCode(e.errorCode, e.getMessage());
         }
 
-        private RecoverableKeyStoreLoaderException(int errorCode, String message) {
+        private RecoveryManagerException(int errorCode, String message) {
             super(message);
             mErrorCode = errorCode;
         }
@@ -165,32 +163,32 @@ public class RecoverableKeyStoreLoader {
     }
 
     /**
-     * Initializes key recovery service for the calling application. RecoverableKeyStoreLoader
+     * Initializes key recovery service for the calling application. RecoveryManager
      * 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 RecoverableKeyStoreLoader to select
+     * preinstalled on the device. The random selection allows RecoveryManager to select
      * which of a set of remote recovery service devices will be used.
      *
-     * <p>In addition, RecoverableKeyStoreLoader enforces a delay of three months between
+     * <p>In addition, RecoveryManager 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 RecoverableKeyStoreLoaderException if signature is invalid, or key rotation was rate
+     * @throws RecoveryManagerException if signature is invalid, or key rotation was rate
      *     limited.
      * @hide
      */
     public void initRecoveryService(
             @NonNull String rootCertificateAlias, @NonNull byte[] signedPublicKeyList)
-            throws RecoverableKeyStoreLoaderException {
+            throws RecoveryManagerException {
         try {
             mBinder.initRecoveryService(rootCertificateAlias, signedPublicKeyList);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
@@ -202,15 +200,15 @@ public class RecoverableKeyStoreLoader {
      * @return Data necessary to recover keystore.
      * @hide
      */
-    public @NonNull KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account)
-            throws RecoverableKeyStoreLoaderException {
+    public @NonNull RecoveryData getRecoveryData(@NonNull byte[] account)
+            throws RecoveryManagerException {
         try {
-            KeyStoreRecoveryData recoveryData = mBinder.getRecoveryData(account);
+            RecoveryData recoveryData = mBinder.getRecoveryData(account);
             return recoveryData;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
@@ -224,13 +222,13 @@ public class RecoverableKeyStoreLoader {
      * @hide
      */
     public void setSnapshotCreatedPendingIntent(@Nullable PendingIntent intent)
-            throws RecoverableKeyStoreLoaderException {
+            throws RecoveryManagerException {
         try {
             mBinder.setSnapshotCreatedPendingIntent(intent);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
@@ -239,11 +237,11 @@ public class RecoverableKeyStoreLoader {
      * version. Version zero is used, if no snapshots were created for the account.
      *
      * @return Map from recovery agent accounts to snapshot versions.
-     * @see KeyStoreRecoveryData#getSnapshotVersion
+     * @see RecoveryData#getSnapshotVersion
      * @hide
      */
     public @NonNull Map<byte[], Integer> getRecoverySnapshotVersions()
-            throws RecoverableKeyStoreLoaderException {
+            throws RecoveryManagerException {
         try {
             // IPC doesn't support generic Maps.
             @SuppressWarnings("unchecked")
@@ -253,28 +251,28 @@ public class RecoverableKeyStoreLoader {
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
     /**
      * Server parameters used to generate new recovery key blobs. This value will be included in
-     * {@code KeyStoreRecoveryData.getEncryptedRecoveryKeyBlob()}. The same value must be included
+     * {@code RecoveryData.getEncryptedRecoveryKeyBlob()}. The same value must be included
      * in vaultParams {@link #startRecoverySession}
      *
      * @param serverParameters included in recovery key blob.
      * @see #getRecoveryData
-     * @throws RecoverableKeyStoreLoaderException If parameters rotation is rate limited.
+     * @throws RecoveryManagerException If parameters rotation is rate limited.
      * @hide
      */
     public void setServerParameters(long serverParameters)
-            throws RecoverableKeyStoreLoaderException {
+            throws RecoveryManagerException {
         try {
             mBinder.setServerParameters(serverParameters);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
@@ -290,13 +288,13 @@ public class RecoverableKeyStoreLoader {
      */
     public void setRecoveryStatus(
             @NonNull String packageName, @Nullable String[] aliases, int status)
-            throws NameNotFoundException, RecoverableKeyStoreLoaderException {
+            throws NameNotFoundException, RecoveryManagerException {
         try {
             mBinder.setRecoveryStatus(packageName, aliases, status);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
@@ -318,7 +316,7 @@ public class RecoverableKeyStoreLoader {
      * @hide
      */
     public Map<String, Integer> getRecoveryStatus(@Nullable String packageName)
-            throws RecoverableKeyStoreLoaderException {
+            throws RecoveryManagerException {
         try {
             // IPC doesn't support generic Maps.
             @SuppressWarnings("unchecked")
@@ -329,7 +327,7 @@ public class RecoverableKeyStoreLoader {
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
@@ -337,36 +335,36 @@ public class RecoverableKeyStoreLoader {
      * 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 KeyStoreRecoveryMetadata#TYPE_LOCKSCREEN} or {@link
-     *     KeyStoreRecoveryMetadata#TYPE_CUSTOM_PASSWORD}
+     * @param secretTypes {@link RecoveryMetadata#TYPE_LOCKSCREEN} or {@link
+     *     RecoveryMetadata#TYPE_CUSTOM_PASSWORD}
      */
     public void setRecoverySecretTypes(
-            @NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] secretTypes)
-            throws RecoverableKeyStoreLoaderException {
+            @NonNull @RecoveryMetadata.UserSecretType int[] secretTypes)
+            throws RecoveryManagerException {
         try {
             mBinder.setRecoverySecretTypes(secretTypes);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
     /**
      * Defines a set of secret types used for end-to-end keystore encryption. Knowing all of them is
-     * necessary to generate KeyStoreRecoveryData.
+     * necessary to generate RecoveryData.
      *
      * @return list of recovery secret types
-     * @see KeyStoreRecoveryData
+     * @see RecoveryData
      */
-    public @NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] getRecoverySecretTypes()
-            throws RecoverableKeyStoreLoaderException {
+    public @NonNull @RecoveryMetadata.UserSecretType int[] getRecoverySecretTypes()
+            throws RecoveryManagerException {
         try {
             return mBinder.getRecoverySecretTypes();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
@@ -376,35 +374,37 @@ public class RecoverableKeyStoreLoader {
      * called.
      *
      * @return list of recovery secret types
+     * @hide
      */
-    public @NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] getPendingRecoverySecretTypes()
-            throws RecoverableKeyStoreLoaderException {
+    public @NonNull @RecoveryMetadata.UserSecretType int[] getPendingRecoverySecretTypes()
+            throws RecoveryManagerException {
         try {
             return mBinder.getPendingRecoverySecretTypes();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
     /**
      * 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
-     * should use {@link KeyStoreRecoveryMetadata#clearSecret} to override the secret value in
+     * should use {@link RecoveryMetadata#clearSecret} to override the secret value in
      * memory.
      *
      * @param recoverySecret user generated secret together with parameters necessary to regenerate
      *     it on a new device.
+     * @hide
      */
-    public void recoverySecretAvailable(@NonNull KeyStoreRecoveryMetadata recoverySecret)
-            throws RecoverableKeyStoreLoaderException {
+    public void recoverySecretAvailable(@NonNull RecoveryMetadata recoverySecret)
+            throws RecoveryManagerException {
         try {
             mBinder.recoverySecretAvailable(recoverySecret);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
@@ -430,8 +430,8 @@ public class RecoverableKeyStoreLoader {
             @NonNull byte[] verifierPublicKey,
             @NonNull byte[] vaultParams,
             @NonNull byte[] vaultChallenge,
-            @NonNull List<KeyStoreRecoveryMetadata> secrets)
-            throws RecoverableKeyStoreLoaderException {
+            @NonNull List<RecoveryMetadata> secrets)
+            throws RecoveryManagerException {
         try {
             byte[] recoveryClaim =
                     mBinder.startRecoverySession(
@@ -444,7 +444,7 @@ public class RecoverableKeyStoreLoader {
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
@@ -456,21 +456,21 @@ public class RecoverableKeyStoreLoader {
      * @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
-     *     KeyEntryRecoveryData}. Caller is responsibility to perform certificates check.
+     *     EntryRecoveryData}. Caller is responsibility to perform certificates check.
      * @return Map from alias to raw key material.
      */
     public Map<String, byte[]> recoverKeys(
             @NonNull String sessionId,
             @NonNull byte[] recoveryKeyBlob,
-            @NonNull List<KeyEntryRecoveryData> applicationKeys)
-            throws RecoverableKeyStoreLoaderException {
+            @NonNull List<EntryRecoveryData> applicationKeys)
+            throws RecoveryManagerException {
         try {
             return (Map<String, byte[]>) mBinder.recoverKeys(
                     sessionId, recoveryKeyBlob, applicationKeys);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
@@ -479,17 +479,17 @@ public class RecoverableKeyStoreLoader {
      * raw material of the key.
      *
      * @param alias The key alias.
-     * @throws RecoverableKeyStoreLoaderException if an error occurred generating and storing the
+     * @throws RecoveryManagerException if an error occurred generating and storing the
      *     key.
      */
     public byte[] generateAndStoreKey(@NonNull String alias)
-            throws RecoverableKeyStoreLoaderException {
+            throws RecoveryManagerException {
         try {
             return mBinder.generateAndStoreKey(alias);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 
@@ -498,13 +498,13 @@ public class RecoverableKeyStoreLoader {
      *
      * @param alias The key alias.
      */
-    public void removeKey(@NonNull String alias) throws RecoverableKeyStoreLoaderException {
+    public void removeKey(@NonNull String alias) throws RecoveryManagerException {
         try {
             mBinder.removeKey(alias);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
-            throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+            throw RecoveryManagerException.fromServiceSpecificException(e);
         }
     }
 }
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security.recoverablekeystore;
+package android.security.keystore;
 
 /* @hide */
-parcelable KeyStoreRecoveryMetadata;
+parcelable RecoveryMetadata;
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security.recoverablekeystore;
+package android.security.keystore;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -33,7 +33,7 @@ import java.util.Arrays;
  *
  * @hide
  */
-public final class KeyStoreRecoveryMetadata implements Parcelable {
+public final class RecoveryMetadata implements Parcelable {
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({TYPE_LOCKSCREEN, TYPE_CUSTOM_PASSWORD})
@@ -43,12 +43,12 @@ public final class KeyStoreRecoveryMetadata implements Parcelable {
     /**
      * Lockscreen secret is required to recover KeyStore.
      */
-    public static final int TYPE_LOCKSCREEN = 1;
+    public static final int TYPE_LOCKSCREEN = 100;
 
     /**
      * Custom passphrase, unrelated to lock screen, is required to recover KeyStore.
      */
-    public static final int TYPE_CUSTOM_PASSWORD = 2;
+    public static final int TYPE_CUSTOM_PASSWORD = 101;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -72,10 +72,10 @@ public final class KeyStoreRecoveryMetadata implements Parcelable {
     public static final int TYPE_PATTERN = 3;
 
     @UserSecretType
-    private final int mUserSecretType;
+    private Integer mUserSecretType;
 
     @LockScreenUiFormat
-    private final int mLockScreenUiFormat;
+    private Integer mLockScreenUiFormat;
 
     /**
      * Parameters of key derivation function, including algorithm, difficulty, salt.
@@ -86,22 +86,37 @@ public final class KeyStoreRecoveryMetadata implements Parcelable {
     /**
      * @param secret Constructor creates a reference to the secret. Caller must use
      * @link {#clearSecret} to overwrite its value in memory.
+     * @hide
      */
-    public KeyStoreRecoveryMetadata(@UserSecretType int userSecretType,
+    public RecoveryMetadata(@UserSecretType int userSecretType,
             @LockScreenUiFormat int lockScreenUiFormat,
-            @NonNull KeyDerivationParameters keyDerivationParameters, @NonNull byte[] secret) {
+            @NonNull KeyDerivationParameters keyDerivationParameters,
+            @NonNull byte[] secret) {
         mUserSecretType = userSecretType;
         mLockScreenUiFormat = lockScreenUiFormat;
         mKeyDerivationParameters = Preconditions.checkNotNull(keyDerivationParameters);
         mSecret = Preconditions.checkNotNull(secret);
     }
 
+    private RecoveryMetadata() {
+
+    }
+
+    /**
+     * @see TYPE_LOCKSCREEN
+     * @see TYPE_CUSTOM_PASSWORD
+     */
+    public @UserSecretType int getUserSecretType() {
+        return mUserSecretType;
+    }
+
     /**
      * Specifies UX shown to user during recovery.
+     * Default value is {@code TYPE_LOCKSCREEN}
      *
-     * @see KeyStore.TYPE_PIN
-     * @see KeyStore.TYPE_PASSWORD
-     * @see KeyStore.TYPE_PATTERN
+     * @see TYPE_PIN
+     * @see TYPE_PASSWORD
+     * @see TYPE_PATTERN
      */
     public @LockScreenUiFormat int getLockScreenUiFormat() {
         return mLockScreenUiFormat;
@@ -116,18 +131,91 @@ public final class KeyStoreRecoveryMetadata implements Parcelable {
     }
 
     /**
-     * Secret string derived from user input.
+     * Secret derived from user input.
+     * Default value is empty array
+     *
+     * @return secret or empty array
      */
     public @NonNull byte[] getSecret() {
         return mSecret;
     }
 
     /**
-     * @see KeyStore.TYPE_LOCKSCREEN
-     * @see KeyStore.TYPE_CUSTOM_PASSWORD
+     * Builder for creating {@link RecoveryMetadata}.
      */
-    public @UserSecretType int getUserSecretType() {
-        return mUserSecretType;
+    public static class Builder {
+        private RecoveryMetadata mInstance = new RecoveryMetadata();
+
+        /**
+         * Sets user secret type.
+         *
+         * @see TYPE_LOCKSCREEN
+         * @see TYPE_CUSTOM_PASSWORD
+         * @param userSecretType The secret type
+         * @return This builder.
+         */
+        public Builder setUserSecretType(@UserSecretType int userSecretType) {
+            mInstance.mUserSecretType = userSecretType;
+            return this;
+        }
+
+        /**
+         * Sets UI format.
+         *
+         * @see TYPE_PIN
+         * @see TYPE_PASSWORD
+         * @see TYPE_PATTERN
+         * @param lockScreenUiFormat The UI format
+         * @return This builder.
+         */
+        public Builder setLockScreenUiFormat(@LockScreenUiFormat int lockScreenUiFormat) {
+            mInstance.mLockScreenUiFormat = lockScreenUiFormat;
+            return this;
+        }
+
+        /**
+         * Sets parameters of the key derivation function.
+         *
+         * @param keyDerivationParameters Key derivation parameters
+         * @return This builder.
+         */
+        public Builder setKeyDerivationParameters(@NonNull KeyDerivationParameters
+                keyDerivationParameters) {
+            mInstance.mKeyDerivationParameters = keyDerivationParameters;
+            return this;
+        }
+
+        /**
+         * Secret derived from user input, or empty array.
+         *
+         * @param secret The secret.
+         * @return This builder.
+         */
+        public Builder setSecret(@NonNull byte[] secret) {
+            mInstance.mSecret = secret;
+            return this;
+        }
+
+
+        /**
+         * Creates a new {@link RecoveryMetadata} instance.
+         * The instance will include default values, if {@link setSecret}
+         * or {@link setUserSecretType} were not called.
+         *
+         * @return new instance
+         * @throws NullPointerException if some required fields were not set.
+         */
+        public @NonNull RecoveryMetadata build() {
+            if (mInstance.mUserSecretType == null) {
+                mInstance.mUserSecretType = TYPE_LOCKSCREEN;
+            }
+            Preconditions.checkNotNull(mInstance.mLockScreenUiFormat);
+            Preconditions.checkNotNull(mInstance.mKeyDerivationParameters);
+            if (mInstance.mSecret == null) {
+                mInstance.mSecret = new byte[]{};
+            }
+            return mInstance;
+        }
     }
 
     /**
@@ -147,17 +235,20 @@ public final class KeyStoreRecoveryMetadata implements Parcelable {
         Arrays.fill(mSecret, (byte) 0);
     }
 
-    public static final Parcelable.Creator<KeyStoreRecoveryMetadata> CREATOR =
-            new Parcelable.Creator<KeyStoreRecoveryMetadata>() {
-        public KeyStoreRecoveryMetadata createFromParcel(Parcel in) {
-            return new KeyStoreRecoveryMetadata(in);
+    public static final Parcelable.Creator<RecoveryMetadata> CREATOR =
+            new Parcelable.Creator<RecoveryMetadata>() {
+        public RecoveryMetadata createFromParcel(Parcel in) {
+            return new RecoveryMetadata(in);
         }
 
-        public KeyStoreRecoveryMetadata[] newArray(int length) {
-            return new KeyStoreRecoveryMetadata[length];
+        public RecoveryMetadata[] newArray(int length) {
+            return new RecoveryMetadata[length];
         }
     };
 
+    /**
+     * @hide
+     */
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mUserSecretType);
@@ -166,7 +257,10 @@ public final class KeyStoreRecoveryMetadata implements Parcelable {
         out.writeByteArray(mSecret);
     }
 
-    protected KeyStoreRecoveryMetadata(Parcel in) {
+    /**
+     * @hide
+     */
+    protected RecoveryMetadata(Parcel in) {
         mUserSecretType = in.readInt();
         mLockScreenUiFormat = in.readInt();
         mKeyDerivationParameters = in.readTypedObject(KeyDerivationParameters.CREATOR);
diff --git a/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.java b/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.java
deleted file mode 100644 (file)
index 5f56c91..0000000
+++ /dev/null
@@ -1,88 +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.recoverablekeystore;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.util.Preconditions;
-
-/**
- * Helper class with data necessary recover a single application key, given a recovery key.
- *
- * <ul>
- *   <li>Alias - Keystore alias of the key.
- *   <li>Encrypted key material.
- * </ul>
- *
- * Note that Application info is not included. Recovery Agent can only make its own keys
- * recoverable.
- *
- * @hide
- */
-public final class KeyEntryRecoveryData implements Parcelable {
-    private final String mAlias;
-    // The only supported format is AES-256 symmetric key.
-    private final byte[] mEncryptedKeyMaterial;
-
-    public KeyEntryRecoveryData(@NonNull String alias, @NonNull byte[] encryptedKeyMaterial) {
-        mAlias = Preconditions.checkNotNull(alias);
-        mEncryptedKeyMaterial = Preconditions.checkNotNull(encryptedKeyMaterial);
-    }
-
-    /**
-     * Application-specific alias of the key.
-     *
-     * @see java.security.KeyStore.aliases
-     */
-    public @NonNull String getAlias() {
-        return mAlias;
-    }
-
-    /** Encrypted key material encrypted by recovery key. */
-    public @NonNull byte[] getEncryptedKeyMaterial() {
-        return mEncryptedKeyMaterial;
-    }
-
-    public static final Parcelable.Creator<KeyEntryRecoveryData> CREATOR =
-            new Parcelable.Creator<KeyEntryRecoveryData>() {
-                public KeyEntryRecoveryData createFromParcel(Parcel in) {
-                    return new KeyEntryRecoveryData(in);
-                }
-
-                public KeyEntryRecoveryData[] newArray(int length) {
-                    return new KeyEntryRecoveryData[length];
-                }
-            };
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(mAlias);
-        out.writeByteArray(mEncryptedKeyMaterial);
-    }
-
-    protected KeyEntryRecoveryData(Parcel in) {
-        mAlias = in.readString();
-        mEncryptedKeyMaterial = in.createByteArray();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-}
diff --git a/core/java/android/security/recoverablekeystore/KeyStoreRecoveryData.java b/core/java/android/security/recoverablekeystore/KeyStoreRecoveryData.java
deleted file mode 100644 (file)
index 087f7a2..0000000
+++ /dev/null
@@ -1,115 +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.recoverablekeystore;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.List;
-
-/**
- * Helper class which returns data necessary to recover keys.
- * Contains
- *
- * <ul>
- * <li>Snapshot version.
- * <li>Recovery metadata with UI and key derivation parameters.
- * <li>List of application keys encrypted by recovery key.
- * <li>Encrypted recovery key.
- * </ul>
- *
- * @hide
- */
-public final class KeyStoreRecoveryData implements Parcelable {
-    private final int mSnapshotVersion;
-    private final List<KeyStoreRecoveryMetadata> mRecoveryMetadata;
-    private final List<KeyEntryRecoveryData> mApplicationKeyBlobs;
-    private final byte[] mEncryptedRecoveryKeyBlob;
-
-    public KeyStoreRecoveryData(int snapshotVersion, @NonNull List<KeyStoreRecoveryMetadata>
-            recoveryMetadata, @NonNull List<KeyEntryRecoveryData> applicationKeyBlobs,
-            @NonNull byte[] encryptedRecoveryKeyBlob) {
-        mSnapshotVersion = snapshotVersion;
-        mRecoveryMetadata = Preconditions.checkNotNull(recoveryMetadata);
-        mApplicationKeyBlobs = Preconditions.checkNotNull(applicationKeyBlobs);
-        mEncryptedRecoveryKeyBlob = Preconditions.checkNotNull(encryptedRecoveryKeyBlob);
-    }
-
-    /**
-     * Snapshot version for given account. It is incremented when user secret or list of application
-     * keys changes.
-     */
-    public int getSnapshotVersion() {
-        return mSnapshotVersion;
-    }
-
-    /**
-     * UI and key derivation parameters. Note that combination of secrets may be used.
-     */
-    public @NonNull List<KeyStoreRecoveryMetadata> getRecoveryMetadata() {
-        return mRecoveryMetadata;
-    }
-
-    /**
-     * List of application keys, with key material encrypted by
-     * the recovery key ({@link #getEncryptedRecoveryKeyBlob}).
-     */
-    public @NonNull List<KeyEntryRecoveryData> getApplicationKeyBlobs() {
-        return mApplicationKeyBlobs;
-    }
-
-    /**
-     * Recovery key blob, encrypted by user secret and recovery service public key.
-     */
-    public @NonNull byte[] getEncryptedRecoveryKeyBlob() {
-        return mEncryptedRecoveryKeyBlob;
-    }
-
-    public static final Parcelable.Creator<KeyStoreRecoveryData> CREATOR =
-            new Parcelable.Creator<KeyStoreRecoveryData>() {
-        public KeyStoreRecoveryData createFromParcel(Parcel in) {
-            return new KeyStoreRecoveryData(in);
-        }
-
-        public KeyStoreRecoveryData[] newArray(int length) {
-            return new KeyStoreRecoveryData[length];
-        }
-    };
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mSnapshotVersion);
-        out.writeTypedList(mRecoveryMetadata);
-        out.writeByteArray(mEncryptedRecoveryKeyBlob);
-        out.writeTypedList(mApplicationKeyBlobs);
-    }
-
-    protected KeyStoreRecoveryData(Parcel in) {
-        mSnapshotVersion = in.readInt();
-        mRecoveryMetadata = in.createTypedArrayList(KeyStoreRecoveryMetadata.CREATOR);
-        mEncryptedRecoveryKeyBlob = in.createByteArray();
-        mApplicationKeyBlobs = in.createTypedArrayList(KeyEntryRecoveryData.CREATOR);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-}
index 4e7df28..c668e3d 100644 (file)
@@ -19,9 +19,9 @@ package com.android.internal.widget;
 import android.app.PendingIntent;
 import android.app.trust.IStrongAuthTracker;
 import android.os.Bundle;
-import android.security.recoverablekeystore.KeyEntryRecoveryData;
-import android.security.recoverablekeystore.KeyStoreRecoveryData;
-import android.security.recoverablekeystore.KeyStoreRecoveryMetadata;
+import android.security.keystore.EntryRecoveryData;
+import android.security.keystore.RecoveryData;
+import android.security.keystore.RecoveryMetadata;
 import com.android.internal.widget.ICheckCredentialProgressCallback;
 import com.android.internal.widget.VerifyCredentialResponse;
 
@@ -60,11 +60,11 @@ interface ILockSettings {
             in byte[] token, int requestedQuality, int userId);
     void unlockUserWithToken(long tokenHandle, in byte[] token, int userId);
 
-    // RecoverableKeyStoreLoader methods.
+    // Keystore RecoveryManager methods.
     // {@code ServiceSpecificException} may be thrown to signal an error, which caller can
-    // convert to  {@code RecoverableKeyStoreLoader}.
+    // convert to  {@code RecoveryManagerException}.
     void initRecoveryService(in String rootCertificateAlias, in byte[] signedPublicKeyList);
-    KeyStoreRecoveryData getRecoveryData(in byte[] account);
+    RecoveryData getRecoveryData(in byte[] account);
     byte[] generateAndStoreKey(String alias);
     void removeKey(String alias);
     void setSnapshotCreatedPendingIntent(in PendingIntent intent);
@@ -75,10 +75,10 @@ interface ILockSettings {
     void setRecoverySecretTypes(in int[] secretTypes);
     int[] getRecoverySecretTypes();
     int[] getPendingRecoverySecretTypes();
-    void recoverySecretAvailable(in KeyStoreRecoveryMetadata recoverySecret);
+    void recoverySecretAvailable(in RecoveryMetadata recoverySecret);
     byte[] startRecoverySession(in String sessionId,
             in byte[] verifierPublicKey, in byte[] vaultParams, in byte[] vaultChallenge,
-            in List<KeyStoreRecoveryMetadata> secrets);
+            in List<RecoveryMetadata> secrets);
     Map/*<String, byte[]>*/ recoverKeys(in String sessionId, in byte[] recoveryKeyBlob,
-            in List<KeyEntryRecoveryData> applicationKeys);
+            in List<EntryRecoveryData> applicationKeys);
 }
index 516828b..5a8005c 100644 (file)
@@ -79,10 +79,10 @@ import android.security.keystore.AndroidKeyStoreProvider;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
 import android.security.keystore.UserNotAuthenticatedException;
-import android.security.recoverablekeystore.KeyEntryRecoveryData;
-import android.security.recoverablekeystore.KeyStoreRecoveryData;
-import android.security.recoverablekeystore.KeyStoreRecoveryMetadata;
-import android.security.recoverablekeystore.RecoverableKeyStoreLoader.RecoverableKeyStoreLoaderException;
+import android.security.keystore.EntryRecoveryData;
+import android.security.keystore.RecoveryData;
+import android.security.keystore.RecoveryMetadata;
+import android.security.keystore.RecoveryManager.RecoveryManagerException;
 import android.service.gatekeeper.GateKeeperResponse;
 import android.service.gatekeeper.IGateKeeperService;
 import android.text.TextUtils;
@@ -1968,7 +1968,7 @@ public class LockSettingsService extends ILockSettings.Stub {
     }
 
     @Override
-    public KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account) throws RemoteException {
+    public RecoveryData getRecoveryData(@NonNull byte[] account) throws RemoteException {
         return mRecoverableKeyStoreManager.getRecoveryData(account);
     }
 
@@ -1997,7 +1997,7 @@ public class LockSettingsService extends ILockSettings.Stub {
     }
 
     @Override
-    public void setRecoverySecretTypes(@NonNull @KeyStoreRecoveryMetadata.UserSecretType
+    public void setRecoverySecretTypes(@NonNull @RecoveryMetadata.UserSecretType
             int[] secretTypes) throws RemoteException {
         mRecoverableKeyStoreManager.setRecoverySecretTypes(secretTypes);
     }
@@ -2014,7 +2014,7 @@ public class LockSettingsService extends ILockSettings.Stub {
     }
 
     @Override
-    public void recoverySecretAvailable(@NonNull KeyStoreRecoveryMetadata recoverySecret)
+    public void recoverySecretAvailable(@NonNull RecoveryMetadata recoverySecret)
             throws RemoteException {
         mRecoverableKeyStoreManager.recoverySecretAvailable(recoverySecret);
     }
@@ -2022,7 +2022,7 @@ public class LockSettingsService extends ILockSettings.Stub {
     @Override
     public byte[] startRecoverySession(@NonNull String sessionId,
             @NonNull byte[] verifierPublicKey, @NonNull byte[] vaultParams,
-            @NonNull byte[] vaultChallenge, @NonNull List<KeyStoreRecoveryMetadata> secrets)
+            @NonNull byte[] vaultChallenge, @NonNull List<RecoveryMetadata> secrets)
             throws RemoteException {
         return mRecoverableKeyStoreManager.startRecoverySession(sessionId, verifierPublicKey,
                 vaultParams, vaultChallenge, secrets);
@@ -2030,7 +2030,7 @@ public class LockSettingsService extends ILockSettings.Stub {
 
     @Override
     public Map<String, byte[]> recoverKeys(@NonNull String sessionId,
-            @NonNull byte[] recoveryKeyBlob, @NonNull List<KeyEntryRecoveryData> applicationKeys)
+            @NonNull byte[] recoveryKeyBlob, @NonNull List<EntryRecoveryData> applicationKeys)
             throws RemoteException {
         return mRecoverableKeyStoreManager.recoverKeys(
                 sessionId, recoveryKeyBlob, applicationKeys);
index 6079873..57d0041 100644 (file)
 
 package com.android.server.locksettings.recoverablekeystore;
 
-import static android.security.recoverablekeystore.KeyStoreRecoveryMetadata.TYPE_LOCKSCREEN;
+import static android.security.keystore.RecoveryMetadata.TYPE_LOCKSCREEN;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
-import android.security.recoverablekeystore.KeyDerivationParameters;
-import android.security.recoverablekeystore.KeyEntryRecoveryData;
-import android.security.recoverablekeystore.KeyStoreRecoveryData;
-import android.security.recoverablekeystore.KeyStoreRecoveryMetadata;
+import android.security.keystore.KeyDerivationParameters;
+import android.security.keystore.EntryRecoveryData;
+import android.security.keystore.RecoveryData;
+import android.security.keystore.RecoveryMetadata;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -250,12 +250,13 @@ public class KeySyncTask implements Runnable {
             return;
         }
         // TODO: store raw data in RecoveryServiceMetadataEntry and generate Parcelables later
-        KeyStoreRecoveryMetadata metadata = new KeyStoreRecoveryMetadata(
+        // TODO: use Builder.
+        RecoveryMetadata metadata = new RecoveryMetadata(
                 /*userSecretType=*/ TYPE_LOCKSCREEN,
                 /*lockScreenUiFormat=*/ getUiFormat(mCredentialType, mCredential),
                 /*keyDerivationParameters=*/ KeyDerivationParameters.createSha256Parameters(salt),
                 /*secret=*/ new byte[0]);
-        ArrayList<KeyStoreRecoveryMetadata> metadataList = new ArrayList<>();
+        ArrayList<RecoveryMetadata> metadataList = new ArrayList<>();
         metadataList.add(metadata);
 
         int snapshotVersion = incrementSnapshotVersion(recoveryAgentUid);
@@ -263,7 +264,8 @@ public class KeySyncTask implements Runnable {
         // If application keys are not updated, snapshot will not be created on next unlock.
         mRecoverableKeyStoreDb.setShouldCreateSnapshot(mUserId, recoveryAgentUid, false);
 
-        mRecoverySnapshotStorage.put(recoveryAgentUid, new KeyStoreRecoveryData(
+        // TODO: use Builder.
+        mRecoverySnapshotStorage.put(recoveryAgentUid, new RecoveryData(
                 snapshotVersion,
                 /*recoveryMetadata=*/ metadataList,
                 /*applicationKeyBlobs=*/ createApplicationKeyEntries(encryptedApplicationKeys),
@@ -306,7 +308,7 @@ public class KeySyncTask implements Runnable {
      */
     private boolean shoudCreateSnapshot(int recoveryAgentUid) {
         int[] types = mRecoverableKeyStoreDb.getRecoverySecretTypes(mUserId, recoveryAgentUid);
-        if (!ArrayUtils.contains(types, KeyStoreRecoveryMetadata.TYPE_LOCKSCREEN)) {
+        if (!ArrayUtils.contains(types, RecoveryMetadata.TYPE_LOCKSCREEN)) {
             // Only lockscreen type is supported.
             // We will need to pass extra argument to KeySyncTask to support custom pass phrase.
             return false;
@@ -329,14 +331,14 @@ public class KeySyncTask implements Runnable {
      * @return The format - either pattern, pin, or password.
      */
     @VisibleForTesting
-    @KeyStoreRecoveryMetadata.LockScreenUiFormat static int getUiFormat(
+    @RecoveryMetadata.LockScreenUiFormat static int getUiFormat(
             int credentialType, String credential) {
         if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
-            return KeyStoreRecoveryMetadata.TYPE_PATTERN;
+            return RecoveryMetadata.TYPE_PATTERN;
         } else if (isPin(credential)) {
-            return KeyStoreRecoveryMetadata.TYPE_PIN;
+            return RecoveryMetadata.TYPE_PIN;
         } else {
-            return KeyStoreRecoveryMetadata.TYPE_PASSWORD;
+            return RecoveryMetadata.TYPE_PASSWORD;
         }
     }
 
@@ -399,12 +401,12 @@ public class KeySyncTask implements Runnable {
         return keyGenerator.generateKey();
     }
 
-    private static List<KeyEntryRecoveryData> createApplicationKeyEntries(
+    private static List<EntryRecoveryData> createApplicationKeyEntries(
             Map<String, byte[]> encryptedApplicationKeys) {
-        ArrayList<KeyEntryRecoveryData> keyEntries = new ArrayList<>();
+        ArrayList<EntryRecoveryData> keyEntries = new ArrayList<>();
         for (String alias : encryptedApplicationKeys.keySet()) {
             keyEntries.add(
-                    new KeyEntryRecoveryData(
+                    new EntryRecoveryData(
                             alias,
                             encryptedApplicationKeys.get(alias)));
         }
index e851d8c..0ab8dc5 100644 (file)
@@ -37,8 +37,7 @@ import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 
 /**
- * Utility functions for the flow where the RecoverableKeyStoreLoader syncs keys with remote
- * storage.
+ * Utility functions for the flow where the RecoveryManager syncs keys with remote storage.
  *
  * @hide
  */
index ee83876..0e93f94 100644 (file)
 
 package com.android.server.locksettings.recoverablekeystore;
 
-import static android.security.recoverablekeystore.RecoverableKeyStoreLoader
-        .ERROR_BAD_X509_CERTIFICATE;
-import static android.security.recoverablekeystore.RecoverableKeyStoreLoader.ERROR_DATABASE_ERROR;
-import static android.security.recoverablekeystore.RecoverableKeyStoreLoader
-        .ERROR_DECRYPTION_FAILED;
-import static android.security.recoverablekeystore.RecoverableKeyStoreLoader.ERROR_INSECURE_USER;
-import static android.security.recoverablekeystore.RecoverableKeyStoreLoader
-        .ERROR_KEYSTORE_INTERNAL_ERROR;
-import static android.security.recoverablekeystore.RecoverableKeyStoreLoader
-        .ERROR_NOT_YET_SUPPORTED;
-import static android.security.recoverablekeystore.RecoverableKeyStoreLoader
-        .ERROR_UNEXPECTED_MISSING_ALGORITHM;
+import static android.security.keystore.RecoveryManager.ERROR_BAD_X509_CERTIFICATE;
+import static android.security.keystore.RecoveryManager.ERROR_DATABASE_ERROR;
+import static android.security.keystore.RecoveryManager.ERROR_DECRYPTION_FAILED;
+import static android.security.keystore.RecoveryManager.ERROR_INSECURE_USER;
+import static android.security.keystore.RecoveryManager.ERROR_KEYSTORE_INTERNAL_ERROR;
+import static android.security.keystore.RecoveryManager.ERROR_NOT_YET_SUPPORTED;
+import static android.security.keystore.RecoveryManager.ERROR_UNEXPECTED_MISSING_ALGORITHM;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Context;
+import android.Manifest;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 
-import android.security.recoverablekeystore.KeyEntryRecoveryData;
-import android.security.recoverablekeystore.KeyStoreRecoveryData;
-import android.security.recoverablekeystore.KeyStoreRecoveryMetadata;
-import android.security.recoverablekeystore.RecoverableKeyStoreLoader;
+import android.security.keystore.EntryRecoveryData;
+import android.security.keystore.RecoveryData;
+import android.security.keystore.RecoveryMetadata;
+import android.security.keystore.RecoveryManager;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -69,7 +65,7 @@ import java.util.concurrent.Executors;
 import javax.crypto.AEADBadTagException;
 
 /**
- * Class with {@link RecoverableKeyStoreLoader} API implementation and internal methods to interact
+ * Class with {@link RecoveryManager} API implementation and internal methods to interact
  * with {@code LockSettingsService}.
  *
  * @hide
@@ -175,13 +171,13 @@ public class RecoverableKeyStoreManager {
      * @return recovery data
      * @hide
      */
-    public @NonNull KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account)
+    public @NonNull RecoveryData getRecoveryData(@NonNull byte[] account)
             throws RemoteException {
         checkRecoverKeyStorePermission();
         int uid = Binder.getCallingUid();
-        KeyStoreRecoveryData snapshot = mSnapshotStorage.get(uid);
+        RecoveryData snapshot = mSnapshotStorage.get(uid);
         if (snapshot == null) {
-            throw new ServiceSpecificException(RecoverableKeyStoreLoader.ERROR_NO_SNAPSHOT_PENDING);
+            throw new ServiceSpecificException(RecoveryManager.ERROR_NO_SNAPSHOT_PENDING);
         }
         return snapshot;
     }
@@ -261,7 +257,7 @@ public class RecoverableKeyStoreManager {
      * @hide
      */
     public void setRecoverySecretTypes(
-            @NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] secretTypes)
+            @NonNull @RecoveryMetadata.UserSecretType int[] secretTypes)
             throws RemoteException {
         checkRecoverKeyStorePermission();
         int userId = UserHandle.getCallingUserId();
@@ -285,7 +281,7 @@ public class RecoverableKeyStoreManager {
     }
 
     /**
-     * Gets secret types RecoverableKeyStoreLoaders is waiting for to create new Recovery Data.
+     * Gets secret types RecoveryManagers is waiting for to create new Recovery Data.
      *
      * @return secret types
      * @hide
@@ -296,9 +292,9 @@ public class RecoverableKeyStoreManager {
     }
 
     public void recoverySecretAvailable(
-            @NonNull KeyStoreRecoveryMetadata recoverySecret) throws RemoteException {
+            @NonNull RecoveryMetadata recoverySecret) throws RemoteException {
         int uid = Binder.getCallingUid();
-        if (recoverySecret.getLockScreenUiFormat() == KeyStoreRecoveryMetadata.TYPE_LOCKSCREEN) {
+        if (recoverySecret.getLockScreenUiFormat() == RecoveryMetadata.TYPE_LOCKSCREEN) {
             throw new SecurityException(
                     "Caller " + uid + " is not allowed to set lock screen secret");
         }
@@ -324,7 +320,7 @@ public class RecoverableKeyStoreManager {
             @NonNull byte[] verifierPublicKey,
             @NonNull byte[] vaultParams,
             @NonNull byte[] vaultChallenge,
-            @NonNull List<KeyStoreRecoveryMetadata> secrets)
+            @NonNull List<RecoveryMetadata> secrets)
             throws RemoteException {
         checkRecoverKeyStorePermission();
         int uid = Binder.getCallingUid();
@@ -333,7 +329,7 @@ public class RecoverableKeyStoreManager {
             // TODO: support multiple secrets
             throw new ServiceSpecificException(
                     ERROR_NOT_YET_SUPPORTED,
-                    "Only a single KeyStoreRecoveryMetadata is supported");
+                    "Only a single RecoveryMetadata is supported");
         }
 
         PublicKey publicKey;
@@ -391,7 +387,7 @@ public class RecoverableKeyStoreManager {
     public Map<String, byte[]> recoverKeys(
             @NonNull String sessionId,
             @NonNull byte[] encryptedRecoveryKey,
-            @NonNull List<KeyEntryRecoveryData> applicationKeys)
+            @NonNull List<EntryRecoveryData> applicationKeys)
             throws RemoteException {
         checkRecoverKeyStorePermission();
         int uid = Binder.getCallingUid();
@@ -481,9 +477,9 @@ public class RecoverableKeyStoreManager {
      */
     private Map<String, byte[]> recoverApplicationKeys(
             @NonNull byte[] recoveryKey,
-            @NonNull List<KeyEntryRecoveryData> applicationKeys) throws RemoteException {
+            @NonNull List<EntryRecoveryData> applicationKeys) throws RemoteException {
         HashMap<String, byte[]> keyMaterialByAlias = new HashMap<>();
-        for (KeyEntryRecoveryData applicationKey : applicationKeys) {
+        for (EntryRecoveryData applicationKey : applicationKeys) {
             String alias = applicationKey.getAlias();
             byte[] encryptedKeyMaterial = applicationKey.getEncryptedKeyMaterial();
 
@@ -567,7 +563,7 @@ public class RecoverableKeyStoreManager {
 
     private void checkRecoverKeyStorePermission() {
         mContext.enforceCallingOrSelfPermission(
-                RecoverableKeyStoreLoader.PERMISSION_RECOVER_KEYSTORE,
+                Manifest.permission.RECOVER_KEYSTORE,
                 "Caller " + Binder.getCallingUid() + " doesn't have RecoverKeyStore permission.");
     }
 
index 54aa9f0..0042e10 100644 (file)
@@ -17,7 +17,7 @@
 package com.android.server.locksettings.recoverablekeystore;
 
 import android.util.Log;
-import android.security.recoverablekeystore.RecoverableKeyStoreLoader;
+import android.security.keystore.RecoveryManager;
 
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
@@ -97,7 +97,7 @@ public class WrappedKey {
                 /*nonce=*/ cipher.getIV(),
                 /*keyMaterial=*/ encryptedKeyMaterial,
                 /*platformKeyGenerationId=*/ wrappingKey.getGenerationId(),
-                RecoverableKeyStoreLoader.RECOVERY_STATUS_SYNC_IN_PROGRESS);
+                RecoveryManager.RECOVERY_STATUS_SYNC_IN_PROGRESS);
     }
 
     /**
@@ -107,14 +107,14 @@ public class WrappedKey {
      * @param keyMaterial The encrypted bytes of the key material.
      * @param platformKeyGenerationId The generation ID of the key used to wrap this key.
      *
-     * @see RecoverableKeyStoreLoader.RECOVERY_STATUS_SYNC_IN_PROGRESS
+     * @see RecoveryManager.RECOVERY_STATUS_SYNC_IN_PROGRESS
      * @hide
      */
     public WrappedKey(byte[] nonce, byte[] keyMaterial, int platformKeyGenerationId) {
         mNonce = nonce;
         mKeyMaterial = keyMaterial;
         mPlatformKeyGenerationId = platformKeyGenerationId;
-        mRecoveryStatus = RecoverableKeyStoreLoader.RECOVERY_STATUS_SYNC_IN_PROGRESS;
+        mRecoveryStatus = RecoveryManager.RECOVERY_STATUS_SYNC_IN_PROGRESS;
     }
 
     /**
index c6f3ede..8674330 100644 (file)
@@ -449,7 +449,7 @@ public class RecoverableKeyStoreDb {
     /**
      * Updates the list of user secret types used for end-to-end encryption.
      * If no secret types are set, recovery snapshot will not be created.
-     * See {@code KeyStoreRecoveryMetadata}
+     * See {@code RecoveryMetadata}
      *
      * @param userId The userId of the profile the application is running under.
      * @param uid The uid of the application.
index 597ae4c..a6d9bd4 100644 (file)
@@ -64,7 +64,7 @@ class RecoverableKeyStoreDbContract {
         static final String COLUMN_NAME_LAST_SYNCED_AT = "last_synced_at";
 
         /**
-         * Status of the key sync {@code RecoverableKeyStoreLoader#setRecoveryStatus}
+         * Status of the key sync {@code RecoveryManager#setRecoveryStatus}
          */
         static final String COLUMN_NAME_RECOVERY_STATUS = "recovery_status";
     }
index 011b374..158b1e3 100644 (file)
@@ -17,7 +17,7 @@
 package com.android.server.locksettings.recoverablekeystore.storage;
 
 import android.annotation.Nullable;
-import android.security.recoverablekeystore.KeyStoreRecoveryData;
+import android.security.keystore.RecoveryData;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
@@ -34,12 +34,12 @@ import com.android.internal.annotations.GuardedBy;
  */
 public class RecoverySnapshotStorage {
     @GuardedBy("this")
-    private final SparseArray<KeyStoreRecoveryData> mSnapshotByUid = new SparseArray<>();
+    private final SparseArray<RecoveryData> mSnapshotByUid = new SparseArray<>();
 
     /**
      * Sets the latest {@code snapshot} for the recovery agent {@code uid}.
      */
-    public synchronized void put(int uid, KeyStoreRecoveryData snapshot) {
+    public synchronized void put(int uid, RecoveryData snapshot) {
         mSnapshotByUid.put(uid, snapshot);
     }
 
@@ -47,7 +47,7 @@ public class RecoverySnapshotStorage {
      * Returns the latest snapshot for the recovery agent {@code uid}, or null if none exists.
      */
     @Nullable
-    public synchronized KeyStoreRecoveryData get(int uid) {
+    public synchronized RecoveryData get(int uid) {
         return mSnapshotByUid.get(uid);
     }
 
index 4c613a4..7538079 100644 (file)
 
 package com.android.server.locksettings.recoverablekeystore;
 
-import static android.security.recoverablekeystore.KeyStoreRecoveryMetadata.TYPE_LOCKSCREEN;
+import static android.security.keystore.RecoveryMetadata.TYPE_LOCKSCREEN;
 
-import static android.security.recoverablekeystore.KeyStoreRecoveryMetadata.TYPE_PASSWORD;
-import static android.security.recoverablekeystore.KeyStoreRecoveryMetadata.TYPE_PATTERN;
-import static android.security.recoverablekeystore.KeyStoreRecoveryMetadata.TYPE_PIN;
+import static android.security.keystore.RecoveryMetadata.TYPE_PASSWORD;
+import static android.security.keystore.RecoveryMetadata.TYPE_PATTERN;
+import static android.security.keystore.RecoveryMetadata.TYPE_PIN;
 
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
@@ -40,9 +40,9 @@ import android.content.Context;
 import android.security.keystore.AndroidKeyStoreSecretKey;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
-import android.security.recoverablekeystore.KeyDerivationParameters;
-import android.security.recoverablekeystore.KeyEntryRecoveryData;
-import android.security.recoverablekeystore.KeyStoreRecoveryData;
+import android.security.keystore.KeyDerivationParameters;
+import android.security.keystore.EntryRecoveryData;
+import android.security.keystore.RecoveryData;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -275,7 +275,6 @@ public class KeySyncTaskTest {
 
     @Test
     public void run_sendsEncryptedKeysIfAvailableToSync() throws Exception {
-
         mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                 TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
         when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);
@@ -283,7 +282,7 @@ public class KeySyncTaskTest {
                 addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
         mKeySyncTask.run();
 
-        KeyStoreRecoveryData recoveryData = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
+        RecoveryData recoveryData = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
         KeyDerivationParameters keyDerivationParameters =
                 recoveryData.getRecoveryMetadata().get(0).getKeyDerivationParameters();
         assertThat(keyDerivationParameters.getAlgorithm()).isEqualTo(
@@ -302,9 +301,9 @@ public class KeySyncTaskTest {
                         counterId,
                         /*maxAttempts=*/ 10,
                         TEST_DEVICE_ID));
-        List<KeyEntryRecoveryData> applicationKeys = recoveryData.getApplicationKeyBlobs();
+        List<EntryRecoveryData> applicationKeys = recoveryData.getEntryRecoveryData();
         assertThat(applicationKeys).hasSize(1);
-        KeyEntryRecoveryData keyData = applicationKeys.get(0);
+        EntryRecoveryData keyData = applicationKeys.get(0);
         assertEquals(TEST_APP_KEY_ALIAS, keyData.getAlias());
         assertThat(keyData.getAlias()).isEqualTo(keyData.getAlias());
         byte[] appKey = KeySyncUtils.decryptApplicationKey(
@@ -314,7 +313,6 @@ public class KeySyncTaskTest {
 
     @Test
     public void run_setsCorrectSnapshotVersion() throws Exception {
-
         mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                 TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
         when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);
@@ -323,7 +321,7 @@ public class KeySyncTaskTest {
 
         mKeySyncTask.run();
 
-        KeyStoreRecoveryData recoveryData = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
+        RecoveryData recoveryData = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
         assertThat(recoveryData.getSnapshotVersion()).isEqualTo(1); // default value;
         mRecoverableKeyStoreDb.setShouldCreateSnapshot(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, true);
 
@@ -353,13 +351,13 @@ public class KeySyncTaskTest {
 
         mKeySyncTask.run();
 
-        KeyStoreRecoveryData recoveryData = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
+        RecoveryData recoveryData = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
         assertThat(recoveryData.getRecoveryMetadata()).hasSize(1);
         assertThat(recoveryData.getRecoveryMetadata().get(0).getLockScreenUiFormat()).
                 isEqualTo(TYPE_PASSWORD);
     }
 
-    @Test
+   @Test
     public void run_setsCorrectTypeForPin() throws Exception {
         mKeySyncTask = new KeySyncTask(
                 mRecoverableKeyStoreDb,
@@ -379,7 +377,7 @@ public class KeySyncTaskTest {
 
         mKeySyncTask.run();
 
-        KeyStoreRecoveryData recoveryData = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
+        RecoveryData recoveryData = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
         assertThat(recoveryData.getRecoveryMetadata()).hasSize(1);
         // Password with only digits is changed to pin.
         assertThat(recoveryData.getRecoveryMetadata().get(0).getLockScreenUiFormat()).
@@ -406,7 +404,7 @@ public class KeySyncTaskTest {
 
         mKeySyncTask.run();
 
-        KeyStoreRecoveryData recoveryData = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
+        RecoveryData recoveryData = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
         assertThat(recoveryData.getRecoveryMetadata()).hasSize(1);
         assertThat(recoveryData.getRecoveryMetadata().get(0).getLockScreenUiFormat()).
                 isEqualTo(TYPE_PATTERN);
@@ -431,10 +429,10 @@ public class KeySyncTaskTest {
     @Test
     public void run_sendsEncryptedKeysOnlyForAgentWhichActiveUserSecretType() throws Exception {
         mRecoverableKeyStoreDb.setRecoverySecretTypes(TEST_USER_ID, TEST_RECOVERY_AGENT_UID,
-                new int[] {TYPE_LOCKSCREEN, 100});
+                new int[] {TYPE_LOCKSCREEN, 1000});
         // Snapshot will not be created during unlock event.
         mRecoverableKeyStoreDb.setRecoverySecretTypes(TEST_USER_ID, TEST_RECOVERY_AGENT_UID2,
-                new int[] {100});
+                new int[] {1000});
 
         mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                 TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
index 4da17fa..0eddcf3 100644 (file)
@@ -16,8 +16,8 @@
 
 package com.android.server.locksettings.recoverablekeystore;
 
-import static android.security.recoverablekeystore.KeyStoreRecoveryMetadata.TYPE_LOCKSCREEN;
-import static android.security.recoverablekeystore.KeyStoreRecoveryMetadata.TYPE_PASSWORD;
+import static android.security.keystore.RecoveryMetadata.TYPE_LOCKSCREEN;
+import static android.security.keystore.RecoveryMetadata.TYPE_PASSWORD;
 
 import static com.google.common.truth.Truth.assertThat;
 import static org.junit.Assert.assertArrayEquals;
@@ -35,18 +35,19 @@ import android.app.KeyguardManager;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
+import android.Manifest;
 import android.os.Binder;
 import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 import android.security.keystore.AndroidKeyStoreSecretKey;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
-import android.security.recoverablekeystore.KeyDerivationParameters;
-import android.security.recoverablekeystore.KeyEntryRecoveryData;
-import android.security.recoverablekeystore.KeyStoreRecoveryMetadata;
-import android.security.recoverablekeystore.RecoverableKeyStoreLoader;
-import android.support.test.InstrumentationRegistry;
+import android.security.keystore.KeyDerivationParameters;
+import android.security.keystore.EntryRecoveryData;
+import android.security.keystore.RecoveryMetadata;
+import android.security.keystore.RecoveryManager;
 import android.support.test.filters.SmallTest;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb;
@@ -250,7 +251,7 @@ public class RecoverableKeyStoreManagerTest {
                 TEST_VAULT_PARAMS,
                 TEST_VAULT_CHALLENGE,
                 ImmutableList.of(
-                        new KeyStoreRecoveryMetadata(
+                        new RecoveryMetadata(
                                 TYPE_LOCKSCREEN,
                                 TYPE_PASSWORD,
                                 KeyDerivationParameters.createSha256Parameters(TEST_SALT),
@@ -258,7 +259,7 @@ public class RecoverableKeyStoreManagerTest {
 
         verify(mMockContext, times(1))
                 .enforceCallingOrSelfPermission(
-                        eq(RecoverableKeyStoreLoader.PERMISSION_RECOVER_KEYSTORE), any());
+                        eq(Manifest.permission.RECOVER_KEYSTORE), any());
     }
 
     @Test
@@ -269,7 +270,7 @@ public class RecoverableKeyStoreManagerTest {
                 TEST_VAULT_PARAMS,
                 TEST_VAULT_CHALLENGE,
                 ImmutableList.of(
-                        new KeyStoreRecoveryMetadata(
+                        new RecoveryMetadata(
                                 TYPE_LOCKSCREEN,
                                 TYPE_PASSWORD,
                                 KeyDerivationParameters.createSha256Parameters(TEST_SALT),
@@ -294,7 +295,7 @@ public class RecoverableKeyStoreManagerTest {
             fail("should have thrown");
         } catch (ServiceSpecificException e) {
             assertThat(e.getMessage()).startsWith(
-                    "Only a single KeyStoreRecoveryMetadata is supported");
+                    "Only a single RecoveryMetadata is supported");
         }
     }
 
@@ -307,7 +308,7 @@ public class RecoverableKeyStoreManagerTest {
                     TEST_VAULT_PARAMS,
                     TEST_VAULT_CHALLENGE,
                     ImmutableList.of(
-                            new KeyStoreRecoveryMetadata(
+                            new RecoveryMetadata(
                                     TYPE_LOCKSCREEN,
                                     TYPE_PASSWORD,
                                     KeyDerivationParameters.createSha256Parameters(TEST_SALT),
@@ -329,7 +330,7 @@ public class RecoverableKeyStoreManagerTest {
                     vaultParams,
                     TEST_VAULT_CHALLENGE,
                     ImmutableList.of(
-                            new KeyStoreRecoveryMetadata(
+                            new RecoveryMetadata(
                                     TYPE_LOCKSCREEN,
                                     TYPE_PASSWORD,
                                     KeyDerivationParameters.createSha256Parameters(TEST_SALT),
@@ -347,7 +348,7 @@ public class RecoverableKeyStoreManagerTest {
                     TEST_SESSION_ID,
                     /*recoveryKeyBlob=*/ randomBytes(32),
                     /*applicationKeys=*/ ImmutableList.of(
-                            new KeyEntryRecoveryData("alias", randomBytes(32))
+                            new EntryRecoveryData("alias", randomBytes(32))
                     ));
             fail("should have thrown");
         } catch (ServiceSpecificException e) {
@@ -362,7 +363,7 @@ public class RecoverableKeyStoreManagerTest {
                 TEST_PUBLIC_KEY,
                 TEST_VAULT_PARAMS,
                 TEST_VAULT_CHALLENGE,
-                ImmutableList.of(new KeyStoreRecoveryMetadata(
+                ImmutableList.of(new RecoveryMetadata(
                         TYPE_LOCKSCREEN,
                         TYPE_PASSWORD,
                         KeyDerivationParameters.createSha256Parameters(TEST_SALT),
@@ -386,7 +387,7 @@ public class RecoverableKeyStoreManagerTest {
                 TEST_PUBLIC_KEY,
                 TEST_VAULT_PARAMS,
                 TEST_VAULT_CHALLENGE,
-                ImmutableList.of(new KeyStoreRecoveryMetadata(
+                ImmutableList.of(new RecoveryMetadata(
                         TYPE_LOCKSCREEN,
                         TYPE_PASSWORD,
                         KeyDerivationParameters.createSha256Parameters(TEST_SALT),
@@ -396,7 +397,7 @@ public class RecoverableKeyStoreManagerTest {
         SecretKey recoveryKey = randomRecoveryKey();
         byte[] encryptedClaimResponse = encryptClaimResponse(
                 keyClaimant, TEST_SECRET, TEST_VAULT_PARAMS, recoveryKey);
-        KeyEntryRecoveryData badApplicationKey = new KeyEntryRecoveryData(
+        EntryRecoveryData badApplicationKey = new EntryRecoveryData(
                 TEST_ALIAS,
                 randomBytes(32));
 
@@ -418,7 +419,7 @@ public class RecoverableKeyStoreManagerTest {
                 TEST_PUBLIC_KEY,
                 TEST_VAULT_PARAMS,
                 TEST_VAULT_CHALLENGE,
-                ImmutableList.of(new KeyStoreRecoveryMetadata(
+                ImmutableList.of(new RecoveryMetadata(
                         TYPE_LOCKSCREEN,
                         TYPE_PASSWORD,
                         KeyDerivationParameters.createSha256Parameters(TEST_SALT),
@@ -429,7 +430,7 @@ public class RecoverableKeyStoreManagerTest {
         byte[] encryptedClaimResponse = encryptClaimResponse(
                 keyClaimant, TEST_SECRET, TEST_VAULT_PARAMS, recoveryKey);
         byte[] applicationKeyBytes = randomBytes(32);
-        KeyEntryRecoveryData applicationKey = new KeyEntryRecoveryData(
+        EntryRecoveryData applicationKey = new EntryRecoveryData(
                 TEST_ALIAS,
                 encryptedApplicationKey(recoveryKey, applicationKeyBytes));
 
index b8080ab..6d5e740 100644 (file)
@@ -29,7 +29,7 @@ import org.junit.runner.RunWith;
 
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.security.recoverablekeystore.RecoverableKeyStoreLoader;
+import android.security.keystore.RecoveryManager;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -277,8 +277,7 @@ public class RecoverableKeyStoreDbTest {
 
         Map<String, Integer> statuses = mRecoverableKeyStoreDb.getStatusForAllKeys(uid);
         assertThat(statuses).hasSize(3);
-        assertThat(statuses).containsEntry(alias,
-                RecoverableKeyStoreLoader.RECOVERY_STATUS_SYNC_IN_PROGRESS);
+        assertThat(statuses).containsEntry(alias, RecoveryManager.RECOVERY_STATUS_SYNC_IN_PROGRESS);
         assertThat(statuses).containsEntry(alias2, status);
         assertThat(statuses).containsEntry(alias3, status);
 
index 2759e39..6308f74 100644 (file)
@@ -3,7 +3,7 @@ package com.android.server.locksettings.recoverablekeystore.storage;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 
-import android.security.recoverablekeystore.KeyStoreRecoveryData;
+import android.security.keystore.RecoveryData;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -26,7 +26,7 @@ public class RecoverySnapshotStorageTest {
     @Test
     public void get_returnsSetSnapshot() {
         int userId = 1000;
-        KeyStoreRecoveryData recoveryData = new KeyStoreRecoveryData(
+        RecoveryData recoveryData = new RecoveryData(
                 /*snapshotVersion=*/ 1,
                 new ArrayList<>(),
                 new ArrayList<>(),
@@ -39,7 +39,7 @@ public class RecoverySnapshotStorageTest {
     @Test
     public void remove_removesSnapshots() {
         int userId = 1000;
-        KeyStoreRecoveryData recoveryData = new KeyStoreRecoveryData(
+        RecoveryData recoveryData = new RecoveryData(
                 /*snapshotVersion=*/ 1,
                 new ArrayList<>(),
                 new ArrayList<>(),