Merge "Adding KEY_PERMANENTLY_INVALIDATED int"

am: 18e0781d3d

Change-Id: I9a31a0b3c9abc72a619c06c2ffc092d5ef557213
This commit is contained in:
Max Bires
2019-03-08 10:22:53 -08:00
committed by android-build-merger
7 changed files with 38 additions and 13 deletions

View File

@@ -29,6 +29,7 @@ import android.os.ServiceManager;
import android.os.ServiceSpecificException; import android.os.ServiceSpecificException;
import android.security.KeyStore; import android.security.KeyStore;
import android.security.keystore.AndroidKeyStoreProvider; import android.security.keystore.AndroidKeyStoreProvider;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import com.android.internal.widget.ILockSettings; import com.android.internal.widget.ILockSettings;
@@ -635,7 +636,7 @@ public class RecoveryController {
return getKeyFromGrant(grantAlias); return getKeyFromGrant(grantAlias);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} catch (UnrecoverableKeyException e) { } catch (KeyPermanentlyInvalidatedException | UnrecoverableKeyException e) {
throw new InternalRecoveryServiceException("Failed to get key from keystore", e); throw new InternalRecoveryServiceException("Failed to get key from keystore", e);
} catch (ServiceSpecificException e) { } catch (ServiceSpecificException e) {
if (e.errorCode == ERROR_INSECURE_USER) { if (e.errorCode == ERROR_INSECURE_USER) {
@@ -666,7 +667,7 @@ public class RecoveryController {
return getKeyFromGrant(grantAlias); return getKeyFromGrant(grantAlias);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} catch (UnrecoverableKeyException e) { } catch (KeyPermanentlyInvalidatedException | UnrecoverableKeyException e) {
throw new InternalRecoveryServiceException("Failed to get key from keystore", e); throw new InternalRecoveryServiceException("Failed to get key from keystore", e);
} catch (ServiceSpecificException e) { } catch (ServiceSpecificException e) {
if (e.errorCode == ERROR_INSECURE_USER) { if (e.errorCode == ERROR_INSECURE_USER) {
@@ -696,6 +697,8 @@ public class RecoveryController {
return getKeyFromGrant(grantAlias); return getKeyFromGrant(grantAlias);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} catch (KeyPermanentlyInvalidatedException | UnrecoverableKeyException e) {
throw new UnrecoverableKeyException("Failed to get key from keystore");
} catch (ServiceSpecificException e) { } catch (ServiceSpecificException e) {
throw wrapUnexpectedServiceSpecificException(e); throw wrapUnexpectedServiceSpecificException(e);
} }
@@ -704,7 +707,8 @@ public class RecoveryController {
/** /**
* Returns the key with the given {@code grantAlias}. * 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( return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
mKeyStore, mKeyStore,
grantAlias, grantAlias,

View File

@@ -22,6 +22,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi; import android.annotation.SystemApi;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceSpecificException; import android.os.ServiceSpecificException;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.Log; import android.util.Log;
@@ -218,7 +219,7 @@ public class RecoverySession implements AutoCloseable {
Key key; Key key;
try { try {
key = mRecoveryController.getKeyFromGrant(grantAlias); key = mRecoveryController.getKeyFromGrant(grantAlias);
} catch (UnrecoverableKeyException e) { } catch (KeyPermanentlyInvalidatedException | UnrecoverableKeyException e) {
throw new InternalRecoveryServiceException( throw new InternalRecoveryServiceException(
String.format( String.format(
Locale.US, Locale.US,

View File

@@ -36,6 +36,7 @@ import android.os.Process;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.security.keystore.AndroidKeyStoreProvider; import android.security.keystore.AndroidKeyStoreProvider;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties; import android.security.keystore.KeyProperties;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@@ -538,7 +539,7 @@ public final class KeyChain {
try { try {
return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore( return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(
KeyStore.getInstance(), keyId, KeyStore.UID_SELF); KeyStore.getInstance(), keyId, KeyStore.UID_SELF);
} catch (RuntimeException | UnrecoverableKeyException e) { } catch (RuntimeException | UnrecoverableKeyException | KeyPermanentlyInvalidatedException e) {
throw new KeyChainException(e); throw new KeyChainException(e);
} }
} }

View File

@@ -97,6 +97,9 @@ public class KeyStore {
*/ */
public static final int OP_AUTH_NEEDED = 15; 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. // Used for UID field to indicate the calling UID.
public static final int UID_SELF = -1; public static final int UID_SELF = -1;
@@ -1188,6 +1191,8 @@ public class KeyStore {
return new KeyStoreException(errorCode, "Key blob corrupted"); return new KeyStoreException(errorCode, "Key blob corrupted");
case OP_AUTH_NEEDED: case OP_AUTH_NEEDED:
return new KeyStoreException(errorCode, "Operation requires authorization"); return new KeyStoreException(errorCode, "Operation requires authorization");
case KEY_PERMANENTLY_INVALIDATED:
return new KeyStoreException(errorCode, "Key permanently invalidated");
default: default:
return new KeyStoreException(errorCode, String.valueOf(errorCode)); return new KeyStoreException(errorCode, String.valueOf(errorCode));
} }

View File

@@ -526,7 +526,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
+ result.getPrivate().getAlgorithm() + " vs " + mJcaKeyAlgorithm); + result.getPrivate().getAlgorithm() + " vs " + mJcaKeyAlgorithm);
} }
return result; return result;
} catch (UnrecoverableKeyException e) { } catch (UnrecoverableKeyException | KeyPermanentlyInvalidatedException e) {
throw new ProviderException("Failed to load generated key pair from keystore", e); throw new ProviderException("Failed to load generated key pair from keystore", e);
} }
} }

