summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Bires <jbires@google.com>2018-11-02 10:50:40 -0700
committerMax Bires <jbires@google.com>2019-02-18 20:45:46 +0000
commit13f98ce5aa3f733e5e2c14b0c32020299a08a973 (patch)
tree495eb20c3891711ccbc5e1fb3f001b17ea089881
parent6f82297cb1c3fbb740ae91d2d5e59603f67b1e84 (diff)
Adding KEY_PERMANENTLY_INVALIDATED int
This is to keep it in sync with response codes in keystore.h. This commit also adds the KeyPermanentlyInvalidatedException to all the methods that could receive this error code out of KeyStore. Bug: 118883532 Test: atest cts/hostsidetests/appsecurity/src/android/appsecurity/cts/AuthBoundKeyTest.java Change-Id: I878a628824e2eeb639ec5678b1a5d3d10428a918
-rw-r--r--core/java/android/security/keystore/recovery/RecoveryController.java14
-rw-r--r--core/java/android/security/keystore/recovery/RecoverySession.java3
-rw-r--r--keystore/java/android/security/KeyChain.java3
-rw-r--r--keystore/java/android/security/KeyStore.java5
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java2
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreProvider.java16
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreSpi.java12
7 files changed, 40 insertions, 15 deletions
diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java
index c43a6668b9c3..a88aa8cb4401 100644
--- a/core/java/android/security/keystore/recovery/RecoveryController.java
+++ b/core/java/android/security/keystore/recovery/RecoveryController.java
@@ -28,6 +28,7 @@ import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.security.KeyStore;
import android.security.keystore.AndroidKeyStoreProvider;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
import com.android.internal.widget.ILockSettings;
@@ -548,7 +549,7 @@ public class RecoveryController {
return getKeyFromGrant(grantAlias);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
- } catch (UnrecoverableKeyException e) {
+ } catch (KeyPermanentlyInvalidatedException | UnrecoverableKeyException e) {
throw new InternalRecoveryServiceException("Failed to get key from keystore", e);
} catch (ServiceSpecificException e) {
if (e.errorCode == ERROR_INSECURE_USER) {
@@ -589,7 +590,7 @@ public class RecoveryController {
return getKeyFromGrant(grantAlias);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
- } catch (UnrecoverableKeyException e) {
+ } catch (KeyPermanentlyInvalidatedException | UnrecoverableKeyException e) {
throw new InternalRecoveryServiceException("Failed to get key from keystore", e);
} catch (ServiceSpecificException e) {
if (e.errorCode == ERROR_INSECURE_USER) {
@@ -622,7 +623,7 @@ public class RecoveryController {
return getKeyFromGrant(grantAlias);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
- } catch (UnrecoverableKeyException e) {
+ } catch (KeyPermanentlyInvalidatedException | UnrecoverableKeyException e) {
throw new InternalRecoveryServiceException("Failed to get key from keystore", e);
} catch (ServiceSpecificException e) {
if (e.errorCode == ERROR_INSECURE_USER) {
@@ -665,7 +666,7 @@ public class RecoveryController {
return getKeyFromGrant(grantAlias);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
- } catch (UnrecoverableKeyException e) {
+ } catch (KeyPermanentlyInvalidatedException | UnrecoverableKeyException e) {
throw new InternalRecoveryServiceException("Failed to get key from keystore", e);
} catch (ServiceSpecificException e) {
if (e.errorCode == ERROR_INSECURE_USER) {
@@ -695,6 +696,8 @@ public class RecoveryController {
return getKeyFromGrant(grantAlias);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
+ } catch (KeyPermanentlyInvalidatedException | UnrecoverableKeyException e) {
+ throw new UnrecoverableKeyException(e.getMessage());
} catch (ServiceSpecificException e) {
throw wrapUnexpectedServiceSpecificException(e);
}
@@ -703,7 +706,8 @@ public class RecoveryController {
/**
* Returns the key with the given {@code grantAlias}.
*/
- @NonNull Key getKeyFromGrant(@NonNull String grantAlias) throws UnrecoverableKeyException {
+ @NonNull Key getKeyFromGrant(@NonNull String grantAlias)
+ throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
mKeyStore,
grantAlias,
diff --git a/core/java/android/security/keystore/recovery/RecoverySession.java b/core/java/android/security/keystore/recovery/RecoverySession.java
index 42e718268d2d..2b2438ad2e11 100644
--- a/core/java/android/security/keystore/recovery/RecoverySession.java
+++ b/core/java/android/security/keystore/recovery/RecoverySession.java
@@ -22,6 +22,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.util.ArrayMap;
import android.util.Log;
@@ -174,7 +175,7 @@ public class RecoverySession implements AutoCloseable {
Key key;
try {
key = mRecoveryController.getKeyFromGrant(grantAlias);
- } catch (UnrecoverableKeyException e) {
+ } catch (KeyPermanentlyInvalidatedException | UnrecoverableKeyException e) {
throw new InternalRecoveryServiceException(
String.format(
Locale.US,
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 5d5e40fd3ac3..c180197d6f84 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -36,6 +36,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.security.keystore.AndroidKeyStoreProvider;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import java.io.ByteArrayInputStream;
@@ -584,7 +585,7 @@ public final class KeyChain {
try {
return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(
KeyStore.getInstance(), keyId, KeyStore.UID_SELF);
- } catch (RuntimeException | UnrecoverableKeyException e) {
+ } catch (RuntimeException | UnrecoverableKeyException | KeyPermanentlyInvalidatedException e) {
throw new KeyChainException(e);
}
}
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 213ed7d1ff0a..bfce17c3e6ab 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -98,6 +98,9 @@ public class KeyStore {
*/
public static final int OP_AUTH_NEEDED = 15;
+ // Used when a user changes their pin, invalidating old auth bound keys.
+ public static final int KEY_PERMANENTLY_INVALIDATED = 17;
+
// Used for UID field to indicate the calling UID.
public static final int UID_SELF = -1;
@@ -1200,6 +1203,8 @@ public class KeyStore {
return new KeyStoreException(errorCode, "Key blob corrupted");
case OP_AUTH_NEEDED:
return new KeyStoreException(errorCode, "Operation requires authorization");
+ case KEY_PERMANENTLY_INVALIDATED:
+ return new KeyStoreException(errorCode, "Key permanently invalidated");
default:
return new KeyStoreException(errorCode, String.valueOf(errorCode));
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index d44c894fa573..91aac8367976 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -526,7 +526,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
+ result.getPrivate().getAlgorithm() + " vs " + mJcaKeyAlgorithm);
}
return result;
- } catch (UnrecoverableKeyException e) {
+ } catch (UnrecoverableKeyException | KeyPermanentlyInvalidatedException e) {
throw new ProviderException("Failed to load generated key pair from keystore", e);
}
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index c7c9ee4a406a..234615d9c81d 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -228,10 +228,16 @@ public class AndroidKeyStoreProvider extends Provider {
@NonNull
private static KeyCharacteristics getKeyCharacteristics(@NonNull KeyStore keyStore,
@NonNull String alias, int uid)
- throws UnrecoverableKeyException {
+ throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
int errorCode = keyStore.getKeyCharacteristics(
alias, null, null, uid, keyCharacteristics);
+ if (errorCode == KeyStore.KEY_PERMANENTLY_INVALIDATED) {
+ throw (KeyPermanentlyInvalidatedException)
+ new KeyPermanentlyInvalidatedException(
+ "User changed or deleted their auth credentials",
+ KeyStore.getKeyStoreException(errorCode));
+ }
if (errorCode != KeyStore.NO_ERROR) {
throw (UnrecoverableKeyException)
new UnrecoverableKeyException("Failed to obtain information about key")
@@ -276,7 +282,7 @@ public class AndroidKeyStoreProvider extends Provider {
@NonNull
public static AndroidKeyStorePublicKey loadAndroidKeyStorePublicKeyFromKeystore(
@NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid)
- throws UnrecoverableKeyException {
+ throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
return loadAndroidKeyStorePublicKeyFromKeystore(keyStore, privateKeyAlias, uid,
getKeyCharacteristics(keyStore, privateKeyAlias, uid));
}
@@ -297,7 +303,7 @@ public class AndroidKeyStoreProvider extends Provider {
@NonNull
public static KeyPair loadAndroidKeyStoreKeyPairFromKeystore(
@NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid)
- throws UnrecoverableKeyException {
+ throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
return loadAndroidKeyStoreKeyPairFromKeystore(keyStore, privateKeyAlias, uid,
getKeyCharacteristics(keyStore, privateKeyAlias, uid));
}
@@ -315,7 +321,7 @@ public class AndroidKeyStoreProvider extends Provider {
@NonNull
public static AndroidKeyStorePrivateKey loadAndroidKeyStorePrivateKeyFromKeystore(
@NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid)
- throws UnrecoverableKeyException {
+ throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
return loadAndroidKeyStorePrivateKeyFromKeystore(keyStore, privateKeyAlias, uid,
getKeyCharacteristics(keyStore, privateKeyAlias, uid));
}
@@ -354,7 +360,7 @@ public class AndroidKeyStoreProvider extends Provider {
@NonNull
public static AndroidKeyStoreKey loadAndroidKeyStoreKeyFromKeystore(
@NonNull KeyStore keyStore, @NonNull String userKeyAlias, int uid)
- throws UnrecoverableKeyException {
+ throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
KeyCharacteristics keyCharacteristics = getKeyCharacteristics(keyStore, userKeyAlias, uid);
Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM);
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index 4c007cb70ba2..105af6e829f8 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -24,6 +24,7 @@ import android.security.KeyStoreParameter;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
import android.security.keystore.SecureKeyImportUnavailableException;
@@ -93,13 +94,20 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException,
UnrecoverableKeyException {
String userKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
+ AndroidKeyStoreKey key;
if (!mKeyStore.contains(userKeyAlias, mUid)) {
// try legacy prefix for backward compatibility
userKeyAlias = Credentials.USER_SECRET_KEY + alias;
if (!mKeyStore.contains(userKeyAlias, mUid)) return null;
}
- return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(mKeyStore, userKeyAlias,
- mUid);
+ try {
+ key = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(mKeyStore,
+ userKeyAlias,
+ mUid);
+ } catch (KeyPermanentlyInvalidatedException e) {
+ throw new UnrecoverableKeyException(e.getMessage());
+ }
+ return key;
}
@Override