// 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
