Merge "keystore: add UID to certain APIs"
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
index 240ec1f..64d953f 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -89,7 +89,7 @@
         return 0;
     }
 
-    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength)
+    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
@@ -97,6 +97,7 @@
         data.writeInt32(itemLength);
         void* buf = data.writeInplace(itemLength);
         memcpy(buf, item, itemLength);
+        data.writeInt32(uid);
         status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("import() could not contact remote: %d\n", status);
@@ -111,11 +112,12 @@
         return ret;
     }
 
-    virtual int32_t del(const String16& name)
+    virtual int32_t del(const String16& name, int uid)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
+        data.writeInt32(uid);
         status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("del() could not contact remote: %d\n", status);
@@ -130,11 +132,12 @@
         return ret;
     }
 
-    virtual int32_t exist(const String16& name)
+    virtual int32_t exist(const String16& name, int uid)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
+        data.writeInt32(uid);
         status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("exist() could not contact remote: %d\n", status);
@@ -149,11 +152,12 @@
         return ret;
     }
 
-    virtual int32_t saw(const String16& name, Vector<String16>* matches)
+    virtual int32_t saw(const String16& name, int uid, Vector<String16>* matches)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
+        data.writeInt32(uid);
         status_t status = remote()->transact(BnKeystoreService::SAW, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("saw() could not contact remote: %d\n", status);
@@ -264,11 +268,12 @@
         return ret;
     }
 
-    virtual int32_t generate(const String16& name)
+    virtual int32_t generate(const String16& name, int uid)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
+        data.writeInt32(uid);
         status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("generate() could not contact remote: %d\n", status);
@@ -283,7 +288,7 @@
         return ret;
     }
 
-    virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength)
+    virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength, int uid)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
@@ -291,6 +296,7 @@
         data.writeInt32(keyLength);
         void* buf = data.writeInplace(keyLength);
         memcpy(buf, key, keyLength);
+        data.writeInt32(uid);
         status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("import() could not contact remote: %d\n", status);
@@ -403,11 +409,12 @@
         return 0;
      }
 
-    virtual int32_t del_key(const String16& name)
+    virtual int32_t del_key(const String16& name, int uid)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
+        data.writeInt32(uid);
         status_t status = remote()->transact(BnKeystoreService::DEL_KEY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("del_key() could not contact remote: %d\n", status);
@@ -525,7 +532,8 @@
                 in = NULL;
                 inSize = 0;
             }
-            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize);
+            int uid = data.readInt32();
+            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize, uid);
             reply->writeNoException();
             reply->writeInt32(ret);
             return NO_ERROR;
@@ -533,7 +541,8 @@
         case DEL: {
             CHECK_INTERFACE(IKeystoreService, data, reply);
             String16 name = data.readString16();
-            int32_t ret = del(name);
+            int uid = data.readInt32();
+            int32_t ret = del(name, uid);
             reply->writeNoException();
             reply->writeInt32(ret);
             return NO_ERROR;
@@ -541,7 +550,8 @@
         case EXIST: {
             CHECK_INTERFACE(IKeystoreService, data, reply);
             String16 name = data.readString16();
-            int32_t ret = exist(name);
+            int uid = data.readInt32();
+            int32_t ret = exist(name, uid);
             reply->writeNoException();
             reply->writeInt32(ret);
             return NO_ERROR;
@@ -549,8 +559,9 @@
         case SAW: {
             CHECK_INTERFACE(IKeystoreService, data, reply);
             String16 name = data.readString16();
+            int uid = data.readInt32();
             Vector<String16> matches;
-            int32_t ret = saw(name, &matches);
+            int32_t ret = saw(name, uid, &matches);
             reply->writeNoException();
             reply->writeInt32(matches.size());
             Vector<String16>::const_iterator it = matches.begin();
@@ -600,7 +611,8 @@
         case GENERATE: {
             CHECK_INTERFACE(IKeystoreService, data, reply);
             String16 name = data.readString16();
-            int32_t ret = generate(name);
+            int uid = data.readInt32();
+            int32_t ret = generate(name, uid);
             reply->writeNoException();
             reply->writeInt32(ret);
             return NO_ERROR;
@@ -616,7 +628,8 @@
                 in = NULL;
                 inSize = 0;
             }
-            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize);
+            int uid = data.readInt32();
+            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize, uid);
             reply->writeNoException();
             reply->writeInt32(ret);
             return NO_ERROR;
@@ -693,7 +706,8 @@
         case DEL_KEY: {
             CHECK_INTERFACE(IKeystoreService, data, reply);
             String16 name = data.readString16();
-            int32_t ret = del_key(name);
+            int uid = data.readInt32();
+            int32_t ret = del_key(name, uid);
             reply->writeNoException();
             reply->writeInt32(ret);
             return NO_ERROR;
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
index 15712ce..b4560b9 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -57,13 +57,13 @@
 
     virtual int32_t get(const String16& name, uint8_t** item, size_t* itemLength) = 0;
 
-    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength) = 0;
+    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid) = 0;
 
