// Copyright (c) 2012 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 "chaps/opencryptoki_importer.h"

#include <stdlib.h>

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <base/files/scoped_temp_dir.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "chaps/chaps_factory_mock.h"
#include "chaps/object_mock.h"
#include "chaps/object_pool_mock.h"
#include "chaps/tpm_utility_mock.h"

using base::FilePath;
using std::map;
using std::string;
using std::vector;
using testing::_;
using testing::AnyNumber;
using testing::DoAll;
using testing::Invoke;
using testing::Return;
using testing::SetArgPointee;
using testing::Values;

namespace chaps {

const unsigned char kSampleMasterKeyEncrypted[] = {
    80,  118, 191, 150, 143, 171, 162, 61,  89,  32,  95,  219, 44,  244, 51,
    84,  117, 228, 36,  225, 240, 122, 234, 92,  182, 224, 133, 238, 100, 18,
    116, 130, 166, 177, 7,   103, 223, 122, 112, 136, 126, 30,  191, 253, 137,
    85,  70,  187, 220, 137, 248, 155, 89,  152, 113, 153, 113, 48,  59,  148,
    246, 114, 146, 13,  86,  254, 227, 3,   229, 70,  247, 165, 101, 76,  3,
    58,  134, 230, 84,  113, 94,  226, 134, 130, 34,  100, 56,  157, 5,   255,
    127, 180, 147, 56,  43,  233, 32,  254, 209, 52,  41,  48,  15,  127, 110,
    187, 183, 254, 123, 20,  182, 153, 107, 192, 136, 229, 72,  243, 38,  238,
    155, 59,  216, 15,  17,  72,  39,  209, 196, 66,  53,  140, 236, 132, 19,
    69,  58,  107, 103, 22,  19,  70,  175, 35,  126, 16,  56,  132, 150, 89,
    182, 12,  3,   166, 206, 160, 194, 12,  250, 211, 141, 73,  109, 83,  144,
    253, 166, 71,  109, 219, 143, 202, 237, 89,  185, 136, 249, 104, 78,  68,
    11,  169, 144, 194, 57,  140, 147, 104, 175, 229, 20,  223, 98,  109, 187,
    120, 200, 126, 81,  147, 31,  13,  239, 36,  233, 221, 78,  117, 59,  248,
    156, 231, 189, 232, 48,  128, 150, 128, 84,  244, 30,  117, 183, 150, 70,
    30,  234, 2,   233, 161, 120, 96,  185, 155, 34,  75,  173, 200, 78,  183,
    66,  8,   144, 72,  20,  92,  246, 229, 255, 55,  148, 160, 153, 9,   150,
    16};

const unsigned char kSampleMasterKey[] = {
    116, 62,  77,  252, 196, 57,  225, 14,  115, 52,  68,
    60,  227, 254, 22,  162, 163, 22,  186, 125, 203, 138,
    205, 98,  151, 202, 179, 203, 86,  98,  149, 208};

const unsigned char kSampleAuthDataEncrypted[] = {
    37,  239, 160, 111, 19,  123, 167, 118, 161, 223, 61,  242, 63,  146, 22,
    223, 100, 79,  178, 52,  206, 121, 155, 88,  23,  68,  144, 66,  167, 187,
    83,  13,  101, 221, 218, 185, 99,  23,  149, 3,   239, 142, 78,  62,  239,
    155, 114, 83,  106, 108, 168, 225, 241, 58,  49,  59,  235, 234, 51,  92,
    241, 75,  120, 26,  8,   36,  238, 241, 33,  192, 170, 136, 138, 57,  87,
    210, 181, 143, 111, 181, 251, 30,  50,  64,  48,  96,  195, 223, 172, 221,
    19,  127, 253, 182, 102, 219, 36,  245, 246, 106, 157, 177, 230, 129, 130,
    253, 51,  91,  214, 35,  221, 43,  174, 7,   185, 169, 92,  126, 52,  160,
    212, 233, 158, 142, 120, 255, 212, 32,  10,  176, 112, 73,  71,  51,  72,
    143, 218, 157, 186, 106, 146, 71,  24,  94,  216, 98,  114, 127, 56,  47,
    38,  35,  63,  141, 193, 82,  107, 240, 39,  154, 28,  134, 32,  96,  16,
    32,  54,  233, 74,  242, 136, 178, 236, 0,   243, 5,   78,  98,  219, 0,
    104, 70,  235, 248, 169, 38,  88,  129, 219, 84,  197, 53,  232, 186, 157,
    6,   24,  161, 86,  118, 85,  227, 72,  215, 30,  64,  236, 224, 234, 168,
    16,  118, 4,   154, 170, 157, 85,  80,  158, 87,  14,  17,  76,  15,  11,
    151, 157, 15,  42,  92,  34,  255, 244, 162, 195, 158, 162, 207, 167, 119,
    9,   218, 218, 148, 33,  54,  131, 66,  125, 12,  141, 245, 162, 229, 134,
    227};

const unsigned char kSampleAuthData[] = {29,  230, 13,  53,  202, 172, 136,
                                         59,  83,  139, 43,  154, 175, 183,
                                         163, 205, 110, 117, 149, 144};

const char kTokenPath[] = ".tpm";
const char kTokenObjectPath[] = "TOK_OBJ";
const char kSampleToken[] = "opencryptoki_sample_token.tgz";
const int kPublicSampleObjects = 3;
const int kPrivateSampleObjects = 2;

string Bytes2String(const unsigned char* bytes, size_t num_bytes) {
  return string(reinterpret_cast<const char*>(bytes), num_bytes);
}

void RunCommand(string command) {
  int status = system(command.c_str());
  ASSERT_EQ(0, WEXITSTATUS(status));
}

// Performs hard-coded transformations as a TPM would do. These match the
// sample token data for this test, they are not useful in general.
bool MockUnbind(int key, const string& input, string* output) {
  map<string, string> transforms;
  string encrypted = Bytes2String(kSampleMasterKeyEncrypted,
                                  arraysize(kSampleMasterKeyEncrypted));
  string decrypted =
      Bytes2String(kSampleMasterKey, arraysize(kSampleMasterKey));
  transforms[encrypted] = decrypted;
  encrypted = Bytes2String(kSampleAuthDataEncrypted,
                           arraysize(kSampleAuthDataEncrypted));
  decrypted = Bytes2String(kSampleAuthData, arraysize(kSampleAuthData));
  transforms[encrypted] = decrypted;

  map<string, string>::iterator iter = transforms.find(input);
  if (iter != transforms.end()) {
    *output = iter->second;
    return true;
  }
  return false;
}

// Creates a very 'nice' object mock.
Object* CreateObjectMock() {
  ObjectMock* o = new ObjectMock();
  o->SetupFake();
  EXPECT_CALL(*o, GetObjectClass()).Times(AnyNumber());
  EXPECT_CALL(*o, SetAttributes(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, FinalizeNewObject()).WillRepeatedly(Return(CKR_OK));
  EXPECT_CALL(*o, Copy(_)).WillRepeatedly(Return(CKR_OK));
  EXPECT_CALL(*o, IsTokenObject()).Times(AnyNumber());
  EXPECT_CALL(*o, IsPrivate()).Times(AnyNumber());
  EXPECT_CALL(*o, IsAttributePresent(_)).Times(AnyNumber());
  EXPECT_CALL(*o, GetAttributeString(_)).Times(AnyNumber());
  EXPECT_CALL(*o, GetAttributeInt(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, GetAttributeBool(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, SetAttributeString(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, SetAttributeInt(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, SetAttributeBool(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, GetAttributeMap()).Times(AnyNumber());
  EXPECT_CALL(*o, set_handle(_)).Times(AnyNumber());
  EXPECT_CALL(*o, set_store_id(_)).Times(AnyNumber());
  EXPECT_CALL(*o, handle()).Times(AnyNumber());
  EXPECT_CALL(*o, store_id()).Times(AnyNumber());
  return o;
}

// A test fixture base class for testing the importer.
class TestImporterBase {
 public:
  TestImporterBase() {
    CHECK(temp_dir_.CreateUniqueTempDir());
    importer_.reset(new OpencryptokiImporter(
        0, temp_dir_.GetPath().Append(kTokenPath), &tpm_, &factory_));
    // Set expectations for the TPM utility mock.
    EXPECT_CALL(tpm_, Unbind(_, _, _)).WillRepeatedly(Invoke(MockUnbind));
    EXPECT_CALL(tpm_, LoadKey(_, _, _, _))
        .WillRepeatedly(DoAll(SetArgPointee<3>(1), Return(true)));
    EXPECT_CALL(tpm_, LoadKeyWithParent(_, _, _, _, _))
        .WillRepeatedly(DoAll(SetArgPointee<4>(1), Return(true)));

    // Set expectations for the factory mock.
    EXPECT_CALL(factory_, CreateObject())
        .WillRepeatedly(Invoke(CreateObjectMock));

    // Set expectations for the object pool mock.
    pool_.SetupFake(0);
    EXPECT_CALL(pool_, Insert(_)).Times(AnyNumber());
    EXPECT_CALL(pool_, Import(_)).Times(AnyNumber());
    EXPECT_CALL(pool_, Find(_, _)).Times(AnyNumber());
    EXPECT_CALL(pool_, SetInternalBlob(3, _)).WillRepeatedly(Return(true));
    EXPECT_CALL(pool_, SetInternalBlob(4, _)).WillRepeatedly(Return(true));
  }

 protected:
  void PrepareSampleToken() {
    CHECK(temp_dir_.IsValid());
    RunCommand(base::StringPrintf("tar -xzf %s -C %s", kSampleToken,
                                  temp_dir_.GetPath().value().c_str()));
  }

  ChapsFactoryMock factory_;
  ObjectPoolMock pool_;
  std::unique_ptr<OpencryptokiImporter> importer_;
  TPMUtilityMock tpm_;
  base::ScopedTempDir temp_dir_;
};

// A function that returns the number of objects expected to be imported.
// Returns -1 if a failure is expected.
struct ModifierResult {
  bool import_public_result;
  bool import_private_result;
  int num_public_objects;
  int num_private_objects;
};
typedef ModifierResult (*ModifierCallback)(const char* object_path);

const ModifierResult kModifierSuccess = {true, true, kPublicSampleObjects,
                                         kPrivateSampleObjects};
const ModifierResult kModifierNone = {true, true, 0, 0};
const ModifierResult kModifierPublicOnly = {true, true, kPublicSampleObjects,
                                            0};
const ModifierResult kModifierOneBadPublic = {
    true, true, kPublicSampleObjects - 1, kPrivateSampleObjects};
const ModifierResult kModifierOneBadPrivate = {true, true, kPublicSampleObjects,
                                               kPrivateSampleObjects - 1};

// A parameterized fixture so we can run the same test(s) with multiple modifier
// functions.
class TestImporterWithModifier
    : public TestImporterBase,
      public testing::TestWithParam<ModifierCallback> {};

// This test attempts to import a sample token after it has been modified by a
// modifier function.
TEST_P(TestImporterWithModifier, ImportSample) {
  PrepareSampleToken();
  FilePath object_path =
      temp_dir_.GetPath().Append(kTokenPath).Append(kTokenObjectPath);
  ModifierCallback modifier = GetParam();
  ModifierResult expected_result = modifier(object_path.value().c_str());
  EXPECT_EQ(expected_result.import_public_result,
            importer_->ImportObjects(&pool_));
  vector<const Object*> objects;
  pool_.Find(NULL, &objects);
  EXPECT_EQ(expected_result.num_public_objects, objects.size());
  EXPECT_EQ(expected_result.import_private_result,
            importer_->FinishImportAsync(&pool_));
  objects.clear();
  pool_.Find(NULL, &objects);
  int total_objects =
      expected_result.num_public_objects + expected_result.num_private_objects;
  EXPECT_EQ(total_objects, objects.size());
}

ModifierResult NoModify(const char* object_path) {
  // If we don't modify anything, the import should succeed.
  return kModifierSuccess;
}

ModifierResult DeleteAll(const char* object_path) {
  FilePath token_path = FilePath(object_path).DirName();
  RunCommand(base::StringPrintf("rm -rf %s", token_path.value().c_str()));
  return kModifierNone;
}

ModifierResult DeleteAllObjectFiles(const char* object_path) {
  RunCommand(base::StringPrintf("rm -f %s/*", object_path));
  return kModifierNone;
}

ModifierResult DeleteMasterKey(const char* object_path) {
  FilePath token_path = FilePath(object_path).DirName();
  RunCommand(
      base::StringPrintf("rm -f %s/MK_PRIVATE", token_path.value().c_str()));
  return kModifierPublicOnly;
}

ModifierResult DeleteObjectIndex(const char* object_path) {
  RunCommand(base::StringPrintf("rm -f %s/OBJ.IDX", object_path));
  return kModifierNone;
}

ModifierResult DeleteAllButIndex(const char* object_path) {
  RunCommand(base::StringPrintf("rm -f %s/*0000", object_path));
  return kModifierNone;
}

ModifierResult DeleteHierarchyFile(const char* object_path) {
  RunCommand(base::StringPrintf("rm -f %s/50000000", object_path));
  return kModifierPublicOnly;
}

ModifierResult TruncateFile0(const char* object_path) {
  RunCommand(base::StringPrintf(":> %s/B0000000", object_path));
  return kModifierOneBadPublic;
}

ModifierResult TruncateFile5(const char* object_path) {
  RunCommand(base::StringPrintf("truncate -s 5 %s/B0000000", object_path));
  return kModifierOneBadPublic;
}

ModifierResult TruncateFile21(const char* object_path) {
  RunCommand(base::StringPrintf("truncate -s 21 %s/B0000000", object_path));
  return kModifierOneBadPublic;
}

ModifierResult TruncateFile80(const char* object_path) {
  RunCommand(base::StringPrintf("truncate -s 80 %s/B0000000", object_path));
  return kModifierOneBadPublic;
}

ModifierResult TruncateEncrypted(const char* object_path) {
  RunCommand(base::StringPrintf("truncate -s 80 %s/C0000000", object_path));
  return kModifierOneBadPrivate;
}

ModifierResult AddNotIndexed(const char* object_path) {
  RunCommand(base::StringPrintf(":> %s/D0000000", object_path));
  return kModifierSuccess;
}

ModifierResult AppendJunk(const char* object_path) {
  RunCommand(base::StringPrintf("head -c 100 < /dev/urandom >> %s/B0000000",
                                object_path));
  return kModifierOneBadPublic;
}

ModifierResult AppendJunkEncrypted(const char* object_path) {
  RunCommand(base::StringPrintf("head -c 100 < /dev/urandom >> %s/C0000000",
                                object_path));
  return kModifierOneBadPrivate;
}

// List of parameterized test cases.
INSTANTIATE_TEST_CASE_P(ModifierTests,
                        TestImporterWithModifier,
                        Values(NoModify,
                               DeleteAll,
                               DeleteAllObjectFiles,
                               DeleteMasterKey,
                               DeleteObjectIndex,
                               DeleteAllButIndex,
                               DeleteHierarchyFile,
                               TruncateFile0,
                               TruncateFile5,
                               TruncateFile21,
                               TruncateFile80,
                               TruncateEncrypted,
                               AddNotIndexed,
                               AppendJunk,
                               AppendJunkEncrypted));

ModifierResult RandomizeFile(const char* object_path) {
  RunCommand(base::StringPrintf("head -c 1000 < /dev/urandom > %s/C0000000",
                                object_path));
  return kModifierOneBadPrivate;
}

ModifierResult RandomizeObjectAttributes(const char* object_path) {
  RunCommand(base::StringPrintf("truncate -s 21 %s/B0000000", object_path));
  RunCommand(base::StringPrintf("head -c 1000 < /dev/urandom >> %s/B0000000",
                                object_path));
  return kModifierOneBadPublic;
}

// List of test cases that involve randomization; these are listed separately
// for easy filtering.
INSTANTIATE_TEST_CASE_P(RandomizedTests,
                        TestImporterWithModifier,
                        Values(RandomizeFile, RandomizeObjectAttributes));
}  // namespace chaps
