Add challenge to GateKeeper

needed for enrollment of auxiliary authenticators

Change-Id: Id2d567fc2736dc7c1960b337b4d4d0d93219ccfc
diff --git a/gatekeeper.cpp b/gatekeeper.cpp
index e163ae0..046eb3b 100644
--- a/gatekeeper.cpp
+++ b/gatekeeper.cpp
@@ -88,7 +88,7 @@
         // Signature matches
         SizedBuffer auth_token;
         MintAuthToken(&auth_token.buffer, &auth_token.length, timestamp,
-                user_id, authenticator_id);
+                user_id, authenticator_id, request.challenge);
         response->SetVerificationToken(&auth_token);
     } else {
         response->error = ERROR_INVALID;
@@ -140,14 +140,15 @@
 }
 
 void GateKeeper::MintAuthToken(UniquePtr<uint8_t> *auth_token, uint32_t *length,
-        uint32_t timestamp, secure_id_t user_id, secure_id_t authenticator_id) {
+        uint32_t timestamp, secure_id_t user_id, secure_id_t authenticator_id,
+        uint64_t challenge) {
     if (auth_token == NULL) return;
 
     hw_auth_token_t *token = new hw_auth_token_t;
     SizedBuffer serialized_auth_token;
 
     token->version = HW_AUTH_TOKEN_VERSION;
-    token->challenge = 0; //TODO: take challenge, needed for FP enrollment
+    token->challenge = challenge;
     token->user_id = user_id;
     token->authenticator_id = authenticator_id;
     token->authenticator_type = htonl(HW_AUTH_PASSWORD);
diff --git a/gatekeeper_messages.cpp b/gatekeeper_messages.cpp
index e89ba68..b9ff8ea 100644
--- a/gatekeeper_messages.cpp
+++ b/gatekeeper_messages.cpp
@@ -110,9 +110,10 @@
 }
 
 
-VerifyRequest::VerifyRequest(uint32_t user_id, SizedBuffer *enrolled_password_handle,
-        SizedBuffer *provided_password_payload) {
+VerifyRequest::VerifyRequest(uint32_t user_id, uint64_t challenge,
+        SizedBuffer *enrolled_password_handle, SizedBuffer *provided_password_payload) {
     this->user_id = user_id;
+    this->challenge = challenge;
     this->password_handle.buffer.reset(enrolled_password_handle->buffer.release());
     this->password_handle.length = enrolled_password_handle->length;
     this->provided_password.buffer.reset(provided_password_payload->buffer.release());
@@ -136,10 +137,13 @@
 }
 
 uint32_t VerifyRequest::nonErrorSerializedSize() const {
-    return serialized_buffer_size(password_handle) + serialized_buffer_size(provided_password);
+    return sizeof(challenge) + serialized_buffer_size(password_handle)
+            + serialized_buffer_size(provided_password);
 }
 
 void VerifyRequest::nonErrorSerialize(uint8_t *buffer) const {
+    memcpy(buffer, &challenge, sizeof(challenge));
+    buffer += sizeof(challenge);
     append_to_buffer(&buffer, &password_handle);
     append_to_buffer(&buffer, &provided_password);
 }
@@ -156,6 +160,9 @@
         provided_password.buffer.reset();
     }
 
+    memcpy(&challenge, payload, sizeof(challenge));
+    payload += sizeof(challenge);
+
     error = read_from_buffer(&payload, end, &password_handle);
     if (error != ERROR_NONE) return error;
 
