// 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/resource_manager.h"

#include <string>
#include <vector>

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

#include "trunks/error_codes.h"
#include "trunks/mock_command_transceiver.h"
#include "trunks/mock_tpm.h"
#include "trunks/trunks_factory_for_test.h"

using testing::_;
using testing::DoAll;
using testing::Eq;
using testing::Field;
using testing::InSequence;
using testing::Return;
using testing::ReturnPointee;
using testing::SetArgumentPointee;
using testing::StrictMock;

namespace {

const trunks::TPM_HANDLE kArbitraryObjectHandle = trunks::TRANSIENT_FIRST + 25;
const trunks::TPM_HANDLE kArbitrarySessionHandle = trunks::HMAC_SESSION_FIRST;

void Assign(std::string* to, const std::string& from) {
  *to = from;
}

class ScopedDisableLogging {
 public:
  ScopedDisableLogging() : original_severity_(logging::GetMinLogLevel()) {
    logging::SetMinLogLevel(logging::LOG_FATAL);
  }
  ~ScopedDisableLogging() {
    logging::SetMinLogLevel(original_severity_);
  }

 private:
  logging::LogSeverity original_severity_;
};

}  // namespace

namespace trunks {

class ResourceManagerTest : public testing::Test {
 public:
  const std::vector<TPM_HANDLE> kNoHandles;
  const std::string kNoAuthorization;
  const std::string kNoParameters;

  ResourceManagerTest() : resource_manager_(factory_, &transceiver_) {}
  ~ResourceManagerTest() override {}

  void SetUp() override {
    factory_.set_tpm(&tpm_);
  }

  // Builds a well-formed command.
  std::string CreateCommand(TPM_CC code,
                            const std::vector<TPM_HANDLE>& handles,
                            const std::string& authorization,
                            const std::string& parameters) {
    std::string buffer;
    TPM_ST tag = authorization.empty() ? TPM_ST_NO_SESSIONS : TPM_ST_SESSIONS;
    UINT32 size = 10 + (handles.size() * 4) + authorization.size() +
                  parameters.size() + (authorization.empty() ? 0 : 4);
    Serialize_TPM_ST(tag, &buffer);
    Serialize_UINT32(size, &buffer);
    Serialize_TPM_CC(code, &buffer);
    for (auto handle : handles) {
      Serialize_TPM_HANDLE(handle, &buffer);
    }
    if (!authorization.empty()) {
      Serialize_UINT32(authorization.size(), &buffer);
    }
    return buffer + authorization + parameters;
  }

  // Builds a well-formed response.
  std::string CreateResponse(TPM_RC code,
                             const std::vector<TPM_HANDLE>& handles,
                             const std::string& authorization,
                             const std::string& parameters) {
    std::string buffer;
    TPM_ST tag = authorization.empty() ? TPM_ST_NO_SESSIONS : TPM_ST_SESSIONS;
    UINT32 size = 10 + (handles.size() * 4) + authorization.size() +
                  parameters.size() + (authorization.empty() ? 0 : 4);
    Serialize_TPM_ST(tag, &buffer);
    Serialize_UINT32(size, &buffer);
    Serialize_TPM_RC(code, &buffer);
    for (auto handle : handles) {
      Serialize_TPM_HANDLE(handle, &buffer);
    }
    if (!authorization.empty()) {
      Serialize_UINT32(parameters.size(), &buffer);
    }
    return buffer + parameters + authorization;
  }

  // Builds a well-formed command authorization section.
  std::string CreateCommandAuthorization(TPM_HANDLE handle,
                                         bool continue_session) {
    std::string buffer;
    Serialize_TPM_HANDLE(handle, &buffer);
    Serialize_TPM2B_NONCE(Make_TPM2B_DIGEST(std::string(32, 'A')), &buffer);
    Serialize_BYTE(continue_session ? 1 : 0, &buffer);
    Serialize_TPM2B_DIGEST(Make_TPM2B_DIGEST(std::string(32, 'B')), &buffer);
    return buffer;
  }

