Update verify API to return auth token blob

Change-Id: I853e61815458b54fb3b2f29e12a147b3b9aa3788
diff --git a/gatekeeperd/IGateKeeperService.cpp b/gatekeeperd/IGateKeeperService.cpp
index 933b975..b1e4811 100644
--- a/gatekeeperd/IGateKeeperService.cpp
+++ b/gatekeeperd/IGateKeeperService.cpp
@@ -68,6 +68,25 @@
         case VERIFY: {
             CHECK_INTERFACE(IGateKeeperService, data, reply);
             uint32_t uid = data.readInt32();
+            ssize_t currentPasswordHandleSize = data.readInt32();
+            const uint8_t *currentPasswordHandle =
+                    static_cast<const uint8_t *>(data.readInplace(currentPasswordHandleSize));
+            if (!currentPasswordHandle) currentPasswordHandleSize = 0;
+
+            ssize_t currentPasswordSize = data.readInt32();
+            const uint8_t *currentPassword =
+                static_cast<const uint8_t *>(data.readInplace(currentPasswordSize));
+            if (!currentPassword) currentPasswordSize = 0;
+
+            status_t ret = verify(uid, (uint8_t *) currentPasswordHandle,
+                    currentPasswordHandleSize, (uint8_t *) currentPassword, currentPasswordSize);
+            reply->writeNoException();
+            reply->writeInt32(ret == NO_ERROR ? 1 : 0);
+            return NO_ERROR;
+        }
+        case VERIFY_CHALLENGE: {
+            CHECK_INTERFACE(IGateKeeperService, data, reply);
+            uint32_t uid = data.readInt32();
             uint64_t challenge = data.readInt64();
             ssize_t currentPasswordHandleSize = data.readInt32();
             const uint8_t *currentPasswordHandle =
@@ -79,10 +98,21 @@
                 static_cast<const uint8_t *>(data.readInplace(currentPasswordSize));
             if (!currentPassword) currentPasswordSize = 0;
 
-            status_t ret = verify(uid, challenge, (uint8_t *) currentPasswordHandle,
-                    currentPasswordHandleSize, (uint8_t *) currentPassword, currentPasswordSize);
+
+            uint8_t *out = NULL;
+            uint32_t outSize = 0;
+            status_t ret = verifyChallenge(uid, challenge, (uint8_t *) currentPasswordHandle,
+                    currentPasswordHandleSize, (uint8_t *) currentPassword, currentPasswordSize,
+                    &out, &outSize);
             reply->writeNoException();
-            reply->writeInt32(ret == NO_ERROR ? 1 : 0);
+            if (ret == NO_ERROR && outSize > 0 && out != NULL) {
+                reply->writeInt32(outSize);
+                void *buf = reply->writeInplace(outSize);
+                memcpy(buf, out, outSize);
+                free(out);
+            } else {
+                reply->writeInt32(-1);
+            }
             return NO_ERROR;
         }
         default:
diff --git a/gatekeeperd/IGateKeeperService.h b/gatekeeperd/IGateKeeperService.h
index 90d3029..10b1b43 100644
--- a/gatekeeperd/IGateKeeperService.h
+++ b/gatekeeperd/IGateKeeperService.h
@@ -30,6 +30,7 @@
     enum {
         ENROLL = IBinder::FIRST_CALL_TRANSACTION + 0,
         VERIFY = IBinder::FIRST_CALL_TRANSACTION + 1,
+        VERIFY_CHALLENGE = IBinder::FIRST_CALL_TRANSACTION + 2,
     };
 
     // DECLARE_META_INTERFACE - C++ client interface not needed
@@ -51,9 +52,18 @@
      * Verifies a password previously enrolled with the GateKeeper.
      * Returns 0 on success, negative on failure.
      */
-    virtual status_t verify(uint32_t uid, uint64_t challenge,
-            const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
+    virtual status_t verify(uint32_t uid, const uint8_t *enrolled_password_handle,
+            uint32_t enrolled_password_handle_length,
             const uint8_t *provided_password, uint32_t provided_password_length) = 0;
+
+    /**
+     * Verifies a password previously enrolled with the GateKeeper.
+     * Returns 0 on success, negative on failure.
+     */
+    virtual status_t verifyChallenge(uint32_t uid, uint64_t challenge,
+            const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
+            const uint8_t *provided_password, uint32_t provided_password_length,
+            uint8_t **auth_token, uint32_t *auth_token_length) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index 2a435a9..ea7016e 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -71,9 +71,20 @@
         return ret >= 0 ? NO_ERROR : UNKNOWN_ERROR;
     }
 
-    virtual status_t verify(uint32_t uid, uint64_t challenge,
+    virtual status_t verify(uint32_t uid,
             const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
             const uint8_t *provided_password, uint32_t provided_password_length) {
+        uint8_t *auth_token;
+        uint32_t auth_token_length;
+        return verifyChallenge(uid, 0, enrolled_password_handle, enrolled_password_handle_length,
+                provided_password, provided_password_length,
+                &auth_token, &auth_token_length);
+    }
+
+    virtual status_t verifyChallenge(uint32_t uid, uint64_t challenge,
+            const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
+            const uint8_t *provided_password, uint32_t provided_password_length,
+            uint8_t **auth_token, uint32_t *auth_token_length) {
         IPCThreadState* ipc = IPCThreadState::self();
         const int calling_pid = ipc->getCallingPid();
         const int calling_uid = ipc->getCallingUid();
@@ -85,19 +96,17 @@
         if ((enrolled_password_handle_length | provided_password_length) == 0)
             return -EINVAL;
 
-        uint8_t *auth_token;
-        uint32_t auth_token_length;
         int ret = device->verify(device, uid, challenge,
                 enrolled_password_handle, enrolled_password_handle_length,
-                provided_password, provided_password_length, &auth_token, &auth_token_length);
+                provided_password, provided_password_length, auth_token, auth_token_length);
 
-        if (ret >= 0 && auth_token != NULL && auth_token_length > 0) {
+        if (ret >= 0 && *auth_token != NULL && *auth_token_length > 0) {
             // TODO: cache service?
             sp<IServiceManager> sm = defaultServiceManager();
             sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
             sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
             if (service != NULL) {
-                if (service->addAuthToken(auth_token, auth_token_length) != NO_ERROR) {
+                if (service->addAuthToken(*auth_token, *auth_token_length) != NO_ERROR) {
                     ALOGE("Falure sending auth token to KeyStore");
                 }
             } else {