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/R$styleable;->Window_windowFrame:I
|
||||||
Landroid/security/keystore/AndroidKeyStoreProvider;->getKeyStoreOperationHandle(Ljava/lang/Object;)J
|
Landroid/security/keystore/AndroidKeyStoreProvider;->getKeyStoreOperationHandle(Ljava/lang/Object;)J
|
||||||
Landroid/security/KeyStore;->getInstance()Landroid/security/KeyStore;
|
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/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;->onConnectFailed()V
|
||||||
Landroid/service/media/IMediaBrowserServiceCallbacks;->onConnect(Ljava/lang/String;Landroid/media/session/MediaSession$Token;Landroid/os/Bundle;)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