From 5418393c58d1d80fe37a209ab931f6d56bd46a86 Mon Sep 17 00:00:00 2001 From: Alex Klyubin Date: Fri, 8 May 2015 15:25:48 -0700 Subject: [PATCH] Document when encrypted AndroidKeyStore keys are wiped. This also drops the boolean parameter from KeyGeneratorSpec.Builder.setEncryptionRequired to match the already launched KeyPairGeneratorSpec.Builder.setEncryptionRequired. Bug: 18088752 Change-Id: I91a3e8c77958971b1bda8329319f1a0d8043b669 --- api/current.txt | 2 +- api/system-current.txt | 2 +- .../java/android/security/AndroidKeyStore.java | 5 +++-- .../android/security/KeyGeneratorSpec.java | 13 ++++++------- .../android/security/KeyPairGeneratorSpec.java | 9 ++++++--- keystore/java/android/security/KeyStore.java | 18 +++++++++++++++++- .../android/security/KeyStoreParameter.java | 13 ++++++++----- 7 files changed, 42 insertions(+), 20 deletions(-) diff --git a/api/current.txt b/api/current.txt index 07137f15052ea..b89edcfa54cbb 100644 --- a/api/current.txt +++ b/api/current.txt @@ -28432,7 +28432,7 @@ package android.security { method public android.security.KeyGeneratorSpec.Builder setAlias(java.lang.String); method public android.security.KeyGeneratorSpec.Builder setBlockModes(java.lang.String...); method public android.security.KeyGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...); - method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired(boolean); + method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired(); method public android.security.KeyGeneratorSpec.Builder setKeySize(int); method public android.security.KeyGeneratorSpec.Builder setKeyValidityEnd(java.util.Date); method public android.security.KeyGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date); diff --git a/api/system-current.txt b/api/system-current.txt index 00da3d334c67f..1bf273adac282 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -30446,7 +30446,7 @@ package android.security { method public android.security.KeyGeneratorSpec.Builder setAlias(java.lang.String); method public android.security.KeyGeneratorSpec.Builder setBlockModes(java.lang.String...); method public android.security.KeyGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...); - method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired(boolean); + method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired(); method public android.security.KeyGeneratorSpec.Builder setKeySize(int); method public android.security.KeyGeneratorSpec.Builder setKeyValidityEnd(java.util.Date); method public android.security.KeyGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date); diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java index e82ff6a70acd6..69d80e6441125 100644 --- a/keystore/java/android/security/AndroidKeyStore.java +++ b/keystore/java/android/security/AndroidKeyStore.java @@ -103,8 +103,9 @@ public class AndroidKeyStore extends KeyStoreSpi { keyAliasInKeystore, null, null, keyCharacteristics); if ((errorCode != KeymasterDefs.KM_ERROR_OK) && (errorCode != android.security.KeyStore.NO_ERROR)) { - throw new UnrecoverableKeyException("Failed to load information about key." - + " Error code: " + errorCode); + throw (UnrecoverableKeyException) + new UnrecoverableKeyException("Failed to load information about key") + .initCause(mKeyStore.getInvalidKeyException(alias, errorCode)); } int keymasterAlgorithm = diff --git a/keystore/java/android/security/KeyGeneratorSpec.java b/keystore/java/android/security/KeyGeneratorSpec.java index 5a10a0a3f109b..97e3a676fe961 100644 --- a/keystore/java/android/security/KeyGeneratorSpec.java +++ b/keystore/java/android/security/KeyGeneratorSpec.java @@ -306,16 +306,15 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec { * secure lock screen credential (e.g., password, PIN, or pattern). * *

Note that this feature requires that the secure lock screen (e.g., password, PIN, - * pattern) is set up. Otherwise key generation will fail. + * pattern) is set up, otherwise key generation will fail. Moreover, this key will be + * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device + * Administrator). Finally, this key cannot be used until the user unlocks the secure lock + * screen after boot. * * @see KeyguardManager#isDeviceSecure() */ - public Builder setEncryptionRequired(boolean required) { - if (required) { - mFlags |= KeyStore.FLAG_ENCRYPTED; - } else { - mFlags &= ~KeyStore.FLAG_ENCRYPTED; - } + public Builder setEncryptionRequired() { + mFlags |= KeyStore.FLAG_ENCRYPTED; return this; } diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java index 1fcb355a874f0..7fd5cb5af35fb 100644 --- a/keystore/java/android/security/KeyPairGeneratorSpec.java +++ b/keystore/java/android/security/KeyPairGeneratorSpec.java @@ -654,11 +654,14 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { } /** - * Indicates that this key must be encrypted at rest. This will protect the key pair with - * the secure lock screen credential (e.g., password, PIN, or pattern). + * Indicates that this key pair must be encrypted at rest. This will protect the key pair + * with the secure lock screen credential (e.g., password, PIN, or pattern). * *