View File

@@ -228,10 +228,16 @@ public class AndroidKeyStoreProvider extends Provider {
@NonNull @NonNull
private static KeyCharacteristics getKeyCharacteristics(@NonNull KeyStore keyStore, private static KeyCharacteristics getKeyCharacteristics(@NonNull KeyStore keyStore,
@NonNull String alias, int uid) @NonNull String alias, int uid)
throws UnrecoverableKeyException { throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
KeyCharacteristics keyCharacteristics = new KeyCharacteristics(); KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
int errorCode = keyStore.getKeyCharacteristics( int errorCode = keyStore.getKeyCharacteristics(
alias, null, null, uid, keyCharacteristics); 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) { if (errorCode != KeyStore.NO_ERROR) {
throw (UnrecoverableKeyException) throw (UnrecoverableKeyException)
new UnrecoverableKeyException("Failed to obtain information about key") new UnrecoverableKeyException("Failed to obtain information about key")
@@ -276,7 +282,7 @@ public class AndroidKeyStoreProvider extends Provider {
@NonNull @NonNull
public static AndroidKeyStorePublicKey loadAndroidKeyStorePublicKeyFromKeystore( public static AndroidKeyStorePublicKey loadAndroidKeyStorePublicKeyFromKeystore(
@NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid) @NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid)
throws UnrecoverableKeyException { throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
return loadAndroidKeyStorePublicKeyFromKeystore(keyStore, privateKeyAlias, uid, return loadAndroidKeyStorePublicKeyFromKeystore(keyStore, privateKeyAlias, uid,
getKeyCharacteristics(keyStore, privateKeyAlias, uid)); getKeyCharacteristics(keyStore, privateKeyAlias, uid));
} }
@@ -297,7 +303,7 @@ public class AndroidKeyStoreProvider extends Provider {
@NonNull @NonNull
public static KeyPair loadAndroidKeyStoreKeyPairFromKeystore( public static KeyPair loadAndroidKeyStoreKeyPairFromKeystore(
@NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid) @NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid)
throws UnrecoverableKeyException { throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
return loadAndroidKeyStoreKeyPairFromKeystore(keyStore, privateKeyAlias, uid, return loadAndroidKeyStoreKeyPairFromKeystore(keyStore, privateKeyAlias, uid,
getKeyCharacteristics(keyStore, privateKeyAlias, uid)); getKeyCharacteristics(keyStore, privateKeyAlias, uid));
} }
@@ -315,7 +321,7 @@ public class AndroidKeyStoreProvider extends Provider {
@NonNull @NonNull
public static AndroidKeyStorePrivateKey loadAndroidKeyStorePrivateKeyFromKeystore( public static AndroidKeyStorePrivateKey loadAndroidKeyStorePrivateKeyFromKeystore(
@NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid) @NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid)
throws UnrecoverableKeyException { throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
return loadAndroidKeyStorePrivateKeyFromKeystore(keyStore, privateKeyAlias, uid, return loadAndroidKeyStorePrivateKeyFromKeystore(keyStore, privateKeyAlias, uid,
getKeyCharacteristics(keyStore, privateKeyAlias, uid)); getKeyCharacteristics(keyStore, privateKeyAlias, uid));
} }
@@ -354,7 +360,7 @@ public class AndroidKeyStoreProvider extends Provider {
@NonNull @NonNull
public static AndroidKeyStoreKey loadAndroidKeyStoreKeyFromKeystore( public static AndroidKeyStoreKey loadAndroidKeyStoreKeyFromKeystore(
@NonNull KeyStore keyStore, @NonNull String userKeyAlias, int uid) @NonNull KeyStore keyStore, @NonNull String userKeyAlias, int uid)
throws UnrecoverableKeyException { throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
KeyCharacteristics keyCharacteristics = getKeyCharacteristics(keyStore, userKeyAlias, uid); KeyCharacteristics keyCharacteristics = getKeyCharacteristics(keyStore, userKeyAlias, uid);
Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM); Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM);

View File

@@ -24,6 +24,7 @@ import android.security.KeyStoreParameter;
import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs; import android.security.keymaster.KeymasterDefs;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties; import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection; import android.security.keystore.KeyProtection;
import android.security.keystore.SecureKeyImportUnavailableException; import android.security.keystore.SecureKeyImportUnavailableException;
@@ -93,13 +94,20 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException,
UnrecoverableKeyException { UnrecoverableKeyException {
String userKeyAlias = Credentials.USER_PRIVATE_KEY + alias; String userKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
AndroidKeyStoreKey key;
if (!mKeyStore.contains(userKeyAlias, mUid)) { if (!mKeyStore.contains(userKeyAlias, mUid)) {
// try legacy prefix for backward compatibility // try legacy prefix for backward compatibility
userKeyAlias = Credentials.USER_SECRET_KEY + alias; userKeyAlias = Credentials.USER_SECRET_KEY + alias;
if (!mKeyStore.contains(userKeyAlias, mUid)) return null; if (!mKeyStore.contains(userKeyAlias, mUid)) return null;
} }
return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(mKeyStore, userKeyAlias, try {
key = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(mKeyStore,
userKeyAlias,
mUid); mUid);
} catch (KeyPermanentlyInvalidatedException e) {
throw new UnrecoverableKeyException(e.getMessage());
}
return key;
} }
@Override @Override