Allow uid to be passed for more operations

This expands get, getmtime, exportKey, getKeyCharacteristcs and begin to
accept a uid to run as. This is only for system to use keys owned by
Wifi and VPN, and not something that can be used to do operations as
another arbitrary application.

Bug: 23978113
Change-Id: I06aa089859edc934a5415e3b184b917d6d171ae2
diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl
index 409542d..7cf1d71 100644
--- a/core/java/android/security/IKeystoreService.aidl
+++ b/core/java/android/security/IKeystoreService.aidl
@@ -31,7 +31,7 @@
  */
 interface IKeystoreService {
     int getState(int userId);
-    byte[] get(String name);
+    byte[] get(String name, int uid);
     int insert(String name, in byte[] item, int uid, int flags);
     int del(String name, int uid);
     int exist(String name, int uid);
@@ -49,7 +49,7 @@
     byte[] get_pubkey(String name);
     int grant(String name, int granteeUid);
     int ungrant(String name, int granteeUid);
-    long getmtime(String name);
+    long getmtime(String name, int uid);
     int duplicate(String srcKey, int srcUid, String destKey, int destUid);
     int is_hardware_backed(String string);
     int clear_uid(long uid);
@@ -59,13 +59,13 @@
     int generateKey(String alias, in KeymasterArguments arguments, in byte[] entropy, int uid,
         int flags, out KeyCharacteristics characteristics);
     int getKeyCharacteristics(String alias, in KeymasterBlob clientId, in KeymasterBlob appId,
-        out KeyCharacteristics characteristics);
+        int uid, out KeyCharacteristics characteristics);
     int importKey(String alias, in KeymasterArguments arguments, int format,
         in byte[] keyData, int uid, int flags, out KeyCharacteristics characteristics);
     ExportResult exportKey(String alias, int format, in KeymasterBlob clientId,
-        in KeymasterBlob appId);
+        in KeymasterBlob appId, int uid);
     OperationResult begin(IBinder appToken, String alias, int purpose, boolean pruneable,
-        in KeymasterArguments params, in byte[] entropy);
+        in KeymasterArguments params, in byte[] entropy, int uid);
     OperationResult update(IBinder token, in KeymasterArguments params, in byte[] input);
     OperationResult finish(IBinder token, in KeymasterArguments params, in byte[] signature,
         in byte[] entropy);
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 98b44dc..a27d9e0 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -155,15 +155,19 @@
         return state() == State.UNLOCKED;
     }
 
-    public byte[] get(String key) {
+    public byte[] get(String key, int uid) {
         try {
-            return mBinder.get(key);
+            return mBinder.get(key, uid);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return null;
         }
     }
 
+    public byte[] get(String key) {
+        return get(key, UID_SELF);
+    }
+
     public boolean put(String key, byte[] value, int uid, int flags) {
         return insert(key, value, uid, flags) == NO_ERROR;
     }
@@ -348,9 +352,9 @@
      * Returns the last modification time of the key in milliseconds since the
      * epoch. Will return -1L if the key could not be found or other error.
      */
-    public long getmtime(String key) {
+    public long getmtime(String key, int uid) {
         try {
-            final long millis = mBinder.getmtime(key);
+            final long millis = mBinder.getmtime(key, uid);
             if (millis == -1L) {
                 return -1L;
             }
@@ -362,6 +366,10 @@
         }
     }
 
+    public long getmtime(String key) {
+        return getmtime(key, UID_SELF);
+    }
+
     public boolean duplicate(String srcKey, int srcUid, String destKey, int destUid) {
         try {
             return mBinder.duplicate(srcKey, srcUid, destKey, destUid) == NO_ERROR;
@@ -423,15 +431,20 @@
     }
 
     public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId,
-            KeyCharacteristics outCharacteristics) {
+            int uid, KeyCharacteristics outCharacteristics) {
         try {
-            return mBinder.getKeyCharacteristics(alias, clientId, appId, outCharacteristics);
+            return mBinder.getKeyCharacteristics(alias, clientId, appId, uid, outCharacteristics);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return SYSTEM_ERROR;
         }
     }
 
+    public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId,
+            KeyCharacteristics outCharacteristics) {
+        return getKeyCharacteristics(alias, clientId, appId, UID_SELF, outCharacteristics);
+    }
+
     public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData,
             int uid, int flags, KeyCharacteristics outCharacteristics) {
         try {
@@ -449,9 +462,23 @@
     }
 
     public ExportResult exportKey(String alias, int format, KeymasterBlob clientId,
-            KeymasterBlob appId) {
+            KeymasterBlob appId, int uid) {
         try {
-            return mBinder.exportKey(alias, format, clientId, appId);
+            return mBinder.exportKey(alias, format, clientId, appId, uid);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Cannot connect to keystore", e);
+            return null;
+        }
+    }
+    public ExportResult exportKey(String alias, int format, KeymasterBlob clientId,
+            KeymasterBlob appId) {
+        return exportKey(alias, format, clientId, appId, UID_SELF);
+    }
+
+    public OperationResult begin(String alias, int purpose, boolean pruneable,
+            KeymasterArguments args, byte[] entropy, int uid) {
+        try {
+            return mBinder.begin(getToken(), alias, purpose, pruneable, args, entropy, uid);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return null;
@@ -460,12 +487,7 @@
 
     public OperationResult begin(String alias, int purpose, boolean pruneable,
             KeymasterArguments args, byte[] entropy) {
-        try {
-            return mBinder.begin(getToken(), alias, purpose, pruneable, args, entropy);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Cannot connect to keystore", e);
-            return null;
-        }
+        return begin(alias, purpose, pruneable, args, entropy, UID_SELF);
     }
 
     public OperationResult update(IBinder token, KeymasterArguments arguments, byte[] input) {