/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "gatekeeper_hidl_hal_test"

#include <algorithm>
#include <cmath>
#include <string>
#include <vector>

#include <inttypes.h>
#include <unistd.h>

#include <hardware/hw_auth_token.h>

#include <android/log.h>
#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
#include <android/hardware/gatekeeper/1.0/types.h>

#include <log/log.h>

#include <VtsHalHidlTargetTestBase.h>
#include <VtsHalHidlTargetTestEnvBase.h>

using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::gatekeeper::V1_0::IGatekeeper;
using ::android::hardware::gatekeeper::V1_0::GatekeeperResponse;
using ::android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;

struct GatekeeperRequest {
  uint32_t uid;
  uint64_t challenge;
  hidl_vec<uint8_t> curPwdHandle;
  hidl_vec<uint8_t> curPwd;
  hidl_vec<uint8_t> newPwd;
  GatekeeperRequest() : uid(0), challenge(0) {}
};

// ASSERT_* macros generate return "void" internally
// we have to use EXPECT_* if we return anything but "void"
static const hw_auth_token_t *toAuthToken(GatekeeperResponse &rsp) {
  const hw_auth_token_t *auth_token =
      reinterpret_cast<hw_auth_token_t *>(rsp.data.data());
  const size_t auth_token_size = rsp.data.size();

  EXPECT_NE(nullptr, auth_token);
  EXPECT_EQ(sizeof(hw_auth_token_t), auth_token_size);

  if (auth_token != nullptr && auth_token_size >= sizeof(*auth_token)) {
    // these are in network order: translate to host
    uint32_t auth_type = ntohl(auth_token->authenticator_type);
    uint64_t auth_tstamp = ntohq(auth_token->timestamp);

    EXPECT_EQ(HW_AUTH_PASSWORD, auth_type);
    EXPECT_NE(UINT64_C(~0), auth_tstamp);
    EXPECT_EQ(HW_AUTH_TOKEN_VERSION, auth_token->version);
    //        EXPECT_NE(UINT64_C(0), auth_token->authenticator_id);
    ALOGI("Authenticator ID: %016" PRIX64, auth_token->authenticator_id);
    EXPECT_NE(UINT32_C(0), auth_token->user_id);
  }
  return auth_token;
}

// Test environment for Gatekeeper HIDL HAL.
class GatekeeperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
 public:
  // get the test environment singleton
  static GatekeeperHidlEnvironment* Instance() {
    static GatekeeperHidlEnvironment* instance = new GatekeeperHidlEnvironment;
    return instance;
  }

  virtual void registerTestServices() override { registerTestService<IGatekeeper>(); }
 private:
  GatekeeperHidlEnvironment() {}
};