  // Builds a well-formed response authorization section.
  std::string CreateResponseAuthorization(bool continue_session) {
    std::string buffer;
    Serialize_TPM2B_NONCE(Make_TPM2B_DIGEST(std::string(32, 'A')), &buffer);
    Serialize_BYTE(continue_session ? 1 : 0, &buffer);
    Serialize_TPM2B_DIGEST(Make_TPM2B_DIGEST(std::string(32, 'B')), &buffer);
    return buffer;
  }

  std::string GetHeader(const std::string& message) {
    return message.substr(0, 10);
  }

  std::string StripHeader(const std::string& message) {
    return message.substr(10);
  }

  // Makes the resource manager aware of a transient object handle and returns
  // the newly associated virtual handle.
  TPM_HANDLE LoadHandle(TPM_HANDLE handle) {
    std::vector<TPM_HANDLE> input_handles = {PERSISTENT_FIRST};
    std::string command = CreateCommand(TPM_CC_Load,
                                        input_handles,
                                        kNoAuthorization,
                                        kNoParameters);
    std::vector<TPM_HANDLE> output_handles = {handle};
    std::string response = CreateResponse(TPM_RC_SUCCESS,
                                          output_handles,
                                          kNoAuthorization,
                                          kNoParameters);
    EXPECT_CALL(transceiver_, SendCommandAndWait(command))
        .WillOnce(Return(response));
    std::string actual_response = resource_manager_.SendCommandAndWait(command);
    std::string handle_blob = StripHeader(actual_response);
    TPM_HANDLE virtual_handle;
    CHECK_EQ(TPM_RC_SUCCESS, Parse_TPM_HANDLE(&handle_blob, &virtual_handle,
                                              NULL));
    return virtual_handle;
  }

  // Causes the resource manager to evict existing object handles.
  void EvictObjects() {
    std::string command = CreateCommand(TPM_CC_Startup,
                                        kNoHandles,
                                        kNoAuthorization,
                                        kNoParameters);
    std::string response = CreateErrorResponse(TPM_RC_OBJECT_MEMORY);
    std::string success_response = CreateResponse(TPM_RC_SUCCESS,
                                                  kNoHandles,
                                                  kNoAuthorization,
                                                  kNoParameters);
    EXPECT_CALL(transceiver_, SendCommandAndWait(_))
        .WillOnce(Return(response))
        .WillRepeatedly(Return(success_response));
    EXPECT_CALL(tpm_, ContextSaveSync(_, _, _, _))
        .WillRepeatedly(Return(TPM_RC_SUCCESS));
    EXPECT_CALL(tpm_, FlushContextSync(_, _))
        .WillRepeatedly(Return(TPM_RC_SUCCESS));
    resource_manager_.SendCommandAndWait(command);
  }

  // Makes the resource manager aware of a session handle.
  void StartSession(TPM_HANDLE handle) {
    std::vector<TPM_HANDLE> input_handles = {1, 2};
    std::string command = CreateCommand(TPM_CC_StartAuthSession,
                                        input_handles,
                                        kNoAuthorization,
                                        kNoParameters);
    std::vector<TPM_HANDLE> output_handles = {handle};
    std::string response = CreateResponse(TPM_RC_SUCCESS,
                                          output_handles,
                                          kNoAuthorization,
                                          kNoParameters);
    EXPECT_CALL(transceiver_, SendCommandAndWait(command))
        .WillOnce(Return(response));
    std::string actual_response = resource_manager_.SendCommandAndWait(command);
    ASSERT_EQ(response, actual_response);
  }

  // Causes the resource manager to evict an existing session handle.
  void EvictSession() {
    std::string command = CreateCommand(TPM_CC_Startup,
                                        kNoHandles,
                                        kNoAuthorization,
                                        kNoParameters);
    std::string response = CreateErrorResponse(TPM_RC_SESSION_MEMORY);
    std::string success_response = CreateResponse(TPM_RC_SUCCESS,
                                                  kNoHandles,
                                                  kNoAuthorization,
                                                  kNoParameters);
    EXPECT_CALL(transceiver_, SendCommandAndWait(_))
        .WillOnce(Return(response))
        .WillRepeatedly(Return(success_response));
    EXPECT_CALL(tpm_, ContextSaveSync(_, _, _, _))
        .WillOnce(Return(TPM_RC_SUCCESS));
    resource_manager_.SendCommandAndWait(command);
  }