diff --git a/include/gatekeeper/gatekeeper.h b/include/gatekeeper/gatekeeper.h
index 10f8791..2ba148a 100644
--- a/include/gatekeeper/gatekeeper.h
+++ b/include/gatekeeper/gatekeeper.h
@@ -133,7 +133,7 @@
      * Also returns the length in length if it is not null.
      */
     void MintAuthToken(UniquePtr<uint8_t> *auth_token, uint32_t *length, uint32_t timestamp,
-            secure_id_t user_id, secure_id_t authenticator_id);
+            secure_id_t user_id, secure_id_t authenticator_id, uint64_t challenge);
 
     /**
      * Verifies that handle matches password HMAC'ed with the password_key
diff --git a/include/gatekeeper/gatekeeper_messages.h b/include/gatekeeper/gatekeeper_messages.h
index a98e1c5..0f89047 100644
--- a/include/gatekeeper/gatekeeper_messages.h
+++ b/include/gatekeeper/gatekeeper_messages.h
@@ -127,6 +127,7 @@
 struct VerifyRequest : public GateKeeperMessage {
     VerifyRequest(
             uint32_t user_id,
+            uint64_t challenge,
             SizedBuffer *enrolled_password_handle,
             SizedBuffer *provided_password_payload);
     VerifyRequest();
@@ -136,6 +137,7 @@
     virtual void nonErrorSerialize(uint8_t *buffer) const;
     virtual gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end);
 
+    uint64_t challenge;
     SizedBuffer password_handle;
     SizedBuffer provided_password;
 };
diff --git a/softgatekeeper/soft_gatekeeper_device.cpp b/softgatekeeper/soft_gatekeeper_device.cpp
index a0fd057..c16b639 100644
--- a/softgatekeeper/soft_gatekeeper_device.cpp
+++ b/softgatekeeper/soft_gatekeeper_device.cpp
@@ -138,9 +138,9 @@
 }
 
 int SoftGateKeeperDevice::Verify(const struct gatekeeper_device *dev, 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) {
+        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) {
 
     if (dev == NULL || enrolled_password_handle == NULL ||
             provided_password == NULL) {
@@ -148,11 +148,12 @@
     }
 
     SizedBuffer password_handle_buffer(enrolled_password_handle_length);
-    memcpy(password_handle_buffer.buffer.get(), enrolled_password_handle, enrolled_password_handle_length);
+    memcpy(password_handle_buffer.buffer.get(), enrolled_password_handle,
+            enrolled_password_handle_length);
     SizedBuffer provided_password_buffer(provided_password_length);
     memcpy(provided_password_buffer.buffer.get(), provided_password, provided_password_length);
 
-    VerifyRequest request(uid, &password_handle_buffer, &provided_password_buffer);
+    VerifyRequest request(uid, challenge, &password_handle_buffer, &provided_password_buffer);
     VerifyResponse response;
 
     convert_device(dev)->impl_->Verify(request, &response);
diff --git a/softgatekeeper/soft_gatekeeper_device.h b/softgatekeeper/soft_gatekeeper_device.h
index e9459bf..0b8a8aa 100644
--- a/softgatekeeper/soft_gatekeeper_device.h
+++ b/softgatekeeper/soft_gatekeeper_device.h
@@ -68,7 +68,7 @@
      * Returns: 0 on success or an error code less than 0 on error
      * On error, verification token will not be allocated
      */
