// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "trunks/policy_session_impl.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "trunks/error_codes.h"
#include "trunks/mock_session_manager.h"
#include "trunks/mock_tpm.h"
#include "trunks/tpm_generated.h"
#include "trunks/trunks_factory_for_test.h"

using testing::_;
using testing::NiceMock;
using testing::Return;
using testing::SaveArg;
using testing::SetArgPointee;

namespace trunks {

class PolicySessionTest : public testing::Test {
 public:
  PolicySessionTest() {}
  ~PolicySessionTest() override {}

  void SetUp() override {
    factory_.set_session_manager(&mock_session_manager_);
    factory_.set_tpm(&mock_tpm_);
  }

  HmacAuthorizationDelegate* GetHmacDelegate(PolicySessionImpl* session) {
    return &(session->hmac_delegate_);
  }

 protected:
  TrunksFactoryForTest factory_;
  NiceMock<MockSessionManager> mock_session_manager_;
  NiceMock<MockTpm> mock_tpm_;
};

TEST_F(PolicySessionTest, GetDelegateUninitialized) {
  PolicySessionImpl session(factory_);
  EXPECT_CALL(mock_session_manager_, GetSessionHandle())
      .WillRepeatedly(Return(kUninitializedHandle));
  EXPECT_EQ(nullptr, session.GetDelegate());
}

TEST_F(PolicySessionTest, GetDelegateSuccess) {
  PolicySessionImpl session(factory_);
  EXPECT_CALL(mock_session_manager_, GetSessionHandle())
      .WillRepeatedly(Return(TPM_RH_FIRST));
  EXPECT_EQ(GetHmacDelegate(&session), session.GetDelegate());
}

TEST_F(PolicySessionTest, StartBoundSessionSuccess) {
  PolicySessionImpl session(factory_);
  EXPECT_EQ(TPM_RC_SUCCESS,
            session.StartBoundSession(TPM_RH_FIRST, "auth", true));
}

TEST_F(PolicySessionTest, StartBoundSessionFailure) {
  PolicySessionImpl session(factory_);
  TPM_HANDLE handle = TPM_RH_FIRST;
  EXPECT_CALL(mock_session_manager_, StartSession(TPM_SE_POLICY, handle,
                                                  _, true, _))
      .WillRepeatedly(Return(TPM_RC_FAILURE));
  EXPECT_EQ(TPM_RC_FAILURE, session.StartBoundSession(handle, "auth", true));
}

TEST_F(PolicySessionTest, StartUnboundSessionSuccess) {
  PolicySessionImpl session(factory_);
  EXPECT_EQ(TPM_RC_SUCCESS, session.StartUnboundSession(true));
}

TEST_F(PolicySessionTest, StartUnboundSessionFailure) {
  PolicySessionImpl session(factory_);
  EXPECT_CALL(mock_session_manager_, StartSession(TPM_SE_POLICY, TPM_RH_NULL,
                                                  _, true, _))
      .WillRepeatedly(Return(TPM_RC_FAILURE));
  EXPECT_EQ(TPM_RC_FAILURE, session.StartUnboundSession(true));
}

TEST_F(PolicySessionTest, GetDigestSuccess) {
  PolicySessionImpl session(factory_);
  std::string digest;
  TPM2B_DIGEST policy_digest;
  policy_digest.size = SHA256_DIGEST_SIZE;
  EXPECT_CALL(mock_tpm_, PolicyGetDigestSync(_, _, _, _))
      .WillOnce(DoAll(SetArgPointee<2>(policy_digest),
                      Return(TPM_RC_SUCCESS)));
  EXPECT_EQ(TPM_RC_SUCCESS, session.GetDigest(&digest));
  EXPECT_EQ(SHA256_DIGEST_SIZE, digest.size());
}

TEST_F(PolicySessionTest, GetDigestFailure) {
  PolicySessionImpl session(factory_);
  std::string digest;
  EXPECT_CALL(mock_tpm_, PolicyGetDigestSync(_, _, _, _))
      .WillOnce(Return(TPM_RC_FAILURE));
  EXPECT_EQ(TPM_RC_FAILURE, session.GetDigest(&digest));
}

TEST_F(PolicySessionTest, PolicyORSuccess) {
  PolicySessionImpl session(factory_);
  std::vector<std::string> digests;
  digests.push_back("digest1");
  digests.push_back("digest2");
  digests.push_back("digest3");
  TPML_DIGEST tpm_digests;
  EXPECT_CALL(mock_tpm_, PolicyORSync(_, _, _, _))
      .WillOnce(DoAll(SaveArg<2>(&tpm_digests),
                      Return(TPM_RC_SUCCESS)));
  EXPECT_EQ(TPM_RC_SUCCESS, session.PolicyOR(digests));
  EXPECT_EQ(tpm_digests.count, digests.size());
  EXPECT_EQ(StringFrom_TPM2B_DIGEST(tpm_digests.digests[0]), digests[0]);
  EXPECT_EQ(StringFrom_TPM2B_DIGEST(tpm_digests.digests[1]), digests[1]);
  EXPECT_EQ(StringFrom_TPM2B_DIGEST(tpm_digests.digests[2]), digests[2]);
}

TEST_F(PolicySessionTest, PolicyORBadParam) {
  PolicySessionImpl session(factory_);
  std::vector<std::string> digests;
  // We use 9 here because the maximum number of digests allowed by the TPM
  // is 8. Therefore having 9 digests here should cause the code to fail.
  digests.resize(9);
  EXPECT_EQ(SAPI_RC_BAD_PARAMETER, session.PolicyOR(digests));
}

TEST_F(PolicySessionTest, PolicyORFailure) {
  PolicySessionImpl session(factory_);
  std::vector<std::string> digests;
  EXPECT_CALL(mock_tpm_, PolicyORSync(_, _, _, _))
      .WillOnce(Return(TPM_RC_FAILURE));
  EXPECT_EQ(TPM_RC_FAILURE, session.PolicyOR(digests));
}

TEST_F(PolicySessionTest, PolicyPCRSuccess) {
  PolicySessionImpl session(factory_);
  std::string pcr_digest("digest");
  int pcr_index = 1;
  TPML_PCR_SELECTION pcr_select;
  TPM2B_DIGEST pcr_value;
  EXPECT_CALL(mock_tpm_, PolicyPCRSync(_, _, _, _, _))
      .WillOnce(DoAll(SaveArg<2>(&pcr_value),
                      SaveArg<3>(&pcr_select),
                      Return(TPM_RC_SUCCESS)));
  EXPECT_EQ(TPM_RC_SUCCESS, session.PolicyPCR(pcr_index, pcr_digest));
  uint8_t pcr_select_index = pcr_index / 8;
  uint8_t pcr_select_byte = 1 << (pcr_index % 8);
  EXPECT_EQ(pcr_select.count, 1);
  EXPECT_EQ(pcr_select.pcr_selections[0].hash, TPM_ALG_SHA256);
  EXPECT_EQ(pcr_select.pcr_selections[0].sizeof_select,
            (pcr_select_index + 1));
  EXPECT_EQ(pcr_select.pcr_selections[0].pcr_select[pcr_select_index],
            pcr_select_byte);
  EXPECT_EQ(StringFrom_TPM2B_DIGEST(pcr_value), pcr_digest);
}

TEST_F(PolicySessionTest, PolicyPCRFailure) {
  PolicySessionImpl session(factory_);
  EXPECT_CALL(mock_tpm_, PolicyPCRSync(_, _, _, _, _))
      .WillOnce(Return(TPM_RC_FAILURE));
  EXPECT_EQ(TPM_RC_FAILURE, session.PolicyPCR(1, "pcr_digest"));
}

TEST_F(PolicySessionTest, PolicyCommandCodeSuccess) {
  PolicySessionImpl session(factory_);
  TPM_CC command_code = TPM_CC_FIRST;
  EXPECT_CALL(mock_tpm_, PolicyCommandCodeSync(_, _, command_code, _))
      .WillOnce(Return(TPM_RC_SUCCESS));
  EXPECT_EQ(TPM_RC_SUCCESS, session.PolicyCommandCode(TPM_CC_FIRST));
}

TEST_F(PolicySessionTest, PolicyCommandCodeFailure) {
  PolicySessionImpl session(factory_);
  EXPECT_CALL(mock_tpm_, PolicyCommandCodeSync(_, _, _, _))
      .WillOnce(Return(TPM_RC_FAILURE));
  EXPECT_EQ(TPM_RC_FAILURE, session.PolicyCommandCode(TPM_CC_FIRST));
}

TEST_F(PolicySessionTest, PolicyAuthValueSuccess) {
  PolicySessionImpl session(factory_);
  EXPECT_CALL(mock_tpm_, PolicyAuthValueSync(_, _, _))
      .WillOnce(Return(TPM_RC_SUCCESS));
  EXPECT_EQ(TPM_RC_SUCCESS, session.PolicyAuthValue());
}

TEST_F(PolicySessionTest, PolicyAuthValueFailure) {
  PolicySessionImpl session(factory_);
  EXPECT_CALL(mock_tpm_, PolicyAuthValueSync(_, _, _))
      .WillOnce(Return(TPM_RC_FAILURE));
  EXPECT_EQ(TPM_RC_FAILURE, session.PolicyAuthValue());
}

TEST_F(PolicySessionTest, EntityAuthorizationForwardingTest) {
  PolicySessionImpl session(factory_);
  std::string test_auth("test_auth");
  session.SetEntityAuthorizationValue(test_auth);
  HmacAuthorizationDelegate* hmac_delegate = GetHmacDelegate(&session);
  std::string entity_auth = hmac_delegate->entity_authorization_value();
  EXPECT_EQ(0, test_auth.compare(entity_auth));
}

}  // namespace trunks