  // Creates a TPMS_CONTEXT with the given sequence field.
  TPMS_CONTEXT CreateContext(UINT64 sequence) {
    TPMS_CONTEXT context = {sequence};
    return context;
  }

  // Creates a serialized TPMS_CONTEXT with the given sequence field.
  std::string CreateContextParameter(UINT64 sequence) {
    std::string buffer;
    Serialize_TPMS_CONTEXT(CreateContext(sequence), &buffer);
    return buffer;
  }

 protected:
  StrictMock<MockTpm> tpm_;
  TrunksFactoryForTest factory_;
  StrictMock<MockCommandTransceiver> transceiver_;
  ResourceManager resource_manager_;
};

TEST_F(ResourceManagerTest, BasicPassThrough) {
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      kNoAuthorization,
                                      kNoParameters);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        kNoAuthorization,
                                        kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
      .WillOnce(Return(response));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(actual_response, response);
}

TEST_F(ResourceManagerTest, BasicPassThroughAsync) {
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      kNoAuthorization,
                                      kNoParameters);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        kNoAuthorization,
                                        kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
      .WillOnce(Return(response));
  std::string actual_response;
  CommandTransceiver::ResponseCallback callback =
      base::Bind(&Assign, &actual_response);
  resource_manager_.SendCommand(command, callback);
  EXPECT_EQ(actual_response, response);
}

TEST_F(ResourceManagerTest, VirtualHandleOutput) {
  std::vector<TPM_HANDLE> input_handles = {PERSISTENT_FIRST};
  std::string command = CreateCommand(TPM_CC_Load,
                                      input_handles,
                                      kNoAuthorization,
                                      kNoParameters);
  std::vector<TPM_HANDLE> output_handles = {kArbitraryObjectHandle};
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        output_handles,
                                        kNoAuthorization,
                                        kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
      .WillOnce(Return(response));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response.size(), actual_response.size());
  // We expect the resource manager has replaced the output handle with a
  // virtual handle (which we can't predict, but it's unlikely to be the same as
  // the handle emitted by the mock).
  EXPECT_EQ(GetHeader(response), GetHeader(actual_response));
  EXPECT_NE(StripHeader(response), StripHeader(actual_response));
  TPM_HT handle_type = static_cast<TPM_HT>(StripHeader(actual_response)[0]);
  EXPECT_EQ(TPM_HT_TRANSIENT, handle_type);
}

TEST_F(ResourceManagerTest, VirtualHandleInput) {
  TPM_HANDLE tpm_handle = kArbitraryObjectHandle;
  TPM_HANDLE virtual_handle = LoadHandle(tpm_handle);
  std::vector<TPM_HANDLE> input_handles = {virtual_handle};
  std::string command = CreateCommand(TPM_CC_Sign,
                                      input_handles,
                                      kNoAuthorization,
                                      kNoParameters);
  // We expect the resource manager to replace |virtual_handle| with
  // |tpm_handle|.
  std::vector<TPM_HANDLE> expected_input_handles = {tpm_handle};
  std::string expected_command = CreateCommand(TPM_CC_Sign,
                                               expected_input_handles,
                                               kNoAuthorization,
                                               kNoParameters);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        kNoAuthorization,
                                        kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(expected_command))
      .WillOnce(Return(response));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
}

