diff options
9 files changed, 805 insertions, 0 deletions
diff --git a/core/java/android/security/recoverablekeystore/KeyDerivationParameters.aidl b/core/java/android/security/recoverablekeystore/KeyDerivationParameters.aidl new file mode 100644 index 000000000000..fe13179cab47 --- /dev/null +++ b/core/java/android/security/recoverablekeystore/KeyDerivationParameters.aidl @@ -0,0 +1,20 @@ +/* + * 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; + +/* @hide */ +parcelable KeyDerivationParameters; diff --git a/core/java/android/security/recoverablekeystore/KeyDerivationParameters.java b/core/java/android/security/recoverablekeystore/KeyDerivationParameters.java new file mode 100644 index 000000000000..2205c416921d --- /dev/null +++ b/core/java/android/security/recoverablekeystore/KeyDerivationParameters.java @@ -0,0 +1,112 @@ +/* + * 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.IntDef; +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Collection of parameters which define a key derivation function. + * Supports + * + * <ul> + * <li>SHA256 + * <li>Argon2id + * </ul> + * @hide + */ +public final class KeyDerivationParameters implements Parcelable { + private final int mAlgorithm; + private byte[] mSalt; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ALGORITHM_SHA256, ALGORITHM_ARGON2ID}) + public @interface KeyDerivationAlgorithm { + } + + /** + * Salted SHA256 + */ + public static final int ALGORITHM_SHA256 = 1; + + /** + * Argon2ID + */ + // TODO: add Argon2ID support. + public static final int ALGORITHM_ARGON2ID = 2; + + /** + * Creates instance of the class to to derive key using salted SHA256 hash. + */ + public KeyDerivationParameters createSHA256Parameters(@NonNull byte[] salt) { + return new KeyDerivationParameters(ALGORITHM_SHA256, salt); + } + + private KeyDerivationParameters(@KeyDerivationAlgorithm int algorithm, @NonNull byte[] salt) { + mAlgorithm = algorithm; + mSalt = Preconditions.checkNotNull(salt); + } + + /** + * Gets algorithm. + */ + public @KeyDerivationAlgorithm int getAlgorithm() { + return mAlgorithm; + } + + /** + * Gets salt. + */ + public @NonNull byte[] getSalt() { + return mSalt; + } + + public static final Parcelable.Creator<KeyDerivationParameters> CREATOR = + new Parcelable.Creator<KeyDerivationParameters>() { + public KeyDerivationParameters createFromParcel(Parcel in) { + return new KeyDerivationParameters(in); + } + + public KeyDerivationParameters[] newArray(int length) { + return new KeyDerivationParameters[length]; + } + }; + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mAlgorithm); + out.writeByteArray(mSalt); + } + + protected KeyDerivationParameters(Parcel in) { + mAlgorithm = in.readInt(); + mSalt = in.createByteArray(); + } + + @Override + public int describeContents() { + return 0; + } +} diff --git a/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.aidl b/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.aidl new file mode 100644 index 000000000000..1058463aa561 --- /dev/null +++ b/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.aidl @@ -0,0 +1,20 @@ +/* + * 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.recoverablekeystore; + +/* @hide */ +parcelable KeyEntryRecoveryData; diff --git a/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.java b/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.java new file mode 100644 index 000000000000..80f5aa71acd8 --- /dev/null +++ b/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.java @@ -0,0 +1,90 @@ +/* + * 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 byte[] mAlias; + // The only supported format is AES-256 symmetric key. + private final byte[] mEncryptedKeyMaterial; + + public KeyEntryRecoveryData(@NonNull byte[] 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 byte[] 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.writeByteArray(mAlias); + out.writeByteArray(mEncryptedKeyMaterial); + } + + protected KeyEntryRecoveryData(Parcel in) { + mAlias = in.createByteArray(); + mEncryptedKeyMaterial = in.createByteArray(); + } + + @Override + public int describeContents() { + return 0; + } +} diff --git a/core/java/android/security/recoverablekeystore/KeyStoreRecoveryData.aidl b/core/java/android/security/recoverablekeystore/KeyStoreRecoveryData.aidl new file mode 100644 index 000000000000..bd760516c6c3 --- /dev/null +++ b/core/java/android/security/recoverablekeystore/KeyStoreRecoveryData.aidl @@ -0,0 +1,20 @@ +/* + * 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; + +/* @hide */ +parcelable KeyStoreRecoveryData; diff --git a/core/java/android/security/recoverablekeystore/KeyStoreRecoveryData.java b/core/java/android/security/recoverablekeystore/KeyStoreRecoveryData.java new file mode 100644 index 000000000000..087f7a25688d --- /dev/null +++ b/core/java/android/security/recoverablekeystore/KeyStoreRecoveryData.java @@ -0,0 +1,115 @@ +/* + * 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; + } +} diff --git a/core/java/android/security/recoverablekeystore/KeyStoreRecoveryMetadata.aidl b/core/java/android/security/recoverablekeystore/KeyStoreRecoveryMetadata.aidl new file mode 100644 index 000000000000..e1d49defe157 --- /dev/null +++ b/core/java/android/security/recoverablekeystore/KeyStoreRecoveryMetadata.aidl @@ -0,0 +1,20 @@ +/* + * 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; + +/* @hide */ +parcelable KeyStoreRecoveryMetadata; diff --git a/core/java/android/security/recoverablekeystore/KeyStoreRecoveryMetadata.java b/core/java/android/security/recoverablekeystore/KeyStoreRecoveryMetadata.java new file mode 100644 index 000000000000..43f9c80571b3 --- /dev/null +++ b/core/java/android/security/recoverablekeystore/KeyStoreRecoveryMetadata.java @@ -0,0 +1,180 @@ +/* + * 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.IntDef; +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Arrays; + +/** + * Helper class with data necessary to recover Keystore on a new device. + * It defines UI shown to the user and a way to derive a cryptographic key from user output. + * + * @hide + */ +public final class KeyStoreRecoveryMetadata implements Parcelable { + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({TYPE_LOCKSCREEN, TYPE_CUSTOM_PASSWORD}) + public @interface UserSecretType { + } + + /** + * Lockscreen secret is required to recover KeyStore. + */ + public static final int TYPE_LOCKSCREEN = 1; + + /** + * Custom passphrase, unrelated to lock screen, is required to recover KeyStore. + */ + public static final int TYPE_CUSTOM_PASSWORD = 2; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({TYPE_PIN, TYPE_PASSWORD, TYPE_PATTERN}) + public @interface LockScreenUiFormat { + } + + /** + * Pin with digits only. + */ + public static final int TYPE_PIN = 1; + + /** + * Password. String with latin-1 characters only. + */ + public static final int TYPE_PASSWORD = 2; + + /** + * Pattern with 3 by 3 grid. + */ + public static final int TYPE_PATTERN = 3; + + @UserSecretType + private final int mUserSecretType; + + @LockScreenUiFormat + private final int mLockScreenUiFormat; + + /** + * Parameters of key derivation function, including algorithm, difficulty, salt. + */ + private KeyDerivationParameters mKeyDerivationParameters; + private byte[] mSecret; // Derived from user secret. The field must have limited visibility. + + /** + * @param secret Constructor creates a reference to the secret. Caller must use + * @link {#clearSecret} to overwrite its value in memory. + */ + public KeyStoreRecoveryMetadata(@UserSecretType int userSecretType, + @LockScreenUiFormat int lockScreenUiFormat, + @NonNull KeyDerivationParameters keyDerivationParameters, @NonNull byte[] secret) { + mUserSecretType = userSecretType; + mLockScreenUiFormat = lockScreenUiFormat; + mKeyDerivationParameters = Preconditions.checkNotNull(keyDerivationParameters); + mSecret = Preconditions.checkNotNull(secret); + } + + /** + * Specifies UX shown to user during recovery. + * + * @see KeyStore.TYPE_PIN + * @see KeyStore.TYPE_PASSWORD + * @see KeyStore.TYPE_PATTERN + */ + public @LockScreenUiFormat int getLockScreenUiFormat() { + return mLockScreenUiFormat; + } + + /** + * Specifies function used to derive symmetric key from user input + * Format is defined in separate util class. + */ + public @NonNull KeyDerivationParameters getKeyDerivationParameters() { + return mKeyDerivationParameters; + } + + /** + * Secret string derived from user input. + */ + public @NonNull byte[] getSecret() { + return mSecret; + } + + /** + * @see KeyStore.TYPE_LOCKSCREEN + * @see KeyStore.TYPE_CUSTOM_PASSWORD + */ + public @UserSecretType int getUserSecretType() { + return mUserSecretType; + } + + /** + * Removes secret from memory than object is no longer used. + * Since finalizer call is not reliable, please use @link {#clearSecret} directly. + */ + @Override + protected void finalize() throws Throwable { + clearSecret(); + super.finalize(); + } + + /** + * Fills mSecret with zeroes. + */ + public void clearSecret() { + 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 KeyStoreRecoveryMetadata[] newArray(int length) { + return new KeyStoreRecoveryMetadata[length]; + } + }; + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mUserSecretType); + out.writeInt(mLockScreenUiFormat); + out.writeTypedObject(mKeyDerivationParameters, flags); + out.writeByteArray(mSecret); + } + + protected KeyStoreRecoveryMetadata(Parcel in) { + mUserSecretType = in.readInt(); + mLockScreenUiFormat = in.readInt(); + mKeyDerivationParameters = in.readTypedObject(KeyDerivationParameters.CREATOR); + mSecret = in.createByteArray(); + } + + @Override + public int describeContents() { + return 0; + } +} diff --git a/core/java/android/security/recoverablekeystore/RecoverableKeyStoreLoader.java b/core/java/android/security/recoverablekeystore/RecoverableKeyStoreLoader.java new file mode 100644 index 000000000000..0510320d3e11 --- /dev/null +++ b/core/java/android/security/recoverablekeystore/RecoverableKeyStoreLoader.java @@ -0,0 +1,228 @@ +/* + * 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.annotation.Nullable; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.ServiceManager; + +import com.android.internal.widget.ILockSettings; + +import java.util.List; + +/** + * A wrapper around KeyStore which lets key be exported to + * trusted hardware on server side and recovered later. + * + * @hide + */ +public class RecoverableKeyStoreLoader { + + private final ILockSettings mBinder; + + // Exception codes, should be in sync with {@code KeyStoreException}. + public static final int SYSTEM_ERROR = 4; + + public static final int UNINITIALIZED_RECOVERY_PUBLIC_KEY = 20; + + // Too many updates to recovery public key or server parameters. + public static final int RATE_LIMIT_EXCEEDED = 21; + + private RecoverableKeyStoreLoader(ILockSettings binder) { + mBinder = binder; + } + + /** + * @hide + */ + public static RecoverableKeyStoreLoader getInstance() { + ILockSettings lockSettings = + ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings")); + return new RecoverableKeyStoreLoader(lockSettings); + } + + /** + * @hide + */ + public static class RecoverableKeyStoreLoaderException extends Exception { + private final int mErrorCode; + + public RecoverableKeyStoreLoaderException(int errorCode, String message) { + super(message); + mErrorCode = errorCode; + } + + public int getErrorCode() { + return mErrorCode; + } + } + + /** + * Initializes key recovery service for the calling application. RecoverableKeyStoreLoader + * 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 which of a set of remote recovery service + * devices will be used. + * + * <p>In addition, RecoverableKeyStoreLoader 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 + * limited. + * @hide + */ + public void initRecoveryService(@NonNull String rootCertificateAlias, + @NonNull byte[] signedPublicKeyList) + throws RecoverableKeyStoreLoaderException { + throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented"); + // TODO: extend widget/ILockSettings.aidl + /* try { + mBinder.initRecoveryService(rootCertificate, publicKeyList); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } */ + } + + /** + * Returns data necessary to store all recoverable keys for given account. + * Key material is encrypted with user secret and recovery public key. + */ + public KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account) + throws RecoverableKeyStoreLoaderException { + throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented"); + } + + /** + * Server parameters used to generate new recovery key blobs. This value will be included in + * {@code KeyStoreRecoveryData.getEncryptedRecoveryKeyBlob()}. + * The same value must be included in vaultParams {@link startRecoverySession} + * + * @see #getRecoveryData + * @throws RecoverableKeyStoreLoaderException If parameters rotation is rate limited. + */ + public void updateServerParameters(long serverParameters) + throws RecoverableKeyStoreLoaderException { + throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented"); + } + + /** + * Updates recovery status for given keys. + * It is used to notify keystore that key was successfully stored on the server or + * there were an error. Returned as a part of KeyInfo data structure. + * + * @param packageName Application whose recoverable keys' statuses are to be updated. + * @param aliases List of application-specific key aliases. If the array is empty, updates the + * status for all existing recoverable keys. + * @param status Status specific to recovery agent. + */ + public void setRecoveryStatus(@NonNull String packageName, @Nullable String[] aliases, + int status) throws NameNotFoundException, RecoverableKeyStoreLoaderException { + throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented"); + } + + /** + * 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} + */ + public void setRecoverySecretTypes(@NonNull @KeyStoreRecoveryMetadata.UserSecretType + int[] secretTypes) throws RecoverableKeyStoreLoaderException { + throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented"); + } + + /** + * Defines a set of secret types used for end-to-end keystore encryption. + * Knowing all of them is necessary to generate KeyStoreRecoveryData. + * @see KeyStoreRecoveryData + */ + public @NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] getRecoverySecretTypes() + throws RecoverableKeyStoreLoaderException { + throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented"); + } + + /** + * Returns a list of recovery secret types, necessary to create a pending recovery snapshot. + * When user enters a secret of a pending type + * {@link #recoverySecretAvailable} should be called. + */ + public @NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] getPendingRecoverySecretTypes() + throws RecoverableKeyStoreLoaderException { + throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented"); + } + + /** + * 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 memory. + * + * @param recoverySecret user generated secret together with parameters necessary to + * regenerate it on a new device. + */ + public void recoverySecretAvailable(@NonNull KeyStoreRecoveryMetadata recoverySecret) + throws RecoverableKeyStoreLoaderException { + throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented"); + } + + /** + * Initializes recovery session and returns a blob with proof of recovery secrets possession. + * The method generates symmetric key for a session, which trusted remote device can use + * to return recovery key. + * + * @param sessionId ID for recovery session. + * @param verifierPublicKey Certificate with Public key used to create the recovery blob on + * the source device. Keystore will verify the certificate using root of trust. + * @param vaultParams Must match the parameters in the corresponding field in the recovery blob. + * Used to limit number of guesses. + * @param vaultChallenge Data passed from server for this recovery session and used to prevent + * replay attacks + * @param secrets Secrets provided by user, the method only uses type and secret fields. + * @return Binary blob with recovery claim. It is encrypted with verifierPublicKey and + * contains a proof of user secrets, session symmetric key and parameters necessary to identify + * the counter with the number of failed recovery attempts. + */ + public @NonNull byte[] startRecoverySession(@NonNull String sessionId, + @NonNull byte[] verifierPublicKey, @NonNull byte[] vaultParams, + @NonNull byte[] vaultChallenge, @NonNull List<KeyStoreRecoveryMetadata> secrets) + throws RecoverableKeyStoreLoaderException { + throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented"); + } + + /** + * Imports keys. + * + * @param sessionId Id for recovery session, same as in = {@link startRecoverySession}. + * @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. + */ + public void recoverKeys(@NonNull String sessionId, @NonNull byte[] recoveryKeyBlob, + @NonNull List<KeyEntryRecoveryData> applicationKeys) + throws RecoverableKeyStoreLoaderException { + throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented"); + } +} |