-    static int Verify(const struct gatekeeper_device *dev, uint32_t uid,
+    static int Verify(const struct gatekeeper_device *dev, 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);
diff --git a/tests/gatekeeper_device_test.cpp b/tests/gatekeeper_device_test.cpp
index 1d7e74b..9f0d718 100644
--- a/tests/gatekeeper_device_test.cpp
+++ b/tests/gatekeeper_device_test.cpp
@@ -63,7 +63,7 @@
 
     ASSERT_EQ(0, ret);
 
-    ret = device->verify(device, 0, password_handle, password_handle_length,
+    ret = device->verify(device, 0, 0, password_handle, password_handle_length,
             password_payload, password_len, &auth_token, &auth_token_len);
 
     ASSERT_EQ(0, ret);
@@ -85,7 +85,7 @@
 
     password_payload[0] = 4;
 
-    ret = device->verify(device, 0, password_handle, password_handle_length,
+    ret = device->verify(device, 0, 0, password_handle, password_handle_length,
             password_payload, password_len, &auth_token, &auth_token_len);
 
     ASSERT_NE(0, ret);
@@ -139,5 +139,3 @@
     ASSERT_EQ(sid, handle->user_id);
 }
 
-
-
diff --git a/tests/gatekeeper_messages_test.cpp b/tests/gatekeeper_messages_test.cpp
index 1a18e82..706bdb5 100644
--- a/tests/gatekeeper_messages_test.cpp
+++ b/tests/gatekeeper_messages_test.cpp
@@ -167,7 +167,7 @@
           *password_handle = make_buffer(password_size);
     const SizedBuffer *deserialized_password;
     // create request, serialize, deserialize, and validate
-    VerifyRequest msg(USER_ID, password_handle, provided_password);
+    VerifyRequest msg(USER_ID, 1, password_handle, provided_password);
     SizedBuffer serialized_msg(msg.GetSerializedSize());
     msg.Serialize(serialized_msg.buffer.get(), serialized_msg.buffer.get() + serialized_msg.length);
 
@@ -179,6 +179,7 @@
             deserialized_msg.error);
 
     ASSERT_EQ(USER_ID, deserialized_msg.user_id);
+    ASSERT_EQ((uint64_t) 1, deserialized_msg.challenge);
     deserialized_password = &deserialized_msg.password_handle;
     ASSERT_EQ((uint32_t) password_size, deserialized_password->length);
     ASSERT_EQ(0, memcmp(msg.provided_password.buffer.get(), deserialized_password->buffer.get(),
diff --git a/tests/gatekeeper_test.cpp b/tests/gatekeeper_test.cpp
index 66de7de..c5e7087 100644
--- a/tests/gatekeeper_test.cpp
+++ b/tests/gatekeeper_test.cpp
@@ -71,7 +71,7 @@
 
     do_enroll(gatekeeper, &enroll_response);
     ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
-    VerifyRequest request(0, &enroll_response.enrolled_password_handle,
+    VerifyRequest request(0, 1, &enroll_response.enrolled_password_handle,
             &provided_password);
     VerifyResponse response;
 
@@ -83,6 +83,7 @@
         reinterpret_cast<hw_auth_token_t *>(response.auth_token.buffer.get());
 
     ASSERT_EQ((uint32_t) HW_AUTH_PASSWORD, auth_token->authenticator_type);
+    ASSERT_EQ((uint64_t) 1, auth_token->challenge);
     ASSERT_NE(~((uint32_t) 0), auth_token->timestamp);
     ASSERT_NE((uint64_t) 0, auth_token->user_id);
     ASSERT_NE((uint64_t) 0, auth_token->authenticator_id);
@@ -108,7 +109,7 @@
             password_handle.length);
 
     // verify first password
-    VerifyRequest request(0, &enroll_response.enrolled_password_handle,
+    VerifyRequest request(0, 0, &enroll_response.enrolled_password_handle,
             &provided_password);
     VerifyResponse response;
     gatekeeper.Verify(request, &response);
@@ -134,7 +135,7 @@
     password.buffer.reset(new uint8_t[16]);
     memset(password.buffer.get(), 1, 16);
     password.length = 16;
-    VerifyRequest new_request(0, &enroll_response.enrolled_password_handle,
+    VerifyRequest new_request(0, 0, &enroll_response.enrolled_password_handle,
             &password);
     gatekeeper.Verify(new_request, &response);
     ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
@@ -156,7 +157,7 @@
     ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
 
     // verify first password
-    VerifyRequest request(0, &enroll_response.enrolled_password_handle,
+    VerifyRequest request(0, 0, &enroll_response.enrolled_password_handle,
             &provided_password);
     VerifyResponse response;
     gatekeeper.Verify(request, &response);
@@ -179,7 +180,7 @@
     password.buffer.reset(new uint8_t[16]);
     memset(password.buffer.get(), 1, 16);
     password.length = 16;
-    VerifyRequest new_request(0, &enroll_response.enrolled_password_handle,
+    VerifyRequest new_request(0, 0, &enroll_response.enrolled_password_handle,
             &password);
     gatekeeper.Verify(new_request, &response);
     ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
@@ -194,7 +195,7 @@
     SizedBuffer password_handle;
     VerifyResponse response;
 
-    VerifyRequest request(0, &provided_password, &password_handle);
+    VerifyRequest request(0, 0, &provided_password, &password_handle);
 
     gatekeeper.Verify(request, &response);