TEST_F(ResourceManagerTest, VirtualHandleCleanup) {
  TPM_HANDLE tpm_handle = kArbitraryObjectHandle;
  TPM_HANDLE virtual_handle = LoadHandle(tpm_handle);
  std::string parameters;
  Serialize_TPM_HANDLE(virtual_handle, &parameters);
  std::string command = CreateCommand(TPM_CC_FlushContext,
                                      kNoHandles,
                                      kNoAuthorization,
                                      parameters);
  std::string expected_parameters;
  Serialize_TPM_HANDLE(tpm_handle, &expected_parameters);
  std::string expected_command = CreateCommand(TPM_CC_FlushContext,
                                               kNoHandles,
                                               kNoAuthorization,
                                               expected_parameters);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        kNoAuthorization,
                                        kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(expected_command))
      .WillOnce(Return(response));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
  // Now we expect there to be no record of |virtual_handle|.
  std::vector<TPM_HANDLE> input_handles = {virtual_handle};
  command = CreateCommand(TPM_CC_Sign,
                          input_handles,
                          kNoAuthorization,
                          kNoParameters);
  response = CreateErrorResponse(TPM_RC_HANDLE | kResourceManagerTpmErrorBase);
  actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);

  // Try again but attempt to flush |tpm_handle| instead of |virtual_handle|.
  virtual_handle = LoadHandle(tpm_handle);
  parameters.clear();
  Serialize_TPM_HANDLE(tpm_handle, &parameters);
  command = CreateCommand(TPM_CC_FlushContext,
                          kNoHandles,
                          kNoAuthorization,
                          parameters);
  actual_response = resource_manager_.SendCommandAndWait(command);
  // TPM_RC_HANDLE also expected here.
  EXPECT_EQ(response, actual_response);
}

TEST_F(ResourceManagerTest, VirtualHandleLoadBeforeUse) {
  TPM_HANDLE tpm_handle = kArbitraryObjectHandle;
  TPM_HANDLE virtual_handle = LoadHandle(tpm_handle);
  EvictObjects();
  std::vector<TPM_HANDLE> input_handles = {virtual_handle};
  std::string command = CreateCommand(TPM_CC_Sign,
                                      input_handles,
                                      kNoAuthorization,
                                      kNoParameters);
  std::vector<TPM_HANDLE> expected_input_handles = {tpm_handle};
  std::string expected_command = CreateCommand(TPM_CC_Sign,
                                               expected_input_handles,
                                               kNoAuthorization,
                                               kNoParameters);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        kNoAuthorization,
                                        kNoParameters);
  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
      .WillOnce(Return(TPM_RC_SUCCESS));
  EXPECT_CALL(transceiver_, SendCommandAndWait(expected_command))
      .WillOnce(Return(response));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
}

TEST_F(ResourceManagerTest, InvalidVirtualHandle) {
  std::vector<TPM_HANDLE> input_handles = {kArbitraryObjectHandle};
  std::string command = CreateCommand(TPM_CC_Sign,
                                      input_handles,
                                      kNoAuthorization,
                                      kNoParameters);
  std::string response = CreateErrorResponse(TPM_RC_HANDLE |
                                             kResourceManagerTpmErrorBase);
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
}

TEST_F(ResourceManagerTest, SimpleFuzzInputParser) {
  std::vector<TPM_HANDLE> handles = {1, 2};
  std::string parameters = "12345";
  std::string command = CreateCommand(TPM_CC_StartAuthSession,
                                      handles,
                                      CreateCommandAuthorization(
                                          kArbitrarySessionHandle,
                                          true),  // continue_session
                                      parameters);
  // We don't care about what happens, only that it doesn't crash.
  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
      .WillRepeatedly(Return(CreateErrorResponse(TPM_RC_FAILURE)));
  ScopedDisableLogging no_logging;
  for (size_t i = 0; i < command.size(); ++i) {
    resource_manager_.SendCommandAndWait(command.substr(0, i));
    resource_manager_.SendCommandAndWait(command.substr(i));
    std::string fuzzed_command(command);
    for (uint8_t value = 0; ; value++) {
      fuzzed_command[i] = static_cast<char>(value);
      resource_manager_.SendCommandAndWait(fuzzed_command);
      if (value == 255) {
        break;
      }
    }
  }
}