-    virtual int32_t del(const String16& name) = 0;
+    virtual int32_t del(const String16& name, int uid) = 0;
 
-    virtual int32_t exist(const String16& name) = 0;
+    virtual int32_t exist(const String16& name, int uid) = 0;
 
-    virtual int32_t saw(const String16& name, Vector<String16>* matches) = 0;
+    virtual int32_t saw(const String16& name, int uid, Vector<String16>* matches) = 0;
 
     virtual int32_t reset() = 0;
 
@@ -75,9 +75,9 @@
 
     virtual int32_t zero() = 0;
 
-    virtual int32_t generate(const String16& name) = 0;
+    virtual int32_t generate(const String16& name, int uid) = 0;
 
-    virtual int32_t import(const String16& name, const uint8_t* data, size_t length) = 0;
+    virtual int32_t import(const String16& name, const uint8_t* data, size_t length, int uid) = 0;
 
     virtual int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
             size_t* outLength) = 0;
@@ -87,7 +87,7 @@
 
     virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) = 0;
 
-    virtual int32_t del_key(const String16& name) = 0;
+    virtual int32_t del_key(const String16& name, int uid) = 0;
 
     virtual int32_t grant(const String16& name, int32_t granteeUid) = 0;
 
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index ef64f33..bd4e564 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -978,7 +978,7 @@
         return ::NO_ERROR;
     }
 
