CryptoObjectUtils.java
/*
* Copyright 2020 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 androidx.biometric;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import java.security.Signature;
import javax.crypto.Cipher;
import javax.crypto.Mac;
/**
* Utility class for converting between different types of crypto objects that may be used
* internally by {@link BiometricPrompt} and {@link BiometricManager}.
*/
class CryptoObjectUtils {
// Prevent instantiation.
private CryptoObjectUtils() {}
/**
* Unwraps a crypto object returned by {@link android.hardware.biometrics.BiometricPrompt}.
*
* @param cryptoObject A crypto object from {@link android.hardware.biometrics.BiometricPrompt}.
* @return An equivalent {@link androidx.biometric.BiometricPrompt.CryptoObject} instance.
*/
@RequiresApi(Build.VERSION_CODES.P)
@Nullable
static BiometricPrompt.CryptoObject unwrapFromBiometricPrompt(
@Nullable android.hardware.biometrics.BiometricPrompt.CryptoObject cryptoObject) {
if (cryptoObject == null) {
return null;
}
final Cipher cipher = Api28Impl.getCipher(cryptoObject);
if (cipher != null) {
return new BiometricPrompt.CryptoObject(cipher);
}
final Signature signature = Api28Impl.getSignature(cryptoObject);
if (signature != null) {
return new BiometricPrompt.CryptoObject(signature);
}
final Mac mac = Api28Impl.getMac(cryptoObject);
if (mac != null) {
return new BiometricPrompt.CryptoObject(mac);
}
return null;
}
/**
* Wraps a crypto object to be passed to {@link android.hardware.biometrics.BiometricPrompt}.
*
* @param cryptoObject An instance of {@link androidx.biometric.BiometricPrompt.CryptoObject}.
* @return An equivalent crypto object that is compatible with
* {@link android.hardware.biometrics.BiometricPrompt}.
*/
@RequiresApi(Build.VERSION_CODES.P)
@Nullable
static android.hardware.biometrics.BiometricPrompt.CryptoObject
wrapForBiometricPrompt(@Nullable BiometricPrompt.CryptoObject cryptoObject) {
if (cryptoObject == null) {
return null;
}
final Cipher cipher = cryptoObject.getCipher();
if (cipher != null) {
return Api28Impl.create(cipher);
}
final Signature signature = cryptoObject.getSignature();
if (signature != null) {
return Api28Impl.create(signature);
}
final Mac mac = cryptoObject.getMac();
if (mac != null) {
return Api28Impl.create(mac);
}
return null;
}
/**
* Unwraps a crypto object returned by
* {@link androidx.core.hardware.fingerprint.FingerprintManagerCompat}.
*
* @param cryptoObject A crypto object from
* {@link androidx.core.hardware.fingerprint.FingerprintManagerCompat}.
* @return An equivalent {@link androidx.biometric.BiometricPrompt.CryptoObject} instance.
*/
@SuppressWarnings("deprecation")
@Nullable
static BiometricPrompt.CryptoObject unwrapFromFingerprintManager(
@Nullable androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject
cryptoObject) {
if (cryptoObject == null) {
return null;
}
final Cipher cipher = cryptoObject.getCipher();
if (cipher != null) {
return new BiometricPrompt.CryptoObject(cipher);
}
final Signature signature = cryptoObject.getSignature();
if (signature != null) {
return new BiometricPrompt.CryptoObject(signature);
}
final Mac mac = cryptoObject.getMac();
if (mac != null) {
return new BiometricPrompt.CryptoObject(mac);
}
return null;
}
/**
* Wraps a crypto object to be passed to
* {@link androidx.core.hardware.fingerprint.FingerprintManagerCompat}.
*
* @param cryptoObject An instance of {@link androidx.biometric.BiometricPrompt.CryptoObject}.
* @return An equivalent crypto object that is compatible with
* {@link androidx.core.hardware.fingerprint.FingerprintManagerCompat}.
*/
@SuppressWarnings("deprecation")
@Nullable
static androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject
wrapForFingerprintManager(@Nullable BiometricPrompt.CryptoObject cryptoObject) {
if (cryptoObject == null) {
return null;
}
final Cipher cipher = cryptoObject.getCipher();
if (cipher != null) {
return new androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject(
cipher);
}
final Signature signature = cryptoObject.getSignature();
if (signature != null) {
return new androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject(
signature);
}
final Mac mac = cryptoObject.getMac();
if (mac != null) {
return new androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject(
mac);
}
return null;
}
/**
* Nested class to avoid verification errors for methods introduced in Android 9.0 (API 28).
*/
@RequiresApi(Build.VERSION_CODES.P)
private static class Api28Impl {
/**
* Creates an instance of the framework class
* {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} from the given cipher.
*
* @param cipher The cipher object to be wrapped.
* @return An instance of {@link android.hardware.biometrics.BiometricPrompt.CryptoObject}.
*/
static android.hardware.biometrics.BiometricPrompt.CryptoObject create(
@NonNull Cipher cipher) {
return new android.hardware.biometrics.BiometricPrompt.CryptoObject(cipher);
}
/**
* Creates an instance of the framework class
* {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} from the given
* signature.
*
* @param signature The signature object to be wrapped.
* @return An instance of {@link android.hardware.biometrics.BiometricPrompt.CryptoObject}.
*/
static android.hardware.biometrics.BiometricPrompt.CryptoObject create(
@NonNull Signature signature) {
return new android.hardware.biometrics.BiometricPrompt.CryptoObject(signature);
}
/**
* Creates an instance of the framework class
* {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} from the given MAC.
*
* @param mac The MAC object to be wrapped.
* @return An instance of {@link android.hardware.biometrics.BiometricPrompt.CryptoObject}.
*/
static android.hardware.biometrics.BiometricPrompt.CryptoObject create(@NonNull Mac mac) {
return new android.hardware.biometrics.BiometricPrompt.CryptoObject(mac);
}
/**
* Gets the cipher associated with the given crypto object, if any.
*
* @param crypto An instance of
* {@link android.hardware.biometrics.BiometricPrompt.CryptoObject}.
* @return The wrapped cipher object, or {@code null}.
*/
@Nullable
static Cipher getCipher(
@NonNull android.hardware.biometrics.BiometricPrompt.CryptoObject crypto) {
return crypto.getCipher();
}
/**
* Gets the signature associated with the given crypto object, if any.
*
* @param crypto An instance of
* {@link android.hardware.biometrics.BiometricPrompt.CryptoObject}.
* @return The wrapped signature object, or {@code null}.
*/
@Nullable
static Signature getSignature(
@NonNull android.hardware.biometrics.BiometricPrompt.CryptoObject crypto) {
return crypto.getSignature();
}
/**
* Gets the MAC associated with the given crypto object, if any.
*
* @param crypto An instance of
* {@link android.hardware.biometrics.BiometricPrompt.CryptoObject}.
* @return The wrapped MAC object, or {@code null}.
*/
@Nullable
static Mac getMac(
@NonNull android.hardware.biometrics.BiometricPrompt.CryptoObject crypto) {
return crypto.getMac();
}
}
}