TEST_F(ResourceManagerTest, SimpleFuzzOutputParser) {
  std::vector<TPM_HANDLE> handles = {1, 2};
  std::string parameters = "12345";
  std::string command = CreateCommand(TPM_CC_StartAuthSession,
                                      handles,
                                      CreateCommandAuthorization(
                                          kArbitrarySessionHandle,
                                          true),  // continue_session
                                      parameters);
  std::vector<TPM_HANDLE> out_handles = {3};
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        out_handles,
                                        CreateResponseAuthorization(
                                            true),  // continue_session
                                        parameters);
  std::string fuzzed_response;
  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
      .WillRepeatedly(ReturnPointee(&fuzzed_response));
  ScopedDisableLogging no_logging;
  for (size_t i = 0; i < response.size(); ++i) {
    fuzzed_response = response.substr(0, i);
    resource_manager_.SendCommandAndWait(command);
    fuzzed_response = response.substr(i);
    resource_manager_.SendCommandAndWait(command);
    fuzzed_response = response;
    for (uint8_t value = 0; ; value++) {
      fuzzed_response[i] = static_cast<char>(value);
      resource_manager_.SendCommandAndWait(command);
      if (value == 255) {
        break;
      }
    }
    fuzzed_response[i] = response[i];
  }
}

TEST_F(ResourceManagerTest, NewSession) {
  StartSession(kArbitrarySessionHandle);
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      CreateCommandAuthorization(
                                          kArbitrarySessionHandle,
                                          true),  // continue_session
                                      kNoParameters);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        CreateResponseAuthorization(
                                            true),  // continue_session
                                        kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
      .WillOnce(Return(response));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
}

TEST_F(ResourceManagerTest, DiscontinuedSession) {
  StartSession(kArbitrarySessionHandle);
  // Use the session but do not continue.
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      CreateCommandAuthorization(
                                          kArbitrarySessionHandle,
                                          false),  // continue_session
                                      kNoParameters);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        CreateResponseAuthorization(
                                            false),  // continue_session
                                        kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
      .WillOnce(Return(response));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
  // Now attempt to use it again and expect a handle error.
  response = CreateErrorResponse(TPM_RC_HANDLE | kResourceManagerTpmErrorBase);
  actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
}

TEST_F(ResourceManagerTest, LoadSessionBeforeUse) {
  StartSession(kArbitrarySessionHandle);
  EvictSession();
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      CreateCommandAuthorization(
                                          kArbitrarySessionHandle,
                                          true),  // continue_session
                                      kNoParameters);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        CreateResponseAuthorization(
                                            true),  // continue_session
                                        kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
      .WillOnce(Return(response));
  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
      .WillOnce(Return(TPM_RC_SUCCESS));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
}

TEST_F(ResourceManagerTest, SessionHandleCleanup) {
  StartSession(kArbitrarySessionHandle);
  std::string parameters;
  Serialize_TPM_HANDLE(kArbitrarySessionHandle, &parameters);
  std::string command = CreateCommand(TPM_CC_FlushContext,
                                      kNoHandles,
                                      kNoAuthorization,
                                      parameters);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        kNoAuthorization,
                                        kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
      .WillOnce(Return(response));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
  // Now we expect there to be no record of |kArbitrarySessionHandle|.
  command = CreateCommand(TPM_CC_Startup,
                          kNoHandles,
                          CreateCommandAuthorization(
                              kArbitrarySessionHandle,
                              true),  // continue_session
                          kNoParameters);
  response = CreateErrorResponse(TPM_RC_HANDLE | kResourceManagerTpmErrorBase);
  actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
}