// The main test class for Gatekeeper HIDL HAL.
class GatekeeperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
 protected:
  void setUid(uint32_t uid) { uid_ = uid; }

  void doEnroll(GatekeeperRequest &req, GatekeeperResponse &rsp) {
    while (true) {
      auto ret = gatekeeper_->enroll(
          uid_, req.curPwdHandle, req.curPwd, req.newPwd,
          [&rsp](const GatekeeperResponse &cbRsp) { rsp = cbRsp; });
      ASSERT_TRUE(ret.isOk());
      if (rsp.code != GatekeeperStatusCode::ERROR_RETRY_TIMEOUT) break;
      ALOGI("%s: got retry code; retrying in 1 sec", __func__);
      sleep(1);
    }
  }

  void doVerify(GatekeeperRequest &req, GatekeeperResponse &rsp) {
    while (true) {
      auto ret = gatekeeper_->verify(
          uid_, req.challenge, req.curPwdHandle, req.newPwd,
          [&rsp](const GatekeeperResponse &cb_rsp) { rsp = cb_rsp; });
      ASSERT_TRUE(ret.isOk());
      if (rsp.code != GatekeeperStatusCode::ERROR_RETRY_TIMEOUT) break;
      ALOGI("%s: got retry code; retrying in 1 sec", __func__);
      sleep(1);
    }
  }

  void doDeleteUser(GatekeeperResponse &rsp) {
    while (true) {
      auto ret = gatekeeper_->deleteUser(
          uid_, [&rsp](const GatekeeperResponse &cb_rsp) { rsp = cb_rsp; });
      ASSERT_TRUE(ret.isOk());
      if (rsp.code != GatekeeperStatusCode::ERROR_RETRY_TIMEOUT) break;
      ALOGI("%s: got retry code; retrying in 1 sec", __func__);
      sleep(1);
    }
  }

  void doDeleteAllUsers(GatekeeperResponse &rsp) {
    while (true) {
      auto ret = gatekeeper_->deleteAllUsers(
          [&rsp](const GatekeeperResponse &cb_rsp) { rsp = cb_rsp; });
      ASSERT_TRUE(ret.isOk());
      if (rsp.code != GatekeeperStatusCode::ERROR_RETRY_TIMEOUT) break;
      ALOGI("%s: got retry code; retrying in 1 sec", __func__);
      sleep(1);
    }
  }

  void generatePassword(hidl_vec<uint8_t> &password, uint8_t seed) {
    password.resize(16);
    memset(password.data(), seed, password.size());
  }

  void checkEnroll(GatekeeperResponse &rsp, bool expectSuccess) {
    if (expectSuccess) {
      EXPECT_EQ(GatekeeperStatusCode::STATUS_OK, rsp.code);
      EXPECT_NE(nullptr, rsp.data.data());
      EXPECT_GT(rsp.data.size(), UINT32_C(0));
    } else {
      EXPECT_EQ(GatekeeperStatusCode::ERROR_GENERAL_FAILURE, rsp.code);
      EXPECT_EQ(UINT32_C(0), rsp.data.size());
    }
  }

  void checkVerify(GatekeeperResponse &rsp, uint64_t challenge,
                   bool expectSuccess) {
    if (expectSuccess) {
      EXPECT_GE(rsp.code, GatekeeperStatusCode::STATUS_OK);
      EXPECT_LE(rsp.code, GatekeeperStatusCode::STATUS_REENROLL);

      const hw_auth_token_t *auth_token = toAuthToken(rsp);
      ASSERT_NE(nullptr, auth_token);
      EXPECT_EQ(challenge, auth_token->challenge);
    } else {
      EXPECT_EQ(GatekeeperStatusCode::ERROR_GENERAL_FAILURE, rsp.code);
      EXPECT_EQ(UINT32_C(0), rsp.data.size());
    }
  }

  void enrollNewPassword(hidl_vec<uint8_t> &password, GatekeeperResponse &rsp,
                         bool expectSuccess) {
    GatekeeperRequest req;
    req.newPwd.setToExternal(password.data(), password.size());
    doEnroll(req, rsp);
    checkEnroll(rsp, expectSuccess);
  }

  void verifyPassword(hidl_vec<uint8_t> &password,
                      hidl_vec<uint8_t> &passwordHandle, uint64_t challenge,
                      GatekeeperResponse &verifyRsp, bool expectSuccess) {
    GatekeeperRequest verifyReq;

    // build verify request for the same password (we want it to succeed)
    verifyReq.newPwd = password;
    // use enrolled password handle we've got
    verifyReq.curPwdHandle = passwordHandle;
    verifyReq.challenge = challenge;
    doVerify(verifyReq, verifyRsp);
    checkVerify(verifyRsp, challenge, expectSuccess);
  }

 protected:
  sp<IGatekeeper> gatekeeper_;
  uint32_t uid_;

 public:
  GatekeeperHidlTest() : uid_(0) {}
  virtual void SetUp() override {
    GatekeeperResponse rsp;
    gatekeeper_ = ::testing::VtsHalHidlTargetTestBase::getService<IGatekeeper>(
        GatekeeperHidlEnvironment::Instance()->getServiceName<IGatekeeper>());
    ASSERT_NE(nullptr, gatekeeper_.get());
    doDeleteAllUsers(rsp);
  }

  virtual void TearDown() override {
    GatekeeperResponse rsp;
    doDeleteAllUsers(rsp);
  }
};

/**
 * Ensure we can enroll new password
 */
TEST_F(GatekeeperHidlTest, EnrollSuccess) {
  hidl_vec<uint8_t> password;
  GatekeeperResponse rsp;
  ALOGI("Testing Enroll (expected success)");
  generatePassword(password, 0);
  enrollNewPassword(password, rsp, true);
  ALOGI("Testing Enroll done");
}

/**
 * Ensure we can not enroll empty password
 */
TEST_F(GatekeeperHidlTest, EnrollNoPassword) {
  hidl_vec<uint8_t> password;
  GatekeeperResponse rsp;
  ALOGI("Testing Enroll (expected failure)");
  enrollNewPassword(password, rsp, false);
  ALOGI("Testing Enroll done");
}

/**
 * Ensure we can successfully verify previously enrolled password
 */
