Support cross-UID access from AndroidKeyStore.
This is meant for exposing the pre-existing cross-UID access to keys
backed by the keystore service via higher-level JCA API. For example,
this lets system_server use Wi-Fi or VPN UID keys via JCA API.
To obtain a JCA AndroidKeyStore KeyStore for another UID, use the
hidden system API AndroidKeyStoreProvider.getKeyStoreForUid(uid).
To generate a key owned by another UID, invoke setUid(uid) on
KeyGenParameterSpec.Builder.
This CL does not change the security policy, such as which UID can
access/modify which UIDs' keys. The policy is that only certain system
UIDs are permitted to access keys of certain other system UIDs.
Bug: 23978113
Change-Id: Ie381530f41dc41c50d52f675fb9e68bc87c006de
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index 79095f4..65460b5 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -147,6 +147,7 @@
private KeyGenParameterSpec mSpec;
private String mEntryAlias;
+ private int mEntryUid;
private boolean mEncryptionAtRestRequired;
private @KeyProperties.KeyAlgorithmEnum String mJcaKeyAlgorithm;
private int mKeymasterAlgorithm = -1;
@@ -283,6 +284,7 @@
}
mEntryAlias = spec.getKeystoreAlias();
+ mEntryUid = spec.getUid();
mSpec = spec;
mKeymasterAlgorithm = keymasterAlgorithm;
mEncryptionAtRestRequired = encryptionAtRestRequired;
@@ -352,6 +354,7 @@
private void resetAll() {
mEntryAlias = null;
+ mEntryUid = KeyStore.UID_SELF;
mJcaKeyAlgorithm = null;
mKeymasterAlgorithm = -1;
mKeymasterPurposes = null;
@@ -470,12 +473,13 @@
final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + mEntryAlias;
boolean success = false;
try {
- Credentials.deleteAllTypesForAlias(mKeyStore, mEntryAlias);
+ Credentials.deleteAllTypesForAlias(mKeyStore, mEntryAlias, mEntryUid);
KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
int errorCode = mKeyStore.generateKey(
privateKeyAlias,
args,
additionalEntropy,
+ mEntryUid,
flags,
resultingKeyCharacteristics);
if (errorCode != KeyStore.NO_ERROR) {
@@ -486,7 +490,7 @@
KeyPair result;
try {
result = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(
- mKeyStore, privateKeyAlias);
+ mKeyStore, privateKeyAlias, mEntryUid);
} catch (UnrecoverableKeyException e) {
throw new ProviderException("Failed to load generated key pair from keystore", e);
}
@@ -515,7 +519,7 @@
int insertErrorCode = mKeyStore.insert(
Credentials.USER_CERTIFICATE + mEntryAlias,
certBytes,
- KeyStore.UID_SELF,
+ mEntryUid,
flags);
if (insertErrorCode != KeyStore.NO_ERROR) {
throw new ProviderException("Failed to store self-signed certificate",
@@ -526,7 +530,7 @@
return result;
} finally {
if (!success) {
- Credentials.deleteAllTypesForAlias(mKeyStore, mEntryAlias);
+ Credentials.deleteAllTypesForAlias(mKeyStore, mEntryAlias, mEntryUid);
}
}
}