Make client/app ids objects in the binder API

Previously a null client/app id was translated into a blob with
length=0, data=NULL, but this was a bit janky and required null ids to
be set on key creation/import.

Change-Id: I27607a50f4dc5a898625b569f5293369f0039eba
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
index 3818acf..3a23059 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -361,12 +361,18 @@
     return NULL;
 }
 
-static void readKeymasterBlob(const Parcel& in, keymaster_blob_t* blob) {
+static std::unique_ptr<keymaster_blob_t> readKeymasterBlob(const Parcel& in) {
+    std::unique_ptr<keymaster_blob_t> blob;
+    if (in.readInt32() != 1) {
+        blob.reset(NULL);
+        return blob;
+    }
     ssize_t length = in.readInt32();
+    blob.reset(new keymaster_blob_t);
     if (length > 0) {
-        blob->data = (uint8_t*) in.readInplace(length);
+        blob->data = reinterpret_cast<const uint8_t*>(in.readInplace(length));
         if (blob->data) {
-            blob->data_length = (size_t) length;
+            blob->data_length = static_cast<size_t>(length);
         } else {
             blob->data_length = 0;
         }
@@ -374,6 +380,7 @@
         blob->data = NULL;
         blob->data_length = 0;
     }
+    return blob;
 }
 
 class BpKeystoreService: public BpInterface<IKeystoreService>
@@ -1018,15 +1025,23 @@
         return ret;
     }
     virtual int32_t getKeyCharacteristics(const String16& name,
-                                          const keymaster_blob_t& clientId,
-                                          const keymaster_blob_t& appData,
+                                          const keymaster_blob_t* clientId,
+                                          const keymaster_blob_t* appData,
                                           KeyCharacteristics* outCharacteristics)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeByteArray(clientId.data_length, clientId.data);
-        data.writeByteArray(appData.data_length, appData.data);
+        if (clientId) {
+            data.writeByteArray(clientId->data_length, clientId->data);
+        } else {
+            data.writeInt32(-1);
+        }
+        if (appData) {
+            data.writeByteArray(appData->data_length, appData->data);
+        } else {
+            data.writeInt32(-1);
+        }
         status_t status = remote()->transact(BnKeystoreService::GET_KEY_CHARACTERISTICS,
                                              data, &reply);
         if (status != NO_ERROR) {
@@ -1076,8 +1091,8 @@
     }
 
     virtual void exportKey(const String16& name, keymaster_key_format_t format,
-                           const keymaster_blob_t& clientId,
-                           const keymaster_blob_t& appData, ExportResult* result)
+                           const keymaster_blob_t* clientId,
+                           const keymaster_blob_t* appData, ExportResult* result)
     {
         if (!result) {
             return;
@@ -1087,8 +1102,16 @@
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
         data.writeInt32(format);
-        data.writeByteArray(clientId.data_length, clientId.data);
-        data.writeByteArray(appData.data_length, appData.data);
+        if (clientId) {
+            data.writeByteArray(clientId->data_length, clientId->data);
+        } else {
+            data.writeInt32(-1);
+        }
+        if (appData) {
+            data.writeByteArray(appData->data_length, appData->data);
+        } else {
+            data.writeInt32(-1);
+        }
         status_t status = remote()->transact(BnKeystoreService::EXPORT_KEY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("exportKey() could not contact remote: %d\n", status);
@@ -1574,11 +1597,11 @@
         case GET_KEY_CHARACTERISTICS: {
             CHECK_INTERFACE(IKeystoreService, data, reply);
             String16 name = data.readString16();
-            keymaster_blob_t clientId, appData;
-            readKeymasterBlob(data, &clientId);
-            readKeymasterBlob(data, &appData);
+            std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
+            std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
             KeyCharacteristics outCharacteristics;
-            int ret = getKeyCharacteristics(name, clientId, appData, &outCharacteristics);
+            int ret = getKeyCharacteristics(name, clientId.get(), appData.get(),
+                                            &outCharacteristics);
             reply->writeNoException();
             reply->writeInt32(ret);
             reply->writeInt32(1);
@@ -1612,11 +1635,10 @@
             CHECK_INTERFACE(IKeystoreService, data, reply);
             String16 name = data.readString16();
             keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
-            keymaster_blob_t clientId, appData;
-            readKeymasterBlob(data, &clientId);
-            readKeymasterBlob(data, &appData);
+            std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
+            std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
             ExportResult result;
-            exportKey(name, format, clientId, appData, &result);
+            exportKey(name, format, clientId.get(), appData.get(), &result);
             reply->writeNoException();
             reply->writeInt32(1);
             result.writeToParcel(reply);
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
index f671077..f7f1295 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -199,8 +199,8 @@
     virtual int32_t generateKey(const String16& name, const KeymasterArguments& params,
                                 int uid, int flags, KeyCharacteristics* outCharacteristics) = 0;
     virtual int32_t getKeyCharacteristics(const String16& name,
-                                          const keymaster_blob_t& clientId,
-                                          const keymaster_blob_t& appData,
+                                          const keymaster_blob_t* clientId,
+                                          const keymaster_blob_t* appData,
                                           KeyCharacteristics* outCharacteristics) = 0;
     virtual int32_t importKey(const String16& name, const KeymasterArguments&  params,
                               keymaster_key_format_t format, const uint8_t *keyData,
@@ -208,8 +208,8 @@
                               KeyCharacteristics* outCharacteristics) = 0;
 
     virtual void exportKey(const String16& name, keymaster_key_format_t format,
-                           const keymaster_blob_t& clientId,
-                           const keymaster_blob_t& appData, ExportResult* result) = 0;
+                           const keymaster_blob_t* clientId,
+                           const keymaster_blob_t* appData, ExportResult* result) = 0;
 
     virtual void begin(const sp<IBinder>& apptoken, const String16& name,
                        keymaster_purpose_t purpose, bool pruneable,
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 46bc174..a949ffb 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -2540,8 +2540,8 @@
     }
 
     int32_t getKeyCharacteristics(const String16& name,
-                                  const keymaster_blob_t& clientId,
-                                  const keymaster_blob_t& appData,
+                                  const keymaster_blob_t* clientId,
+                                  const keymaster_blob_t* appData,
                                   KeyCharacteristics* outCharacteristics) {
 
         if (!outCharacteristics) {
@@ -2568,7 +2568,7 @@
             ALOGW("device does not implement get_key_characteristics");
             return KM_ERROR_UNIMPLEMENTED;
         }
-        rc = dev->get_key_characteristics(dev, &key, &clientId, &appData, &out);
+        rc = dev->get_key_characteristics(dev, &key, clientId, appData, &out);
         if (out) {
             outCharacteristics->characteristics = *out;
             free(out);
@@ -2645,8 +2645,8 @@
     }
 
     void exportKey(const String16& name, keymaster_key_format_t format,
-                           const keymaster_blob_t& clientId,
-                           const keymaster_blob_t& appData, ExportResult* result) {
+                           const keymaster_blob_t* clientId,
+                           const keymaster_blob_t* appData, ExportResult* result) {
 
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
 
@@ -2669,7 +2669,7 @@
             return;
         }
         uint8_t* ptr = NULL;
-        rc = dev->export_key(dev, format, &key, &clientId, &appData,
+        rc = dev->export_key(dev, format, &key, clientId, appData,
                                              &ptr, &result->dataLength);
         result->exportData.reset(ptr);
         result->resultCode = rc ? rc : ::NO_ERROR;