TEST_F(ResourceManagerTest, EvictWhenObjectInUse) {
  TPM_HANDLE tpm_handle = kArbitraryObjectHandle;
  TPM_HANDLE virtual_handle = LoadHandle(tpm_handle);
  TPM_HANDLE tpm_handle2 = kArbitraryObjectHandle + 1;
  LoadHandle(tpm_handle2);
  std::vector<TPM_HANDLE> input_handles = {virtual_handle};
  std::string command = CreateCommand(TPM_CC_Sign,
                                      input_handles,
                                      kNoAuthorization,
                                      kNoParameters);
  // Trigger evict logic and verify |input_handles| are not evicted.
  std::string response = CreateErrorResponse(TPM_RC_OBJECT_MEMORY);
  std::string success_response = CreateResponse(TPM_RC_SUCCESS,
                                                kNoHandles,
                                                kNoAuthorization,
                                                kNoParameters);
  EXPECT_CALL(tpm_, ContextSaveSync(tpm_handle2, _, _, _))
      .WillOnce(Return(TPM_RC_SUCCESS));
  EXPECT_CALL(tpm_, FlushContextSync(tpm_handle2, _))
      .WillOnce(Return(TPM_RC_SUCCESS));
  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
      .WillOnce(Return(response))
      .WillRepeatedly(Return(success_response));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(success_response, actual_response);
}

TEST_F(ResourceManagerTest, EvictWhenSessionInUse) {
  StartSession(kArbitrarySessionHandle);
  StartSession(kArbitrarySessionHandle + 1);
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      CreateCommandAuthorization(
                                          kArbitrarySessionHandle,
                                          true),  // continue_session
                                      kNoParameters);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        CreateResponseAuthorization(
                                            true),  // continue_session
                                        kNoParameters);
  std::string error_response = CreateErrorResponse(TPM_RC_SESSION_MEMORY);
  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
      .WillOnce(Return(error_response))
      .WillRepeatedly(Return(response));
  EXPECT_CALL(tpm_, ContextSaveSync(kArbitrarySessionHandle + 1, _, _, _))
      .WillOnce(Return(TPM_RC_SUCCESS));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
}

TEST_F(ResourceManagerTest, EvictMultipleObjects) {
  const int kNumObjects = 10;
  std::map<TPM_HANDLE, TPM_HANDLE> handles;
  for (int i = 0; i < kNumObjects; ++i) {
    TPM_HANDLE handle = kArbitraryObjectHandle + i;
    handles[LoadHandle(handle)] = handle;
  }
  EvictObjects();
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        kNoAuthorization,
                                        kNoParameters);
  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
      .Times(kNumObjects)
      .WillRepeatedly(Return(TPM_RC_SUCCESS));
  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
      .WillRepeatedly(Return(response));
  for (auto item : handles) {
    std::vector<TPM_HANDLE> input_handles = {item.first};
    std::string command = CreateCommand(TPM_CC_Sign,
                                        input_handles,
                                        kNoAuthorization,
                                        kNoParameters);
    std::string actual_response = resource_manager_.SendCommandAndWait(command);
    EXPECT_EQ(response, actual_response);
  }
}

TEST_F(ResourceManagerTest, EvictMostStaleSession) {
  StartSession(kArbitrarySessionHandle);
  StartSession(kArbitrarySessionHandle + 1);
  StartSession(kArbitrarySessionHandle + 2);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        CreateResponseAuthorization(
                                            true),  // continue_session
                                        kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
      .WillRepeatedly(Return(response));
  // Use the first two sessions, leaving the third as the most stale.
  for (int i = 0; i < 2; ++i) {
    std::string command = CreateCommand(TPM_CC_Startup,
                                        kNoHandles,
                                        CreateCommandAuthorization(
                                            kArbitrarySessionHandle + i,
                                            true),  // continue_session
                                        kNoParameters);
    std::string actual_response = resource_manager_.SendCommandAndWait(command);
    EXPECT_EQ(response, actual_response);
  }
  EvictSession();
  // EvictSession will have messed with the expectations; set them again.
  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
      .WillRepeatedly(Return(response));
  // Use the first two sessions again, expecting no calls to ContextLoad.
  for (int i = 0; i < 2; ++i) {
    std::string command = CreateCommand(TPM_CC_Startup,
                                        kNoHandles,
                                        CreateCommandAuthorization(
                                            kArbitrarySessionHandle + i,
                                            true),  // continue_session
                                        kNoParameters);
    std::string actual_response = resource_manager_.SendCommandAndWait(command);
    EXPECT_EQ(response, actual_response);
  }
  // Expect a call to ContextLoad if we use the third session.
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      CreateCommandAuthorization(
                                          kArbitrarySessionHandle + 2,
                                          true),  // continue_session
                                      kNoParameters);
  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
      .WillOnce(Return(TPM_RC_SUCCESS));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
}