TEST_F(GatekeeperHidlTest, VerifySuccess) {
  GatekeeperResponse enrollRsp;
  GatekeeperResponse verifyRsp;
  hidl_vec<uint8_t> password;

  ALOGI("Testing Enroll+Verify (expected success)");
  generatePassword(password, 0);
  enrollNewPassword(password, enrollRsp, true);
  verifyPassword(password, enrollRsp.data, 1, verifyRsp, true);
  ALOGI("Testing Enroll+Verify done");
}

/**
 * Ensure we can securely update password (keep the same
 * secure user_id) if we prove we know old password
 */
TEST_F(GatekeeperHidlTest, TrustedReenroll) {
  GatekeeperResponse enrollRsp;
  GatekeeperRequest reenrollReq;
  GatekeeperResponse reenrollRsp;
  GatekeeperResponse verifyRsp;
  GatekeeperResponse reenrollVerifyRsp;
  hidl_vec<uint8_t> password;
  hidl_vec<uint8_t> newPassword;

  generatePassword(password, 0);

  ALOGI("Testing Trusted Reenroll (expected success)");
  enrollNewPassword(password, enrollRsp, true);
  verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
  ALOGI("Primary Enroll+Verify done");

  generatePassword(newPassword, 1);
  reenrollReq.newPwd.setToExternal(newPassword.data(), newPassword.size());
  reenrollReq.curPwd.setToExternal(password.data(), password.size());
  reenrollReq.curPwdHandle.setToExternal(enrollRsp.data.data(),
                                         enrollRsp.data.size());

  doEnroll(reenrollReq, reenrollRsp);
  checkEnroll(reenrollRsp, true);
  verifyPassword(newPassword, reenrollRsp.data, 0, reenrollVerifyRsp, true);
  ALOGI("Trusted ReEnroll+Verify done");

  const hw_auth_token_t *first = toAuthToken(verifyRsp);
  const hw_auth_token_t *second = toAuthToken(reenrollVerifyRsp);
  if (first != nullptr && second != nullptr) {
    EXPECT_EQ(first->user_id, second->user_id);
  }
  ALOGI("Testing Trusted Reenroll done");
}

/**
 * Ensure we can update password (and get new
 * secure user_id) if we don't know old password
 */
TEST_F(GatekeeperHidlTest, UntrustedReenroll) {
  GatekeeperResponse enrollRsp;
  GatekeeperResponse reenrollRsp;
  GatekeeperResponse verifyRsp;
  GatekeeperResponse reenrollVerifyRsp;
  hidl_vec<uint8_t> password;
  hidl_vec<uint8_t> newPassword;

  ALOGI("Testing Untrusted Reenroll (expected success)");
  generatePassword(password, 0);
  enrollNewPassword(password, enrollRsp, true);
  verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
  ALOGI("Primary Enroll+Verify done");

  generatePassword(newPassword, 1);
  enrollNewPassword(newPassword, reenrollRsp, true);
  verifyPassword(newPassword, reenrollRsp.data, 0, reenrollVerifyRsp, true);
  ALOGI("Untrusted ReEnroll+Verify done");

  const hw_auth_token_t *first = toAuthToken(verifyRsp);
  const hw_auth_token_t *second = toAuthToken(reenrollVerifyRsp);
  if (first != nullptr && second != nullptr) {
    EXPECT_NE(first->user_id, second->user_id);
  }
  ALOGI("Testing Untrusted Reenroll done");
}

/**
 * Ensure we dont get successful verify with invalid data
 */
TEST_F(GatekeeperHidlTest, VerifyNoData) {
  hidl_vec<uint8_t> password;
  hidl_vec<uint8_t> passwordHandle;
  GatekeeperResponse verifyRsp;

  ALOGI("Testing Verify (expected failure)");
  verifyPassword(password, passwordHandle, 0, verifyRsp, false);
  EXPECT_EQ(GatekeeperStatusCode::ERROR_GENERAL_FAILURE, verifyRsp.code);
  ALOGI("Testing Verify done");
}

/**
 * Ensure we can not verify password after we enrolled it and then deleted user
 */
