From 469cbf5156ad54650726ade59f2ee5aa01359ec2 Mon Sep 17 00:00:00 2001 From: Alex Klyubin Date: Thu, 4 Jun 2015 12:36:27 -0700 Subject: [PATCH] Deprecate KeyChain.isBoundKeyAlgorithm. This is bad API. There was never a guarantee that when this method returns true for a key algorithm (e.g., RSA or EC), then all keys of that type will be imported into secure hardware. For example, the secure hardware may reject a key if it's of unsupported size or uses an unsupported public exponent or EC curve. In that case, the key will be imported into keystore/KeyChain without being backed by secure hardware. Bug: 18088752 Change-Id: I8daa574a2e703a347d09d93401cd1ea2d0162ed9 --- api/current.txt | 2 +- api/system-current.txt | 2 +- keystore/java/android/security/KeyChain.java | 15 +++++++++++++++ keystore/java/android/security/KeyStore.java | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/api/current.txt b/api/current.txt index 49e226874efd4..b433d2a289b5b 100644 --- a/api/current.txt +++ b/api/current.txt @@ -28393,7 +28393,7 @@ package android.security { method public static android.content.Intent createInstallIntent(); method public static java.security.cert.X509Certificate[] getCertificateChain(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException; method public static java.security.PrivateKey getPrivateKey(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException; - method public static boolean isBoundKeyAlgorithm(java.lang.String); + method public static deprecated boolean isBoundKeyAlgorithm(java.lang.String); method public static boolean isKeyAlgorithmSupported(java.lang.String); field public static final java.lang.String ACTION_STORAGE_CHANGED = "android.security.STORAGE_CHANGED"; field public static final java.lang.String EXTRA_CERTIFICATE = "CERT"; diff --git a/api/system-current.txt b/api/system-current.txt index 3e8b065c62ff5..cc7deef9635e7 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -30426,7 +30426,7 @@ package android.security { method public static android.content.Intent createInstallIntent(); method public static java.security.cert.X509Certificate[] getCertificateChain(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException; method public static java.security.PrivateKey getPrivateKey(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException; - method public static boolean isBoundKeyAlgorithm(java.lang.String); + method public static deprecated boolean isBoundKeyAlgorithm(java.lang.String); method public static boolean isKeyAlgorithmSupported(java.lang.String); field public static final java.lang.String ACTION_STORAGE_CHANGED = "android.security.STORAGE_CHANGED"; field public static final java.lang.String EXTRA_CERTIFICATE = "CERT"; diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java index 817b7c9538284..059d8e6dbf008 100644 --- a/keystore/java/android/security/KeyChain.java +++ b/keystore/java/android/security/KeyChain.java @@ -29,11 +29,13 @@ import android.os.Looper; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; +import android.security.keystore.KeyInfo; import android.security.keystore.KeyProperties; import java.io.ByteArrayInputStream; import java.io.Closeable; import java.security.InvalidKeyException; +import java.security.KeyFactory; import java.security.Principal; import java.security.PrivateKey; import java.security.cert.Certificate; @@ -442,7 +444,20 @@ public final class KeyChain { * imported or generated. This can be used to tell if there is special * hardware support that can be used to bind keys to the device in a way * that makes it non-exportable. + * + * @deprecated Whether the key is bound to the secure hardware is known only + * once the key has been imported. To find out, use: + *
{@code
+     * PrivateKey key = ...; // private key from KeyChain
+     *
+     * KeyFactory keyFactory =
+     *     KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
+     * KeyInfo keyInfo = keyFactory.getKeySpec(key, KeyInfo.class);
+     * if (keyInfo.isInsideSecureHardware()) {
+     *     // The key is bound to the secure hardware of this Android
+     * }}
*/ + @Deprecated public static boolean isBoundKeyAlgorithm( @NonNull @KeyProperties.KeyAlgorithmEnum String algorithm) { if (!isKeyAlgorithmSupported(algorithm)) { diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 367257ab9bee1..ad348f8fdf753 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -383,7 +383,7 @@ public class KeyStore { } } - // TODO remove this when it's removed from Settings + // TODO: remove this when it's removed from Settings public boolean isHardwareBacked() { return isHardwareBacked("RSA"); }