// 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 <string>
#include <vector>

#include <base/files/scoped_temp_dir.h>
#include <base/logging.h>
#include <base/memory/scoped_ptr.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::SetArgumentPointee;
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_.path().Append(kTokenPath), &tpm_, &factory_));
    // Set expectations for the TPM utility mock.
    EXPECT_CALL(tpm_, Unbind(_, _, _)).WillRepeatedly(Invoke(MockUnbind));
    EXPECT_CALL(tpm_, LoadKey(_, _, _, _))
        .WillRepeatedly(DoAll(SetArgumentPointee<3>(1), Return(true)));
    EXPECT_CALL(tpm_, LoadKeyWithParent(_, _, _, _, _))
        .WillRepeatedly(DoAll(SetArgumentPointee<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();
    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_.path().value().c_str()));
  }

  ChapsFactoryMock factory_;
  ObjectPoolMock pool_;
  scoped_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_.path().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

int main(int argc, char** argv) {
  ::testing::InitGoogleMock(&argc, argv);
  return RUN_ALL_TESTS();
}