TEST_F(GatekeeperHidlTest, DeleteUserTest) {
  hidl_vec<uint8_t> password;
  GatekeeperResponse enrollRsp;
  GatekeeperResponse verifyRsp;
  GatekeeperResponse delRsp;
  ALOGI("Testing deleteUser (expected success)");
  setUid(10001);
  generatePassword(password, 0);
  enrollNewPassword(password, enrollRsp, true);
  verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
  ALOGI("Enroll+Verify done");
  doDeleteUser(delRsp);
  EXPECT_EQ(UINT32_C(0), delRsp.data.size());
  EXPECT_TRUE(delRsp.code == GatekeeperStatusCode::ERROR_NOT_IMPLEMENTED ||
              delRsp.code == GatekeeperStatusCode::STATUS_OK);
  ALOGI("DeleteUser done");
  if (delRsp.code == GatekeeperStatusCode::STATUS_OK) {
    verifyPassword(password, enrollRsp.data, 0, verifyRsp, false);
    EXPECT_EQ(GatekeeperStatusCode::ERROR_GENERAL_FAILURE, verifyRsp.code);
    ALOGI("Verify after Delete done (must fail)");
  }
  ALOGI("Testing deleteUser done: rsp=%" PRIi32, delRsp.code);
}

/**
 * Ensure we can not delete a user that does not exist
 */
TEST_F(GatekeeperHidlTest, DeleteInvalidUserTest) {
  hidl_vec<uint8_t> password;
  GatekeeperResponse enrollRsp;
  GatekeeperResponse verifyRsp;
  GatekeeperResponse delRsp1;
  GatekeeperResponse delRsp2;
  ALOGI("Testing deleteUser (expected failure)");
  setUid(10002);
  generatePassword(password, 0);
  enrollNewPassword(password, enrollRsp, true);
  verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
  ALOGI("Enroll+Verify done");

  // Delete the user
  doDeleteUser(delRsp1);
  EXPECT_EQ(UINT32_C(0), delRsp1.data.size());
  EXPECT_TRUE(delRsp1.code == GatekeeperStatusCode::ERROR_NOT_IMPLEMENTED ||
              delRsp1.code == GatekeeperStatusCode::STATUS_OK);

  // Delete the user again
  doDeleteUser(delRsp2);
  EXPECT_EQ(UINT32_C(0), delRsp2.data.size());
  EXPECT_TRUE(delRsp2.code == GatekeeperStatusCode::ERROR_NOT_IMPLEMENTED ||
              delRsp2.code == GatekeeperStatusCode::ERROR_GENERAL_FAILURE);
  ALOGI("DeleteUser done");
  ALOGI("Testing deleteUser done: rsp=%" PRIi32, delRsp2.code);
}

/**
 * Ensure we can not verify passwords after we enrolled them and then deleted
 * all users
 */
TEST_F(GatekeeperHidlTest, DeleteAllUsersTest) {
  struct UserData {
    uint32_t userId;
    hidl_vec<uint8_t> password;
    GatekeeperResponse enrollRsp;
    GatekeeperResponse verifyRsp;
    UserData(int id) { userId = id; }
  } users[3]{10001, 10002, 10003};
  GatekeeperResponse delAllRsp;
  ALOGI("Testing deleteAllUsers (expected success)");

  // enroll multiple users
  for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
    setUid(users[i].userId);
    generatePassword(users[i].password, (i % 255) + 1);
    enrollNewPassword(users[i].password, users[i].enrollRsp, true);
  }
  ALOGI("Multiple users enrolled");

  // verify multiple users
  for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
    setUid(users[i].userId);
    verifyPassword(users[i].password, users[i].enrollRsp.data, 0,
                   users[i].verifyRsp, true);
  }
  ALOGI("Multiple users verified");

  doDeleteAllUsers(delAllRsp);
  EXPECT_EQ(UINT32_C(0), delAllRsp.data.size());
  EXPECT_TRUE(delAllRsp.code == GatekeeperStatusCode::ERROR_NOT_IMPLEMENTED ||
              delAllRsp.code == GatekeeperStatusCode::STATUS_OK);
  ALOGI("All users deleted");

  if (delAllRsp.code == GatekeeperStatusCode::STATUS_OK) {
    // verify multiple users after they are deleted; all must fail
    for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
      setUid(users[i].userId);
      verifyPassword(users[i].password, users[i].enrollRsp.data, 0,
                     users[i].verifyRsp, false);
      EXPECT_EQ(GatekeeperStatusCode::ERROR_GENERAL_FAILURE,
                users[i].verifyRsp.code);
    }
    ALOGI("Multiple users verified after delete (all must fail)");
  }

  ALOGI("Testing deleteAllUsers done: rsp=%" PRIi32, delAllRsp.code);
}

int main(int argc, char **argv) {
  ::testing::AddGlobalTestEnvironment(GatekeeperHidlEnvironment::Instance());
  ::testing::InitGoogleTest(&argc, argv);
  GatekeeperHidlEnvironment::Instance()->init(&argc, argv);
  int status = RUN_ALL_TESTS();
  ALOGI("Test result = %d", status);
  return status;
}