TEST_F(ResourceManagerTest, HandleContextGap) {
  const int kNumSessions = 7;
  const int kNumSessionsToUngap = 4;
  std::vector<TPM_HANDLE> expected_ungap_order;
  for (int i = 0; i < kNumSessions; ++i) {
    StartSession(kArbitrarySessionHandle + i);
    if (i < kNumSessionsToUngap) {
      EvictSession();
      expected_ungap_order.push_back(kArbitrarySessionHandle + i);
    }
  }
  // Invoke a context gap.
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      kNoAuthorization,
                                      kNoParameters);
  std::string response = CreateErrorResponse(TPM_RC_CONTEXT_GAP);
  std::string success_response = CreateResponse(TPM_RC_SUCCESS,
                                                kNoHandles,
                                                kNoAuthorization,
                                                kNoParameters);
  {
    InSequence ungap_order;
    for (auto handle : expected_ungap_order) {
      EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
          .WillOnce(Return(TPM_RC_SUCCESS));
      EXPECT_CALL(tpm_, ContextSaveSync(handle, _, _, _))
          .WillOnce(Return(TPM_RC_SUCCESS));
    }
  }
  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
      .WillOnce(Return(response))
      .WillRepeatedly(Return(success_response));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(success_response, actual_response);
}

TEST_F(ResourceManagerTest, ExternalContext) {
  StartSession(kArbitrarySessionHandle);
  // Do an external context save.
  std::vector<TPM_HANDLE> handles = {kArbitrarySessionHandle};
  std::string context_save = CreateCommand(TPM_CC_ContextSave,
                                           handles,
                                           kNoAuthorization,
                                           kNoParameters);
  std::string context_parameter1 = CreateContextParameter(1);
  std::string context_save_response1 = CreateResponse(TPM_RC_SUCCESS,
                                                      kNoHandles,
                                                      kNoAuthorization,
                                                      context_parameter1);
  EXPECT_CALL(transceiver_, SendCommandAndWait(context_save))
      .WillOnce(Return(context_save_response1));
  std::string actual_response = resource_manager_.SendCommandAndWait(
      context_save);
  EXPECT_EQ(context_save_response1, actual_response);

  // Invoke a context gap (which will cause context1 to be mapped to context2).
  EXPECT_CALL(tpm_, ContextLoadSync(Field(&TPMS_CONTEXT::sequence, Eq(1)),
                                    _, _))
      .WillOnce(Return(TPM_RC_SUCCESS));
  EXPECT_CALL(tpm_, ContextSaveSync(kArbitrarySessionHandle, _, _, _))
      .WillOnce(DoAll(SetArgumentPointee<2>(CreateContext(2)),
                      Return(TPM_RC_SUCCESS)));
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      kNoAuthorization,
                                      kNoParameters);
  std::string response = CreateErrorResponse(TPM_RC_CONTEXT_GAP);
  std::string success_response = CreateResponse(TPM_RC_SUCCESS,
                                                kNoHandles,
                                                kNoAuthorization,
                                                kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
      .WillOnce(Return(response))
      .WillOnce(Return(success_response));
  actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(success_response, actual_response);

  // Now load external context1 and expect an actual load of context2.
  std::string context_load1 = CreateCommand(TPM_CC_ContextLoad,
                                            kNoHandles,
                                            kNoAuthorization,
                                            context_parameter1);
  std::string context_load2 = CreateCommand(TPM_CC_ContextLoad,
                                            kNoHandles,
                                            kNoAuthorization,
                                            CreateContextParameter(2));
  std::string context_load_response = CreateResponse(TPM_RC_SUCCESS,
                                                     handles,
                                                     kNoAuthorization,
                                                     kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(context_load2))
      .WillOnce(Return(context_load_response));
  actual_response = resource_manager_.SendCommandAndWait(context_load1);
  EXPECT_EQ(context_load_response, actual_response);
}