-    int32_t insert(const String16& name, const uint8_t* item, size_t itemLength) {
+    int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
         if (!has_permission(callingUid, P_INSERT)) {
             ALOGW("permission denied for %d: insert", callingUid);
@@ -986,6 +986,10 @@
         }
         callingUid = get_keystore_euid(callingUid);
 
+        if (uid != -1) {
+            return ::PERMISSION_DENIED;
+        }
+
         State state = checkState();
         if (state != STATE_NO_ERROR) {
             ALOGD("calling insert in state: %d", state);
@@ -1001,7 +1005,7 @@
         return mKeyStore->put(filename, &keyBlob);
     }
 
-    int32_t del(const String16& name) {
+    int32_t del(const String16& name, int uid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
         if (!has_permission(callingUid, P_DELETE)) {
             ALOGW("permission denied for %d: del", callingUid);
@@ -1009,6 +1013,10 @@
         }
         callingUid = get_keystore_euid(callingUid);
 
+        if (uid != -1) {
+            return ::PERMISSION_DENIED;
+        }
+
         String8 name8(name);
         char filename[NAME_MAX];
 
@@ -1022,7 +1030,7 @@
         return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
     }
 
-    int32_t exist(const String16& name) {
+    int32_t exist(const String16& name, int uid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
         if (!has_permission(callingUid, P_EXIST)) {
             ALOGW("permission denied for %d: exist", callingUid);
@@ -1030,6 +1038,10 @@
         }
         callingUid = get_keystore_euid(callingUid);
 
+        if (uid != -1) {
+            return ::PERMISSION_DENIED;
+        }
+
         String8 name8(name);
         char filename[NAME_MAX];
 
@@ -1041,7 +1053,7 @@
         return ::NO_ERROR;
     }
 
-    int32_t saw(const String16& prefix, Vector<String16>* matches) {
+    int32_t saw(const String16& prefix, int uid, Vector<String16>* matches) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
         if (!has_permission(callingUid, P_SAW)) {
             ALOGW("permission denied for %d: saw", callingUid);
@@ -1049,6 +1061,10 @@
         }
         callingUid = get_keystore_euid(callingUid);
 
+        if (uid != -1) {
+            return ::PERMISSION_DENIED;
+        }
+
         DIR* dir = opendir(".");
         if (!dir) {
             return ::SYSTEM_ERROR;
@@ -1186,7 +1202,7 @@
         return mKeyStore->isEmpty() ? ::KEY_NOT_FOUND : ::NO_ERROR;
     }
 
-    int32_t generate(const String16& name) {
+    int32_t generate(const String16& name, int uid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
         if (!has_permission(callingUid, P_INSERT)) {
             ALOGW("permission denied for %d: generate", callingUid);
@@ -1194,6 +1210,10 @@
         }
         callingUid = get_keystore_euid(callingUid);
 
+        if (uid != -1) {
+            return ::PERMISSION_DENIED;
+        }
+
         State state = checkState();
         if (state != STATE_NO_ERROR) {
             ALOGD("calling generate in state: %d", state);
@@ -1233,7 +1253,7 @@
         return mKeyStore->put(filename, &keyBlob);
     }
 
-    int32_t import(const String16& name, const uint8_t* data, size_t length) {
+    int32_t import(const String16& name, const uint8_t* data, size_t length, int uid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
         if (!has_permission(callingUid, P_INSERT)) {
             ALOGW("permission denied for %d: import", callingUid);
@@ -1241,6 +1261,10 @@
         }
         callingUid = get_keystore_euid(callingUid);
 
+        if (uid != -1) {
+            return ::PERMISSION_DENIED;
+        }
+
         State state = checkState();
         if (state != STATE_NO_ERROR) {
             ALOGD("calling import in state: %d", state);
@@ -1408,7 +1432,7 @@
         return ::NO_ERROR;
     }
 
-    int32_t del_key(const String16& name) {
+    int32_t del_key(const String16& name, int uid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
         if (!has_permission(callingUid, P_DELETE)) {
             ALOGW("permission denied for %d: del_key", callingUid);
@@ -1416,6 +1440,10 @@
         }
         callingUid = get_keystore_euid(callingUid);
 
+        if (uid != -1) {
+            return ::PERMISSION_DENIED;
+        }
+
         String8 name8(name);
         char filename[NAME_MAX];
 
diff --git a/keystore/keystore_cli.cpp b/keystore/keystore_cli.cpp
index 01da2c0..fc501bf 100644
--- a/keystore/keystore_cli.cpp
+++ b/keystore/keystore_cli.cpp
@@ -76,6 +76,29 @@
         } \
     } while (0)
 
+#define SINGLE_ARG_PLUS_UID_INT_RETURN(cmd) \
+    do { \
+        if (strcmp(argv[1], #cmd) == 0) { \
+            if (argc < 3) { \
+                fprintf(stderr, "Usage: %s " #cmd " <name> <uid>\n", argv[0]); \
+                return 1; \
+            } \
+            int uid = -1; \
+            if (argc > 3) { \
+                uid = atoi(argv[3]); \
+                fprintf(stderr, "Running as uid %d\n", uid); \
+            } \
+            int32_t ret = service->cmd(String16(argv[2]), uid); \
+            if (ret < 0) { \
+                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
+                return 1; \
+            } else { \
+                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
+                return 0; \
+            } \
+        } \
+    } while (0)
+
 #define STING_ARG_DATA_STDIN_INT_RETURN(cmd) \
     do { \
         if (strcmp(argv[1], #cmd) == 0) { \
@@ -122,9 +145,9 @@
         } \
     } while (0)
 
-static int saw(sp<IKeystoreService> service, const String16& name) {
+static int saw(sp<IKeystoreService> service, const String16& name, int uid) {
     Vector<String16> matches;
-    int32_t ret = service->saw(name, &matches);
+    int32_t ret = service->saw(name, uid, &matches);
     if (ret < 0) {
         fprintf(stderr, "saw: could not connect: %d\n", ret);
         return 1;
@@ -166,12 +189,13 @@
 
     // TODO: insert
 
-    SINGLE_ARG_INT_RETURN(del);
+    SINGLE_ARG_PLUS_UID_INT_RETURN(del);
 
-    SINGLE_ARG_INT_RETURN(exist);
+    SINGLE_ARG_PLUS_UID_INT_RETURN(exist);
 
     if (strcmp(argv[1], "saw") == 0) {
-        return saw(service, argc < 3 ? String16("") : String16(argv[2]));
+        return saw(service, argc < 3 ? String16("") : String16(argv[2]),
+                argc < 4 ? -1 : atoi(argv[3]));
     }
 
     NO_ARG_INT_RETURN(reset);
@@ -184,11 +208,11 @@
 
     NO_ARG_INT_RETURN(zero);
 
-    SINGLE_ARG_INT_RETURN(generate);
+    SINGLE_ARG_PLUS_UID_INT_RETURN(generate);
 
     SINGLE_ARG_DATA_RETURN(get_pubkey);
 
-    SINGLE_ARG_INT_RETURN(del_key);
+    SINGLE_ARG_PLUS_UID_INT_RETURN(del_key);
 
     // TODO: grant