Merge "Adding KEY_PERMANENTLY_INVALIDATED int"
diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java
index c43a666..a88aa8c 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.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
/**
* 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 42e7182..2b2438a 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.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 @@
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 eb169be..1829d2f 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -35,6 +35,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.security.keystore.AndroidKeyStoreProvider;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import com.android.org.conscrypt.TrustedCertificateStore;
@@ -592,7 +593,7 @@
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 213ed7d..bfce17c 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -98,6 +98,9 @@
*/
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 @@
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 d44c894..91aac83 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -526,7 +526,7 @@
+ 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 c7c9ee4..234615d 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -228,10 +228,16 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 4c007cb..105af6e 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -24,6 +24,7 @@
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 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