Merge "Remove deprecated recoverable keystore classes." into pi-dev
am: 654598b542
Change-Id: I883e6e98285fc9cb05cd46d6f88efda2437655ca
This commit is contained in:
@@ -1820,43 +1820,6 @@ Landroid/R$styleable;->Window_windowBackground:I
|
||||
Landroid/R$styleable;->Window_windowFrame:I
|
||||
Landroid/security/keystore/AndroidKeyStoreProvider;->getKeyStoreOperationHandle(Ljava/lang/Object;)J
|
||||
Landroid/security/KeyStore;->getInstance()Landroid/security/KeyStore;
|
||||
Landroid/security/keystore/KeychainProtectionParams;->clearSecret()V
|
||||
Landroid/security/keystore/KeychainProtectionParams;->getKeyDerivationParams()Landroid/security/keystore/KeyDerivationParams;
|
||||
Landroid/security/keystore/KeychainProtectionParams;->getLockScreenUiFormat()I
|
||||
Landroid/security/keystore/KeychainProtectionParams;->getSecret()[B
|
||||
Landroid/security/keystore/KeychainProtectionParams;->getUserSecretType()I
|
||||
Landroid/security/keystore/KeychainProtectionParams;-><init>(IILandroid/security/keystore/KeyDerivationParams;[B)V
|
||||
Landroid/security/keystore/KeychainProtectionParams;-><init>(Landroid/os/Parcel;)V
|
||||
Landroid/security/keystore/KeychainProtectionParams;-><init>()V
|
||||
Landroid/security/keystore/KeychainSnapshot;->getCounterId()J
|
||||
Landroid/security/keystore/KeychainSnapshot;->getEncryptedRecoveryKeyBlob()[B
|
||||
Landroid/security/keystore/KeychainSnapshot;->getKeychainProtectionParams()Ljava/util/List;
|
||||
Landroid/security/keystore/KeychainSnapshot;->getMaxAttempts()I
|
||||
Landroid/security/keystore/KeychainSnapshot;->getServerParams()[B
|
||||
Landroid/security/keystore/KeychainSnapshot;->getSnapshotVersion()I
|
||||
Landroid/security/keystore/KeychainSnapshot;->getTrustedHardwarePublicKey()[B
|
||||
Landroid/security/keystore/KeychainSnapshot;->getWrappedApplicationKeys()Ljava/util/List;
|
||||
Landroid/security/keystore/KeyDerivationParams;->ALGORITHM_ARGON2ID:I
|
||||
Landroid/security/keystore/KeyDerivationParams;->ALGORITHM_SHA256:I
|
||||
Landroid/security/keystore/KeyDerivationParams;->createSha256Params([B)Landroid/security/keystore/KeyDerivationParams;
|
||||
Landroid/security/keystore/KeyDerivationParams;->getAlgorithm()I
|
||||
Landroid/security/keystore/KeyDerivationParams;->getSalt()[B
|
||||
Landroid/security/keystore/KeyDerivationParams;-><init>(I[B)V
|
||||
Landroid/security/keystore/KeyDerivationParams;-><init>(Landroid/os/Parcel;)V
|
||||
Landroid/security/keystore/RecoveryClaim;->getClaimBytes()[B
|
||||
Landroid/security/keystore/RecoveryClaim;->getRecoverySession()Landroid/security/keystore/RecoverySession;
|
||||
Landroid/security/keystore/RecoveryController;->getInstance()Landroid/security/keystore/RecoveryController;
|
||||
Landroid/security/keystore/RecoveryController;->getRecoveryData([B)Landroid/security/keystore/KeychainSnapshot;
|
||||
Landroid/security/keystore/RecoveryController;->initRecoveryService(Ljava/lang/String;[B)V
|
||||
Landroid/security/keystore/RecoveryController;->recoverKeys(Landroid/security/keystore/RecoverySession;[BLjava/util/List;)Ljava/util/Map;
|
||||
Landroid/security/keystore/RecoveryController;->setRecoverySecretTypes([I)V
|
||||
Landroid/security/keystore/RecoveryController;->setRecoveryStatus(Ljava/lang/String;[Ljava/lang/String;I)V
|
||||
Landroid/security/keystore/RecoveryController;->setServerParams([B)V
|
||||
Landroid/security/keystore/RecoveryController;->setSnapshotCreatedPendingIntent(Landroid/app/PendingIntent;)V
|
||||
Landroid/security/keystore/RecoveryController;->startRecoverySession([B[B[BLjava/util/List;)Landroid/security/keystore/RecoveryClaim;
|
||||
Landroid/security/keystore/WrappedApplicationKey;->getAlias()Ljava/lang/String;
|
||||
Landroid/security/keystore/WrappedApplicationKey;->getEncryptedKeyMaterial()[B
|
||||
Landroid/security/keystore/WrappedApplicationKey;-><init>(Ljava/lang/String;[B)V
|
||||
Landroid/security/net/config/RootTrustManager;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;
|
||||
Landroid/service/media/IMediaBrowserServiceCallbacks;->onConnectFailed()V
|
||||
Landroid/service/media/IMediaBrowserServiceCallbacks;->onConnect(Ljava/lang/String;Landroid/media/session/MediaSession$Token;Landroid/os/Bundle;)V
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Helpers for converting classes between old and new API, so we can preserve backwards
|
||||
* compatibility while teamfooding. This will be removed soon.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
class BackwardsCompat {
|
||||
|
||||
|
||||
static KeychainProtectionParams toLegacyKeychainProtectionParams(
|
||||
android.security.keystore.recovery.KeyChainProtectionParams keychainProtectionParams
|
||||
) {
|
||||
return new KeychainProtectionParams.Builder()
|
||||
.setUserSecretType(keychainProtectionParams.getUserSecretType())
|
||||
.setSecret(keychainProtectionParams.getSecret())
|
||||
.setLockScreenUiFormat(keychainProtectionParams.getLockScreenUiFormat())
|
||||
.setKeyDerivationParams(
|
||||
toLegacyKeyDerivationParams(
|
||||
keychainProtectionParams.getKeyDerivationParams()))
|
||||
.build();
|
||||
}
|
||||
|
||||
static KeyDerivationParams toLegacyKeyDerivationParams(
|
||||
android.security.keystore.recovery.KeyDerivationParams keyDerivationParams
|
||||
) {
|
||||
return new KeyDerivationParams(
|
||||
keyDerivationParams.getAlgorithm(), keyDerivationParams.getSalt());
|
||||
}
|
||||
|
||||
static WrappedApplicationKey toLegacyWrappedApplicationKey(
|
||||
android.security.keystore.recovery.WrappedApplicationKey wrappedApplicationKey
|
||||
) {
|
||||
return new WrappedApplicationKey.Builder()
|
||||
.setAlias(wrappedApplicationKey.getAlias())
|
||||
.setEncryptedKeyMaterial(wrappedApplicationKey.getEncryptedKeyMaterial())
|
||||
.build();
|
||||
}
|
||||
|
||||
static android.security.keystore.recovery.KeyDerivationParams fromLegacyKeyDerivationParams(
|
||||
KeyDerivationParams keyDerivationParams
|
||||
) {
|
||||
return android.security.keystore.recovery.KeyDerivationParams.createSha256Params(
|
||||
keyDerivationParams.getSalt());
|
||||
}
|
||||
|
||||
static android.security.keystore.recovery.WrappedApplicationKey fromLegacyWrappedApplicationKey(
|
||||
WrappedApplicationKey wrappedApplicationKey
|
||||
) {
|
||||
return new android.security.keystore.recovery.WrappedApplicationKey.Builder()
|
||||
.setAlias(wrappedApplicationKey.getAlias())
|
||||
.setEncryptedKeyMaterial(wrappedApplicationKey.getEncryptedKeyMaterial())
|
||||
.build();
|
||||
}
|
||||
|
||||
static List<android.security.keystore.recovery.WrappedApplicationKey>
|
||||
fromLegacyWrappedApplicationKeys(List<WrappedApplicationKey> wrappedApplicationKeys
|
||||
) {
|
||||
return map(wrappedApplicationKeys, BackwardsCompat::fromLegacyWrappedApplicationKey);
|
||||
}
|
||||
|
||||
static List<android.security.keystore.recovery.KeyChainProtectionParams>
|
||||
fromLegacyKeychainProtectionParams(
|
||||
List<KeychainProtectionParams> keychainProtectionParams) {
|
||||
return map(keychainProtectionParams, BackwardsCompat::fromLegacyKeychainProtectionParam);
|
||||
}
|
||||
|
||||
static android.security.keystore.recovery.KeyChainProtectionParams
|
||||
fromLegacyKeychainProtectionParam(KeychainProtectionParams keychainProtectionParams) {
|
||||
return new android.security.keystore.recovery.KeyChainProtectionParams.Builder()
|
||||
.setUserSecretType(keychainProtectionParams.getUserSecretType())
|
||||
.setSecret(keychainProtectionParams.getSecret())
|
||||
.setLockScreenUiFormat(keychainProtectionParams.getLockScreenUiFormat())
|
||||
.setKeyDerivationParams(
|
||||
fromLegacyKeyDerivationParams(
|
||||
keychainProtectionParams.getKeyDerivationParams()))
|
||||
.build();
|
||||
}
|
||||
|
||||
static KeychainSnapshot toLegacyKeychainSnapshot(
|
||||
android.security.keystore.recovery.KeyChainSnapshot keychainSnapshot
|
||||
) {
|
||||
return new KeychainSnapshot.Builder()
|
||||
.setCounterId(keychainSnapshot.getCounterId())
|
||||
.setEncryptedRecoveryKeyBlob(keychainSnapshot.getEncryptedRecoveryKeyBlob())
|
||||
.setTrustedHardwarePublicKey(keychainSnapshot.getTrustedHardwarePublicKey())
|
||||
.setSnapshotVersion(keychainSnapshot.getSnapshotVersion())
|
||||
.setMaxAttempts(keychainSnapshot.getMaxAttempts())
|
||||
.setServerParams(keychainSnapshot.getServerParams())
|
||||
.setKeychainProtectionParams(
|
||||
map(keychainSnapshot.getKeyChainProtectionParams(),
|
||||
BackwardsCompat::toLegacyKeychainProtectionParams))
|
||||
.setWrappedApplicationKeys(
|
||||
map(keychainSnapshot.getWrappedApplicationKeys(),
|
||||
BackwardsCompat::toLegacyWrappedApplicationKey))
|
||||
.build();
|
||||
}
|
||||
|
||||
static <A, B> List<B> map(List<A> as, Function<A, B> f) {
|
||||
ArrayList<B> bs = new ArrayList<>(as.size());
|
||||
for (A a : as) {
|
||||
bs.add(f.apply(a));
|
||||
}
|
||||
return bs;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.BadCertificateFormatException}.
|
||||
* @hide
|
||||
*/
|
||||
public class BadCertificateFormatException extends RecoveryControllerException {
|
||||
public BadCertificateFormatException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.DecryptionFailedException}.
|
||||
* @hide
|
||||
*/
|
||||
public class DecryptionFailedException extends RecoveryControllerException {
|
||||
|
||||
public DecryptionFailedException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.InternalRecoveryServiceException}.
|
||||
* @hide
|
||||
*/
|
||||
public class InternalRecoveryServiceException extends RecoveryControllerException {
|
||||
public InternalRecoveryServiceException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public InternalRecoveryServiceException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.security.keystore;
|
||||
|
||||
import android.annotation.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;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.KeyDerivationParams}.
|
||||
* @hide
|
||||
*/
|
||||
public final class KeyDerivationParams implements Parcelable {
|
||||
private final int mAlgorithm;
|
||||
private byte[] mSalt;
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = {"ALGORITHM_"}, value = {ALGORITHM_SHA256, ALGORITHM_ARGON2ID})
|
||||
public @interface KeyDerivationAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* Salted SHA256
|
||||
*/
|
||||
public static final int ALGORITHM_SHA256 = 1;
|
||||
|
||||
/**
|
||||
* Argon2ID
|
||||
* @hide
|
||||
*/
|
||||
// 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 static KeyDerivationParams createSha256Params(@NonNull byte[] salt) {
|
||||
return new KeyDerivationParams(ALGORITHM_SHA256, salt);
|
||||
}
|
||||
|
||||
KeyDerivationParams(@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<KeyDerivationParams> CREATOR =
|
||||
new Parcelable.Creator<KeyDerivationParams>() {
|
||||
public KeyDerivationParams createFromParcel(Parcel in) {
|
||||
return new KeyDerivationParams(in);
|
||||
}
|
||||
|
||||
public KeyDerivationParams[] newArray(int length) {
|
||||
return new KeyDerivationParams[length];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(mAlgorithm);
|
||||
out.writeByteArray(mSalt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
protected KeyDerivationParams(Parcel in) {
|
||||
mAlgorithm = in.readInt();
|
||||
mSalt = in.createByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,269 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.security.keystore;
|
||||
|
||||
import android.annotation.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;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.KeyChainProtectionParams}.
|
||||
* @hide
|
||||
*/
|
||||
public final class KeychainProtectionParams 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 = 100;
|
||||
|
||||
/**
|
||||
* Custom passphrase, unrelated to lock screen, is required to recover KeyStore.
|
||||
*/
|
||||
public static final int TYPE_CUSTOM_PASSWORD = 101;
|
||||
|
||||
/** @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 Integer mUserSecretType;
|
||||
|
||||
@LockScreenUiFormat
|
||||
private Integer mLockScreenUiFormat;
|
||||
|
||||
/**
|
||||
* Parameters of the key derivation function, including algorithm, difficulty, salt.
|
||||
*/
|
||||
private KeyDerivationParams mKeyDerivationParams;
|
||||
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.
|
||||
* @hide
|
||||
*/
|
||||
public KeychainProtectionParams(@UserSecretType int userSecretType,
|
||||
@LockScreenUiFormat int lockScreenUiFormat,
|
||||
@NonNull KeyDerivationParams keyDerivationParams,
|
||||
@NonNull byte[] secret) {
|
||||
mUserSecretType = userSecretType;
|
||||
mLockScreenUiFormat = lockScreenUiFormat;
|
||||
mKeyDerivationParams = Preconditions.checkNotNull(keyDerivationParams);
|
||||
mSecret = Preconditions.checkNotNull(secret);
|
||||
}
|
||||
|
||||
private KeychainProtectionParams() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 TYPE_PIN
|
||||
* @see TYPE_PASSWORD
|
||||
* @see 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 KeyDerivationParams getKeyDerivationParams() {
|
||||
return mKeyDerivationParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Secret derived from user input.
|
||||
* Default value is empty array
|
||||
*
|
||||
* @return secret or empty array
|
||||
*/
|
||||
public @NonNull byte[] getSecret() {
|
||||
return mSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for creating {@link KeychainProtectionParams}.
|
||||
*/
|
||||
public static class Builder {
|
||||
private KeychainProtectionParams mInstance = new KeychainProtectionParams();
|
||||
|
||||
/**
|
||||
* 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 keyDerivationParams Key derivation Params
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setKeyDerivationParams(@NonNull KeyDerivationParams
|
||||
keyDerivationParams) {
|
||||
mInstance.mKeyDerivationParams = keyDerivationParams;
|
||||
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 KeychainProtectionParams} 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.
|
||||
*/
|
||||
@NonNull public KeychainProtectionParams build() {
|
||||
if (mInstance.mUserSecretType == null) {
|
||||
mInstance.mUserSecretType = TYPE_LOCKSCREEN;
|
||||
}
|
||||
Preconditions.checkNotNull(mInstance.mLockScreenUiFormat);
|
||||
Preconditions.checkNotNull(mInstance.mKeyDerivationParams);
|
||||
if (mInstance.mSecret == null) {
|
||||
mInstance.mSecret = new byte[]{};
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<KeychainProtectionParams> CREATOR =
|
||||
new Parcelable.Creator<KeychainProtectionParams>() {
|
||||
public KeychainProtectionParams createFromParcel(Parcel in) {
|
||||
return new KeychainProtectionParams(in);
|
||||
}
|
||||
|
||||
public KeychainProtectionParams[] newArray(int length) {
|
||||
return new KeychainProtectionParams[length];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(mUserSecretType);
|
||||
out.writeInt(mLockScreenUiFormat);
|
||||
out.writeTypedObject(mKeyDerivationParams, flags);
|
||||
out.writeByteArray(mSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
protected KeychainProtectionParams(Parcel in) {
|
||||
mUserSecretType = in.readInt();
|
||||
mLockScreenUiFormat = in.readInt();
|
||||
mKeyDerivationParams = in.readTypedObject(KeyDerivationParams.CREATOR);
|
||||
mSecret = in.createByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.security.keystore;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.KeyChainSnapshot}.
|
||||
* @hide
|
||||
*/
|
||||
public final class KeychainSnapshot implements Parcelable {
|
||||
private static final int DEFAULT_MAX_ATTEMPTS = 10;
|
||||
private static final long DEFAULT_COUNTER_ID = 1L;
|
||||
|
||||
private int mSnapshotVersion;
|
||||
private int mMaxAttempts = DEFAULT_MAX_ATTEMPTS;
|
||||
private long mCounterId = DEFAULT_COUNTER_ID;
|
||||
private byte[] mServerParams;
|
||||
private byte[] mPublicKey;
|
||||
private List<KeychainProtectionParams> mKeychainProtectionParams;
|
||||
private List<WrappedApplicationKey> mEntryRecoveryData;
|
||||
private byte[] mEncryptedRecoveryKeyBlob;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Deprecated, consider using builder.
|
||||
*/
|
||||
public KeychainSnapshot(
|
||||
int snapshotVersion,
|
||||
@NonNull List<KeychainProtectionParams> keychainProtectionParams,
|
||||
@NonNull List<WrappedApplicationKey> wrappedApplicationKeys,
|
||||
@NonNull byte[] encryptedRecoveryKeyBlob) {
|
||||
mSnapshotVersion = snapshotVersion;
|
||||
mKeychainProtectionParams =
|
||||
Preconditions.checkCollectionElementsNotNull(keychainProtectionParams,
|
||||
"keychainProtectionParams");
|
||||
mEntryRecoveryData = Preconditions.checkCollectionElementsNotNull(wrappedApplicationKeys,
|
||||
"wrappedApplicationKeys");
|
||||
mEncryptedRecoveryKeyBlob = Preconditions.checkNotNull(encryptedRecoveryKeyBlob);
|
||||
}
|
||||
|
||||
private KeychainSnapshot() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Snapshot version for given account. It is incremented when user secret or list of application
|
||||
* keys changes.
|
||||
*/
|
||||
public int getSnapshotVersion() {
|
||||
return mSnapshotVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of user secret guesses allowed during Keychain recovery.
|
||||
*/
|
||||
public int getMaxAttempts() {
|
||||
return mMaxAttempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* CounterId which is rotated together with user secret.
|
||||
*/
|
||||
public long getCounterId() {
|
||||
return mCounterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Server parameters.
|
||||
*/
|
||||
public @NonNull byte[] getServerParams() {
|
||||
return mServerParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public key used to encrypt {@code encryptedRecoveryKeyBlob}.
|
||||
*
|
||||
* See implementation for binary key format
|
||||
*/
|
||||
// TODO: document key format.
|
||||
public @NonNull byte[] getTrustedHardwarePublicKey() {
|
||||
return mPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* UI and key derivation parameters. Note that combination of secrets may be used.
|
||||
*/
|
||||
public @NonNull List<KeychainProtectionParams> getKeychainProtectionParams() {
|
||||
return mKeychainProtectionParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of application keys, with key material encrypted by
|
||||
* the recovery key ({@link #getEncryptedRecoveryKeyBlob}).
|
||||
*/
|
||||
public @NonNull List<WrappedApplicationKey> getWrappedApplicationKeys() {
|
||||
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<KeychainSnapshot> CREATOR =
|
||||
new Parcelable.Creator<KeychainSnapshot>() {
|
||||
public KeychainSnapshot createFromParcel(Parcel in) {
|
||||
return new KeychainSnapshot(in);
|
||||
}
|
||||
|
||||
public KeychainSnapshot[] newArray(int length) {
|
||||
return new KeychainSnapshot[length];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Builder for creating {@link KeychainSnapshot}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static class Builder {
|
||||
private KeychainSnapshot mInstance = new KeychainSnapshot();
|
||||
|
||||
/**
|
||||
* Snapshot version for given account.
|
||||
*
|
||||
* @param snapshotVersion The snapshot version
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setSnapshotVersion(int snapshotVersion) {
|
||||
mInstance.mSnapshotVersion = snapshotVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of user secret guesses allowed during Keychain recovery.
|
||||
*
|
||||
* @param maxAttempts The maximum number of guesses.
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setMaxAttempts(int maxAttempts) {
|
||||
mInstance.mMaxAttempts = maxAttempts;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets counter id.
|
||||
*
|
||||
* @param counterId The counter id.
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setCounterId(long counterId) {
|
||||
mInstance.mCounterId = counterId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets server parameters.
|
||||
*
|
||||
* @param serverParams The server parameters
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setServerParams(byte[] serverParams) {
|
||||
mInstance.mServerParams = serverParams;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets public key used to encrypt recovery blob.
|
||||
*
|
||||
* @param publicKey The public key
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setTrustedHardwarePublicKey(byte[] publicKey) {
|
||||
mInstance.mPublicKey = publicKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets UI and key derivation parameters
|
||||
*
|
||||
* @param recoveryMetadata The UI and key derivation parameters
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setKeychainProtectionParams(
|
||||
@NonNull List<KeychainProtectionParams> recoveryMetadata) {
|
||||
mInstance.mKeychainProtectionParams = recoveryMetadata;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of application keys.
|
||||
*
|
||||
* @param entryRecoveryData List of application keys
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setWrappedApplicationKeys(List<WrappedApplicationKey> 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 KeychainSnapshot} instance.
|
||||
*
|
||||
* @return new instance
|
||||
* @throws NullPointerException if some required fields were not set.
|
||||
*/
|
||||
@NonNull public KeychainSnapshot build() {
|
||||
Preconditions.checkCollectionElementsNotNull(mInstance.mKeychainProtectionParams,
|
||||
"recoveryMetadata");
|
||||
Preconditions.checkCollectionElementsNotNull(mInstance.mEntryRecoveryData,
|
||||
"entryRecoveryData");
|
||||
Preconditions.checkNotNull(mInstance.mEncryptedRecoveryKeyBlob);
|
||||
Preconditions.checkNotNull(mInstance.mServerParams);
|
||||
Preconditions.checkNotNull(mInstance.mPublicKey);
|
||||
return mInstance;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(mSnapshotVersion);
|
||||
out.writeTypedList(mKeychainProtectionParams);
|
||||
out.writeByteArray(mEncryptedRecoveryKeyBlob);
|
||||
out.writeTypedList(mEntryRecoveryData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
protected KeychainSnapshot(Parcel in) {
|
||||
mSnapshotVersion = in.readInt();
|
||||
mKeychainProtectionParams = in.createTypedArrayList(KeychainProtectionParams.CREATOR);
|
||||
mEncryptedRecoveryKeyBlob = in.createByteArray();
|
||||
mEntryRecoveryData = in.createTypedArrayList(WrappedApplicationKey.CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.LockScreenRequiredException}.
|
||||
* @hide
|
||||
*/
|
||||
public class LockScreenRequiredException extends RecoveryControllerException {
|
||||
public LockScreenRequiredException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.RecoverySession}.
|
||||
* @hide
|
||||
*/
|
||||
public class RecoveryClaim {
|
||||
|
||||
private final RecoverySession mRecoverySession;
|
||||
private final byte[] mClaimBytes;
|
||||
|
||||
RecoveryClaim(RecoverySession recoverySession, byte[] claimBytes) {
|
||||
mRecoverySession = recoverySession;
|
||||
mClaimBytes = claimBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the session associated with the recovery attempt. This is used to match the symmetric
|
||||
* key, which remains internal to the framework, for decrypting the claim response.
|
||||
*
|
||||
* @return The session data.
|
||||
*/
|
||||
public RecoverySession getRecoverySession() {
|
||||
return mRecoverySession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encrypted claim's bytes.
|
||||
*
|
||||
* <p>This should be sent by the recovery agent to the remote secure hardware, which will use
|
||||
* it to decrypt the keychain, before sending it re-encrypted with the session's symmetric key
|
||||
* to the device.
|
||||
*/
|
||||
public byte[] getClaimBytes() {
|
||||
return mClaimBytes;
|
||||
}
|
||||
}
|
||||
@@ -1,467 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.security.keystore;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.widget.ILockSettings;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.RecoveryController}.
|
||||
* @hide
|
||||
*/
|
||||
public class RecoveryController {
|
||||
private static final String TAG = "RecoveryController";
|
||||
|
||||
/** Key has been successfully synced. */
|
||||
public static final int RECOVERY_STATUS_SYNCED = 0;
|
||||
/** Waiting for recovery agent to sync the key. */
|
||||
public static final int RECOVERY_STATUS_SYNC_IN_PROGRESS = 1;
|
||||
/** Recovery account is not available. */
|
||||
public static final int RECOVERY_STATUS_MISSING_ACCOUNT = 2;
|
||||
/** Key cannot be synced. */
|
||||
public static final int RECOVERY_STATUS_PERMANENT_FAILURE = 3;
|
||||
|
||||
/**
|
||||
* Failed because no snapshot is yet pending to be synced for the user.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int ERROR_NO_SNAPSHOT_PENDING = 21;
|
||||
|
||||
/**
|
||||
* Failed due to an error internal to the recovery service. This is unexpected and indicates
|
||||
* either a problem with the logic in the service, or a problem with a dependency of the
|
||||
* service (such as AndroidKeyStore).
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int ERROR_SERVICE_INTERNAL_ERROR = 22;
|
||||
|
||||
/**
|
||||
* Failed because the user does not have a lock screen set.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int ERROR_INSECURE_USER = 23;
|
||||
|
||||
/**
|
||||
* Error thrown when attempting to use a recovery session that has since been closed.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int ERROR_SESSION_EXPIRED = 24;
|
||||
|
||||
/**
|
||||
* Failed because the provided certificate was not a valid X509 certificate.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int ERROR_BAD_CERTIFICATE_FORMAT = 25;
|
||||
|
||||
/**
|
||||
* Error thrown if decryption failed. This might be because the tag is wrong, the key is wrong,
|
||||
* the data has become corrupted, the data has been tampered with, etc.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int ERROR_DECRYPTION_FAILED = 26;
|
||||
|
||||
|
||||
private final ILockSettings mBinder;
|
||||
|
||||
private RecoveryController(ILockSettings binder) {
|
||||
mBinder = binder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated.
|
||||
* Gets a new instance of the class.
|
||||
*/
|
||||
public static RecoveryController getInstance() {
|
||||
throw new UnsupportedOperationException("using Deprecated RecoveryController version");
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes key recovery service for the calling application. RecoveryController
|
||||
* randomly chooses one of the keys from the list and keeps it to use for future key export
|
||||
* operations. Collection of all keys in the list must be signed by the provided {@code
|
||||
* rootCertificateAlias}, which must also be present in the list of root certificates
|
||||
* preinstalled on the device. The random selection allows RecoveryController to select
|
||||
* which of a set of remote recovery service devices will be used.
|
||||
*
|
||||
* <p>In addition, RecoveryController enforces a delay of three months between
|
||||
* consecutive initialization attempts, to limit the ability of an attacker to often switch
|
||||
* remote recovery devices and significantly increase number of recovery attempts.
|
||||
*
|
||||
* @param rootCertificateAlias alias of a root certificate preinstalled on the device
|
||||
* @param signedPublicKeyList binary blob a list of X509 certificates and signature
|
||||
* @throws BadCertificateFormatException if the {@code signedPublicKeyList} is in a bad format.
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
public void initRecoveryService(
|
||||
@NonNull String rootCertificateAlias, @NonNull byte[] signedPublicKeyList)
|
||||
throws BadCertificateFormatException, InternalRecoveryServiceException {
|
||||
throw new UnsupportedOperationException("Deprecated initRecoveryService method called");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data necessary to store all recoverable keys for given account. Key material is
|
||||
* encrypted with user secret and recovery public key.
|
||||
*
|
||||
* @param account specific to Recovery agent.
|
||||
* @return Data necessary to recover keystore.
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
public @NonNull KeychainSnapshot getRecoveryData(@NonNull byte[] account)
|
||||
throws InternalRecoveryServiceException {
|
||||
try {
|
||||
return BackwardsCompat.toLegacyKeychainSnapshot(mBinder.getKeyChainSnapshot());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (ServiceSpecificException e) {
|
||||
if (e.errorCode == ERROR_NO_SNAPSHOT_PENDING) {
|
||||
return null;
|
||||
}
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a listener which notifies recovery agent that new recovery snapshot is available. {@link
|
||||
* #getRecoveryData} can be used to get the snapshot. Note that every recovery agent can have at
|
||||
* most one registered listener at any time.
|
||||
*
|
||||
* @param intent triggered when new snapshot is available. Unregisters listener if the value is
|
||||
* {@code null}.
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
public void setSnapshotCreatedPendingIntent(@Nullable PendingIntent intent)
|
||||
throws InternalRecoveryServiceException {
|
||||
try {
|
||||
mBinder.setSnapshotCreatedPendingIntent(intent);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map from recovery agent accounts to corresponding KeyStore recovery snapshot
|
||||
* version. Version zero is used, if no snapshots were created for the account.
|
||||
*
|
||||
* @return Map from recovery agent accounts to snapshot versions.
|
||||
* @see KeychainSnapshot#getSnapshotVersion
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
public @NonNull Map<byte[], Integer> getRecoverySnapshotVersions()
|
||||
throws InternalRecoveryServiceException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Server parameters used to generate new recovery key blobs. This value will be included in
|
||||
* {@code KeychainSnapshot.getEncryptedRecoveryKeyBlob()}. The same value must be included
|
||||
* in vaultParams {@link #startRecoverySession}
|
||||
*
|
||||
* @param serverParams included in recovery key blob.
|
||||
* @see #getRecoveryData
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
public void setServerParams(byte[] serverParams) throws InternalRecoveryServiceException {
|
||||
try {
|
||||
mBinder.setServerParams(serverParams);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates recovery status for given keys. It is used to notify keystore that key was
|
||||
* successfully stored on the server or there were an error. Application can check this value
|
||||
* using {@code getRecoveyStatus}.
|
||||
*
|
||||
* @param packageName Application whose recoverable keys' statuses are to be updated.
|
||||
* @param aliases List of application-specific key aliases. If the array is empty, updates the
|
||||
* status for all existing recoverable keys.
|
||||
* @param status Status specific to recovery agent.
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
public void setRecoveryStatus(
|
||||
@NonNull String packageName, @Nullable String[] aliases, int status)
|
||||
throws NameNotFoundException, InternalRecoveryServiceException {
|
||||
try {
|
||||
for (String alias : aliases) {
|
||||
mBinder.setRecoveryStatus(alias, status);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Map} from Application's KeyStore key aliases to their recovery status.
|
||||
* Negative status values are reserved for recovery agent specific codes. List of common codes:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link #RECOVERY_STATUS_SYNCED}
|
||||
* <li>{@link #RECOVERY_STATUS_SYNC_IN_PROGRESS}
|
||||
* <li>{@link #RECOVERY_STATUS_MISSING_ACCOUNT}
|
||||
* <li>{@link #RECOVERY_STATUS_PERMANENT_FAILURE}
|
||||
* </ul>
|
||||
*
|
||||
* @return {@code Map} from KeyStore alias to recovery status.
|
||||
* @see #setRecoveryStatus
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
public Map<String, Integer> getRecoveryStatus() throws InternalRecoveryServiceException {
|
||||
try {
|
||||
// IPC doesn't support generic Maps.
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Integer> result =
|
||||
(Map<String, Integer>) mBinder.getRecoveryStatus();
|
||||
return result;
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a set of secret types used for end-to-end keystore encryption. Knowing all of them
|
||||
* is necessary to recover data.
|
||||
*
|
||||
* @param secretTypes {@link KeychainProtectionParams#TYPE_LOCKSCREEN} or {@link
|
||||
* KeychainProtectionParams#TYPE_CUSTOM_PASSWORD}
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
public void setRecoverySecretTypes(
|
||||
@NonNull @KeychainProtectionParams.UserSecretType int[] secretTypes)
|
||||
throws InternalRecoveryServiceException {
|
||||
try {
|
||||
mBinder.setRecoverySecretTypes(secretTypes);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a set of secret types used for end-to-end keystore encryption. Knowing all of them is
|
||||
* necessary to generate KeychainSnapshot.
|
||||
*
|
||||
* @return list of recovery secret types
|
||||
* @see KeychainSnapshot
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
public @NonNull @KeychainProtectionParams.UserSecretType int[] getRecoverySecretTypes()
|
||||
throws InternalRecoveryServiceException {
|
||||
try {
|
||||
return mBinder.getRecoverySecretTypes();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of recovery secret types, necessary to create a pending recovery snapshot.
|
||||
* When user enters a secret of a pending type {@link #recoverySecretAvailable} should be
|
||||
* called.
|
||||
*
|
||||
* @return list of recovery secret types
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
@NonNull
|
||||
public @KeychainProtectionParams.UserSecretType int[] getPendingRecoverySecretTypes()
|
||||
throws InternalRecoveryServiceException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes recovery session and returns a blob with proof of recovery secrets possession.
|
||||
* The method generates symmetric key for a session, which trusted remote device can use to
|
||||
* return recovery key.
|
||||
*
|
||||
* @param verifierPublicKey Encoded {@code java.security.cert.X509Certificate} with Public key
|
||||
* used to create the recovery blob on the source device.
|
||||
* Keystore will verify the certificate using root of trust.
|
||||
* @param vaultParams Must match the parameters in the corresponding field in the recovery blob.
|
||||
* Used to limit number of guesses.
|
||||
* @param vaultChallenge Data passed from server for this recovery session and used to prevent
|
||||
* replay attacks
|
||||
* @param secrets Secrets provided by user, the method only uses type and secret fields.
|
||||
* @return The recovery claim. Claim provides a b binary blob with recovery claim. It is
|
||||
* encrypted with verifierPublicKey and contains a proof of user secrets, session symmetric
|
||||
* key and parameters necessary to identify the counter with the number of failed recovery
|
||||
* attempts.
|
||||
* @throws BadCertificateFormatException if the {@code verifierPublicKey} is in an incorrect
|
||||
* format.
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
@NonNull public RecoveryClaim startRecoverySession(
|
||||
@NonNull byte[] verifierPublicKey,
|
||||
@NonNull byte[] vaultParams,
|
||||
@NonNull byte[] vaultChallenge,
|
||||
@NonNull List<KeychainProtectionParams> secrets)
|
||||
throws BadCertificateFormatException, InternalRecoveryServiceException {
|
||||
try {
|
||||
RecoverySession recoverySession = RecoverySession.newInstance(this);
|
||||
byte[] recoveryClaim =
|
||||
mBinder.startRecoverySession(
|
||||
recoverySession.getSessionId(),
|
||||
verifierPublicKey,
|
||||
vaultParams,
|
||||
vaultChallenge,
|
||||
BackwardsCompat.fromLegacyKeychainProtectionParams(secrets));
|
||||
return new RecoveryClaim(recoverySession, recoveryClaim);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (ServiceSpecificException e) {
|
||||
if (e.errorCode == ERROR_BAD_CERTIFICATE_FORMAT) {
|
||||
throw new BadCertificateFormatException(e.getMessage());
|
||||
}
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports keys.
|
||||
*
|
||||
* @param session Related recovery session, as originally created by invoking
|
||||
* {@link #startRecoverySession(byte[], byte[], byte[], List)}.
|
||||
* @param recoveryKeyBlob Recovery blob encrypted by symmetric key generated for this session.
|
||||
* @param applicationKeys Application keys. Key material can be decrypted using recoveryKeyBlob
|
||||
* and session. KeyStore only uses package names from the application info in {@link
|
||||
* WrappedApplicationKey}. Caller is responsibility to perform certificates check.
|
||||
* @return Map from alias to raw key material.
|
||||
* @throws SessionExpiredException if {@code session} has since been closed.
|
||||
* @throws DecryptionFailedException if unable to decrypt the snapshot.
|
||||
* @throws InternalRecoveryServiceException if an error occurs internal to the recovery service.
|
||||
*/
|
||||
public Map<String, byte[]> recoverKeys(
|
||||
@NonNull RecoverySession session,
|
||||
@NonNull byte[] recoveryKeyBlob,
|
||||
@NonNull List<WrappedApplicationKey> applicationKeys)
|
||||
throws SessionExpiredException, DecryptionFailedException,
|
||||
InternalRecoveryServiceException {
|
||||
try {
|
||||
return (Map<String, byte[]>) mBinder.recoverKeys(
|
||||
session.getSessionId(),
|
||||
recoveryKeyBlob,
|
||||
BackwardsCompat.fromLegacyWrappedApplicationKeys(applicationKeys));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (ServiceSpecificException e) {
|
||||
if (e.errorCode == ERROR_DECRYPTION_FAILED) {
|
||||
throw new DecryptionFailedException(e.getMessage());
|
||||
}
|
||||
if (e.errorCode == ERROR_SESSION_EXPIRED) {
|
||||
throw new SessionExpiredException(e.getMessage());
|
||||
}
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all data associated with {@code session}. Should not be invoked directly but via
|
||||
* {@link RecoverySession#close()}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
void closeSession(RecoverySession session) {
|
||||
try {
|
||||
mBinder.closeSession(session.getSessionId());
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
Log.e(TAG, "Unexpected error trying to close session", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a key called {@code alias} and loads it into the recoverable key store. Returns the
|
||||
* raw material of the key.
|
||||
*
|
||||
* @param alias The key alias.
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
* @throws LockScreenRequiredException if the user has not set a lock screen. This is required
|
||||
* to generate recoverable keys, as the snapshots are encrypted using a key derived from the
|
||||
* lock screen.
|
||||
*/
|
||||
public byte[] generateAndStoreKey(@NonNull String alias)
|
||||
throws InternalRecoveryServiceException, LockScreenRequiredException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a key called {@code alias} from the recoverable key store.
|
||||
*
|
||||
* @param alias The key alias.
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
*/
|
||||
public void removeKey(@NonNull String alias) throws InternalRecoveryServiceException {
|
||||
try {
|
||||
mBinder.removeKey(alias);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private InternalRecoveryServiceException wrapUnexpectedServiceSpecificException(
|
||||
ServiceSpecificException e) {
|
||||
if (e.errorCode == ERROR_SERVICE_INTERNAL_ERROR) {
|
||||
return new InternalRecoveryServiceException(e.getMessage());
|
||||
}
|
||||
|
||||
// Should never happen. If it does, it's a bug, and we need to update how the method that
|
||||
// called this throws its exceptions.
|
||||
return new InternalRecoveryServiceException("Unexpected error code for method: "
|
||||
+ e.errorCode, e);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 java.security.GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.RecoveryController}.
|
||||
* @hide
|
||||
*/
|
||||
public abstract class RecoveryControllerException extends GeneralSecurityException {
|
||||
RecoveryControllerException() { }
|
||||
|
||||
RecoveryControllerException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public RecoveryControllerException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.RecoverySession}.
|
||||
* @hide
|
||||
*/
|
||||
public class RecoverySession implements AutoCloseable {
|
||||
|
||||
private static final int SESSION_ID_LENGTH_BYTES = 16;
|
||||
|
||||
private final String mSessionId;
|
||||
private final RecoveryController mRecoveryController;
|
||||
|
||||
private RecoverySession(RecoveryController recoveryController, String sessionId) {
|
||||
mRecoveryController = recoveryController;
|
||||
mSessionId = sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* A new session, started by {@code recoveryManager}.
|
||||
*/
|
||||
static RecoverySession newInstance(RecoveryController recoveryController) {
|
||||
return new RecoverySession(recoveryController, newSessionId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new random session ID.
|
||||
*/
|
||||
private static String newSessionId() {
|
||||
SecureRandom secureRandom = new SecureRandom();
|
||||
byte[] sessionId = new byte[SESSION_ID_LENGTH_BYTES];
|
||||
secureRandom.nextBytes(sessionId);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : sessionId) {
|
||||
sb.append(Byte.toHexString(b, /*upperCase=*/ false));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal session ID, used by the framework to match recovery claims to snapshot responses.
|
||||
*/
|
||||
String getSessionId() {
|
||||
return mSessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
mRecoveryController.closeSession(this);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.SessionExpiredException}.
|
||||
* @hide
|
||||
*/
|
||||
public class SessionExpiredException extends RecoveryControllerException {
|
||||
public SessionExpiredException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.security.keystore;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link android.security.keystore.recovery.WrappedApplicationKey}.
|
||||
* @hide
|
||||
*/
|
||||
public final class WrappedApplicationKey implements Parcelable {
|
||||
private String mAlias;
|
||||
// The only supported format is AES-256 symmetric key.
|
||||
private byte[] mEncryptedKeyMaterial;
|
||||
|
||||
/**
|
||||
* Builder for creating {@link WrappedApplicationKey}.
|
||||
*/
|
||||
public static class Builder {
|
||||
private WrappedApplicationKey mInstance = new WrappedApplicationKey();
|
||||
|
||||
/**
|
||||
* 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 WrappedApplicationKey} instance.
|
||||
*
|
||||
* @return new instance
|
||||
* @throws NullPointerException if some required fields were not set.
|
||||
*/
|
||||
@NonNull public WrappedApplicationKey build() {
|
||||
Preconditions.checkNotNull(mInstance.mAlias);
|
||||
Preconditions.checkNotNull(mInstance.mEncryptedKeyMaterial);
|
||||
return mInstance;
|
||||
}
|
||||
}
|
||||
|
||||
private WrappedApplicationKey() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - consider using Builder.
|
||||
* @hide
|
||||
*/
|
||||
public WrappedApplicationKey(@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<WrappedApplicationKey> CREATOR =
|
||||
new Parcelable.Creator<WrappedApplicationKey>() {
|
||||
public WrappedApplicationKey createFromParcel(Parcel in) {
|
||||
return new WrappedApplicationKey(in);
|
||||
}
|
||||
|
||||
public WrappedApplicationKey[] newArray(int length) {
|
||||
return new WrappedApplicationKey[length];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(mAlias);
|
||||
out.writeByteArray(mEncryptedKeyMaterial);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
protected WrappedApplicationKey(Parcel in) {
|
||||
mAlias = in.readString();
|
||||
mEncryptedKeyMaterial = in.createByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user