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);
             }
         }
     }