TEST_F(ResourceManagerTest, NestedFailures) {
  // The scenario being tested is when a command results in a warning to be
  // handled by the resource manager, and in the process of handling the first
  // warning another warning occurs which should be handled by the resource
  // manager, etc..
  for (int i = 0; i < 3; ++i) {
    LoadHandle(kArbitraryObjectHandle + i);
  }
  EvictObjects();
  for (int i = 3; i < 6; ++i) {
    LoadHandle(kArbitraryObjectHandle + i);
  }
  for (int i = 0; i < 10; ++i) {
    StartSession(kArbitrarySessionHandle + i);
    EvictSession();
  }
  for (int i = 10; i < 20; ++i) {
    StartSession(kArbitrarySessionHandle + i);
  }
  std::string error_response = CreateErrorResponse(TPM_RC_MEMORY);
  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
      .WillRepeatedly(Return(error_response));
  // The TPM_RC_MEMORY will result in a context save, make that fail too.
  EXPECT_CALL(tpm_, ContextSaveSync(_, _, _, _))
      .WillRepeatedly(Return(TPM_RC_CONTEXT_GAP));
  // The TPM_RC_CONTEXT_GAP will result in a context load.
  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
      .WillRepeatedly(Return(TPM_RC_SESSION_HANDLES));
  // The TPM_RC_SESSION_HANDLES will result in a context flush.
  EXPECT_CALL(tpm_, FlushContextSync(_, _))
      .WillRepeatedly(Return(TPM_RC_SESSION_MEMORY));
  // The resource manager should not handle the same warning twice so we expect
  // the error of the original call to bubble up.
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      kNoAuthorization,
                                      kNoParameters);
  std::string response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(error_response, response);
}

TEST_F(ResourceManagerTest, OutOfMemory) {
  std::string error_response = CreateErrorResponse(TPM_RC_MEMORY);
  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
      .WillRepeatedly(Return(error_response));
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      kNoAuthorization,
                                      kNoParameters);
  std::string response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(error_response, response);
}

TEST_F(ResourceManagerTest, ReentrantFixGap) {
  for (int i = 0; i < 3; ++i) {
    StartSession(kArbitrarySessionHandle + i);
    EvictSession();
  }
  for (int i = 3; i < 6; ++i) {
    StartSession(kArbitrarySessionHandle + i);
  }
  std::string error_response = CreateErrorResponse(TPM_RC_CONTEXT_GAP);
  EXPECT_CALL(transceiver_, SendCommandAndWait(_))
      .WillRepeatedly(Return(error_response));
  EXPECT_CALL(tpm_, ContextSaveSync(_, _, _, _))
      .WillRepeatedly(Return(TPM_RC_CONTEXT_GAP));
  EXPECT_CALL(tpm_, ContextLoadSync(_, _, _))
      .WillOnce(Return(TPM_RC_CONTEXT_GAP))
      .WillRepeatedly(Return(TPM_RC_SUCCESS));
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      kNoAuthorization,
                                      kNoParameters);
  std::string response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(error_response, response);
}

TEST_F(ResourceManagerTest, PasswordAuthorization) {
  std::string command = CreateCommand(TPM_CC_Startup,
                                      kNoHandles,
                                      CreateCommandAuthorization(
                                          TPM_RS_PW,
                                          false),  // continue_session
                                      kNoParameters);
  std::string response = CreateResponse(TPM_RC_SUCCESS,
                                        kNoHandles,
                                        CreateResponseAuthorization(
                                            false),  // continue_session
                                        kNoParameters);
  EXPECT_CALL(transceiver_, SendCommandAndWait(command))
      .WillOnce(Return(response));
  std::string actual_response = resource_manager_.SendCommandAndWait(command);
  EXPECT_EQ(response, actual_response);
}

}  // namespace trunks