Note that this feature requires that the secure lock screen (e.g., password, PIN, - * pattern) is set up. Otherwise key pair generation will fail. + * pattern) is set up, otherwise key pair generation will fail. Moreover, this key pair will + * be deleted when the secure lock screen is disabled or reset (e.g., by the user or a + * Device Administrator). Finally, this key pair cannot be used until the user unlocks the + * secure lock screen after boot. * * @see KeyguardManager#isDeviceSecure() */ diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 53963a6b08203..3ed8899c4c1fd 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -18,6 +18,7 @@ package android.security; import android.app.ActivityThread; import android.app.Application; +import android.app.KeyguardManager; import com.android.org.conscrypt.NativeConstants; import android.content.Context; @@ -73,6 +74,19 @@ public class KeyStore { // Flags for "put" "import" and "generate" public static final int FLAG_NONE = 0; + + /** + * Indicates that this key (or key pair) must be encrypted at rest. This will protect the key + * (or key pair) with the secure lock screen credential (e.g., password, PIN, or pattern). + * + *

Note that this requires that the secure lock screen (e.g., password, PIN, pattern) is set + * up, otherwise key (or key pair) generation or import will fail. Moreover, this key (or key + * pair) will be deleted when the secure lock screen is disabled or reset (e.g., by the user or + * a Device Administrator). Finally, this key (or key pair) cannot be used until the user + * unlocks the secure lock screen after boot. + * + * @see KeyguardManager#isDeviceSecure() + */ public static final int FLAG_ENCRYPTED = 1; // States @@ -582,7 +596,7 @@ public class KeyStore { case NO_ERROR: return new KeyStoreException(errorCode, "OK"); case LOCKED: - return new KeyStoreException(errorCode, "Keystore locked"); + return new KeyStoreException(errorCode, "User authentication required"); case UNINITIALIZED: return new KeyStoreException(errorCode, "Keystore not initialized"); case SYSTEM_ERROR: @@ -619,6 +633,8 @@ public class KeyStore { */ InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, KeyStoreException e) { switch (e.getErrorCode()) { + case LOCKED: + return new UserNotAuthenticatedException(); case KeymasterDefs.KM_ERROR_KEY_EXPIRED: return new KeyExpiredException(); case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID: diff --git a/keystore/java/android/security/KeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java index ea5ca7110f407..7332332be4080 100644 --- a/keystore/java/android/security/KeyStoreParameter.java +++ b/keystore/java/android/security/KeyStoreParameter.java @@ -305,7 +305,7 @@ public final class KeyStoreParameter implements ProtectionParameter { * *

      * KeyStoreParameter params = new KeyStoreParameter.Builder(mContext)
-     *         .setEncryptionRequired()
+     *         .setEncryptionRequired(true)
      *         .build();
      * 
*/ @@ -338,12 +338,15 @@ public final class KeyStoreParameter implements ProtectionParameter { } /** - * Indicates that this {@link java.security.KeyStore} entry must be encrypted at rest. This - * will protect the entry with the secure lock screen credential (e.g., password, PIN, or - * pattern). + * Sets whether this {@link java.security.KeyStore} entry must be encrypted at rest. + * Encryption at rest will protect the entry with the secure lock screen credential (e.g., + * password, PIN, or pattern). * *

Note that enabling this feature requires that the secure lock screen (e.g., password, - * PIN, pattern) is set up. Otherwise setting the {@code KeyStore} entry will fail. + * PIN, pattern) is set up, otherwise setting the {@code KeyStore} entry will fail. + * Moreover, this entry will be deleted when the secure lock screen is disabled or reset + * (e.g., by the user or a Device Administrator). Finally, this entry cannot be used until + * the user unlocks the secure lock screen after boot. * * @see KeyguardManager#isDeviceSecure() */