// Copyright 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cstdio>
#include <memory>
#include <string>
#include <vector>

#include <base/command_line.h>
#include <base/files/file_util.h>
#include <base/strings/string_util.h>
#include <keystore/keymaster_types.h>
#include <keystore/keystore_client_impl.h>

using base::CommandLine;
using keystore::KeystoreClient;

namespace {
using namespace keystore;

struct TestCase {
    std::string name;
    bool required_for_brillo_pts;
    AuthorizationSet parameters;
};

void PrintUsageAndExit() {
    printf("Usage: keystore_client_v2 <command> [options]\n");
    printf("Commands: brillo-platform-test [--prefix=<test_name_prefix>] [--test_for_0_3]\n"
           "          list-brillo-tests\n"
           "          add-entropy --input=<entropy>\n"
           "          generate --name=<key_name>\n"
           "          get-chars --name=<key_name>\n"
           "          export --name=<key_name>\n"
           "          delete --name=<key_name>\n"
           "          delete-all\n"
           "          exists --name=<key_name>\n"
           "          list [--prefix=<key_name_prefix>]\n"
           "          sign-verify --name=<key_name>\n"
           "          [en|de]crypt --name=<key_name> --in=<file> --out=<file>\n");
    exit(1);
}

std::unique_ptr<KeystoreClient> CreateKeystoreInstance() {
    return std::unique_ptr<KeystoreClient>(
        static_cast<KeystoreClient*>(new keystore::KeystoreClientImpl));
}

void PrintTags(const AuthorizationSet& parameters) {
    for (auto iter = parameters.begin(); iter != parameters.end(); ++iter) {
        auto tag_str = toString(iter->tag);
        printf("  %s\n", tag_str.c_str());
    }
}

void PrintKeyCharacteristics(const AuthorizationSet& hardware_enforced_characteristics,
                             const AuthorizationSet& software_enforced_characteristics) {
    printf("Hardware:\n");
    PrintTags(hardware_enforced_characteristics);
    printf("Software:\n");
    PrintTags(software_enforced_characteristics);
}

bool TestKey(const std::string& name, bool required, const AuthorizationSet& parameters) {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    AuthorizationSet hardware_enforced_characteristics;
    AuthorizationSet software_enforced_characteristics;
    auto result = keystore->generateKey("tmp", parameters, &hardware_enforced_characteristics,
                                        &software_enforced_characteristics);
    const char kBoldRedAbort[] = "\033[1;31mABORT\033[0m";
    if (!result.isOk()) {
        LOG(ERROR) << "Failed to generate key: " << result;
        printf("[%s] %s\n", kBoldRedAbort, name.c_str());
        return false;
    }
    result = keystore->deleteKey("tmp");
    if (!result.isOk()) {
        LOG(ERROR) << "Failed to delete key: " << result;
        printf("[%s] %s\n", kBoldRedAbort, name.c_str());
        return false;
    }
    printf("===============================================================\n");
    printf("%s Key Characteristics:\n", name.c_str());
    PrintKeyCharacteristics(hardware_enforced_characteristics, software_enforced_characteristics);
    bool hardware_backed = (hardware_enforced_characteristics.size() > 0);
    if (software_enforced_characteristics.GetTagCount(TAG_ALGORITHM) > 0 ||
        software_enforced_characteristics.GetTagCount(TAG_KEY_SIZE) > 0 ||
        software_enforced_characteristics.GetTagCount(TAG_RSA_PUBLIC_EXPONENT) > 0) {
        VLOG(1) << "Hardware-backed key but required characteristics enforced in software.";
        hardware_backed = false;
    }
    const char kBoldRedFail[] = "\033[1;31mFAIL\033[0m";
    const char kBoldGreenPass[] = "\033[1;32mPASS\033[0m";
    const char kBoldYellowWarn[] = "\033[1;33mWARN\033[0m";
    printf("[%s] %s\n",
           hardware_backed ? kBoldGreenPass : (required ? kBoldRedFail : kBoldYellowWarn),
           name.c_str());

    return (hardware_backed || !required);
}

AuthorizationSet GetRSASignParameters(uint32_t key_size, bool sha256_only) {
    AuthorizationSetBuilder parameters;
    parameters.RsaSigningKey(key_size, 65537)
        .Digest(Digest::SHA_2_256)
        .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
        .Padding(PaddingMode::RSA_PSS)
        .Authorization(TAG_NO_AUTH_REQUIRED);
    if (!sha256_only) {
        parameters.Digest(Digest::SHA_2_224).Digest(Digest::SHA_2_384).Digest(Digest::SHA_2_512);
    }
    return parameters;
}

AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) {
    AuthorizationSetBuilder parameters;
    parameters.RsaEncryptionKey(key_size, 65537)
        .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
        .Padding(PaddingMode::RSA_OAEP)
        .Authorization(TAG_NO_AUTH_REQUIRED);
    return parameters;
}

AuthorizationSet GetECDSAParameters(uint32_t key_size, bool sha256_only) {
    AuthorizationSetBuilder parameters;
    parameters.EcdsaSigningKey(key_size)
        .Digest(Digest::SHA_2_256)
        .Authorization(TAG_NO_AUTH_REQUIRED);
    if (!sha256_only) {
        parameters.Digest(Digest::SHA_2_224).Digest(Digest::SHA_2_384).Digest(Digest::SHA_2_512);
    }
    return parameters;
}

AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) {
    AuthorizationSetBuilder parameters;
    parameters.AesEncryptionKey(key_size).Authorization(TAG_NO_AUTH_REQUIRED);
    if (with_gcm_mode) {
        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
            .Authorization(TAG_MIN_MAC_LENGTH, 128);
    } else {
        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CTR);
        parameters.Padding(PaddingMode::NONE);
    }
    return parameters;
}

AuthorizationSet GetHMACParameters(uint32_t key_size, Digest digest) {
    AuthorizationSetBuilder parameters;
    parameters.HmacKey(key_size)
        .Digest(digest)
        .Authorization(TAG_MIN_MAC_LENGTH, 224)
        .Authorization(TAG_NO_AUTH_REQUIRED);
    return parameters;
}

std::vector<TestCase> GetTestCases() {
    TestCase test_cases[] = {
        {"RSA-2048 Sign", true, GetRSASignParameters(2048, true)},
        {"RSA-2048 Sign (more digests)", false, GetRSASignParameters(2048, false)},
        {"RSA-3072 Sign", false, GetRSASignParameters(3072, false)},
        {"RSA-4096 Sign", false, GetRSASignParameters(4096, false)},
        {"RSA-2048 Encrypt", true, GetRSAEncryptParameters(2048)},
        {"RSA-3072 Encrypt", false, GetRSAEncryptParameters(3072)},
        {"RSA-4096 Encrypt", false, GetRSAEncryptParameters(4096)},
        {"ECDSA-P256 Sign", true, GetECDSAParameters(256, true)},
        {"ECDSA-P256 Sign (more digests)", false, GetECDSAParameters(256, false)},
        {"ECDSA-P224 Sign", false, GetECDSAParameters(224, false)},
        {"ECDSA-P384 Sign", false, GetECDSAParameters(384, false)},
        {"ECDSA-P521 Sign", false, GetECDSAParameters(521, false)},
        {"AES-128", true, GetAESParameters(128, false)},
        {"AES-256", true, GetAESParameters(256, false)},
        {"AES-128-GCM", false, GetAESParameters(128, true)},
        {"AES-256-GCM", false, GetAESParameters(256, true)},
        {"HMAC-SHA256-16", true, GetHMACParameters(16, Digest::SHA_2_256)},
        {"HMAC-SHA256-32", true, GetHMACParameters(32, Digest::SHA_2_256)},
        {"HMAC-SHA256-64", false, GetHMACParameters(64, Digest::SHA_2_256)},
        {"HMAC-SHA224-32", false, GetHMACParameters(32, Digest::SHA_2_224)},
        {"HMAC-SHA384-32", false, GetHMACParameters(32, Digest::SHA_2_384)},
        {"HMAC-SHA512-32", false, GetHMACParameters(32, Digest::SHA_2_512)},
    };
    return std::vector<TestCase>(&test_cases[0], &test_cases[arraysize(test_cases)]);
}

int BrilloPlatformTest(const std::string& prefix, bool test_for_0_3) {
    const char kBoldYellowWarning[] = "\033[1;33mWARNING\033[0m";
    if (test_for_0_3) {
        printf("%s: Testing for keymaster v0.3. "
               "This does not meet Brillo requirements.\n",
               kBoldYellowWarning);
    }
    int test_count = 0;
    int fail_count = 0;
    std::vector<TestCase> test_cases = GetTestCases();
    for (const auto& test_case : test_cases) {
        if (!prefix.empty() &&
            !base::StartsWith(test_case.name, prefix, base::CompareCase::SENSITIVE)) {
            continue;
        }
        if (test_for_0_3 &&
            (base::StartsWith(test_case.name, "AES", base::CompareCase::SENSITIVE) ||
             base::StartsWith(test_case.name, "HMAC", base::CompareCase::SENSITIVE))) {
            continue;
        }
        ++test_count;
        if (!TestKey(test_case.name, test_case.required_for_brillo_pts, test_case.parameters)) {
            VLOG(1) << "Test failed: " << test_case.name;
            ++fail_count;
        }
    }
    return fail_count;
}

int ListTestCases() {
    const char kBoldGreenRequired[] = "\033[1;32mREQUIRED\033[0m";
    const char kBoldYellowRecommended[] = "\033[1;33mRECOMMENDED\033[0m";
    std::vector<TestCase> test_cases = GetTestCases();
    for (const auto& test_case : test_cases) {
        printf("%s : %s\n", test_case.name.c_str(),
               test_case.required_for_brillo_pts ? kBoldGreenRequired : kBoldYellowRecommended);
    }
    return 0;
}

std::string ReadFile(const std::string& filename) {
    std::string content;
    base::FilePath path(filename);
    if (!base::ReadFileToString(path, &content)) {
        printf("Failed to read file: %s\n", filename.c_str());
        exit(1);
    }
    return content;
}

void WriteFile(const std::string& filename, const std::string& content) {
    base::FilePath path(filename);
    int size = content.size();
    if (base::WriteFile(path, content.data(), size) != size) {
        printf("Failed to write file: %s\n", filename.c_str());
        exit(1);
    }
}

int AddEntropy(const std::string& input) {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    int32_t result = keystore->addRandomNumberGeneratorEntropy(input);
    printf("AddEntropy: %d\n", result);
    return result;
}

int GenerateKey(const std::string& name) {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    AuthorizationSetBuilder params;
    params.RsaSigningKey(2048, 65537)
        .Digest(Digest::SHA_2_224)
        .Digest(Digest::SHA_2_256)
        .Digest(Digest::SHA_2_384)
        .Digest(Digest::SHA_2_512)
        .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
        .Padding(PaddingMode::RSA_PSS)
        .Authorization(TAG_NO_AUTH_REQUIRED);
    AuthorizationSet hardware_enforced_characteristics;
    AuthorizationSet software_enforced_characteristics;
    auto result = keystore->generateKey(name, params, &hardware_enforced_characteristics,
                                        &software_enforced_characteristics);
    printf("GenerateKey: %d\n", int32_t(result));
    if (result.isOk()) {
        PrintKeyCharacteristics(hardware_enforced_characteristics,
                                software_enforced_characteristics);
    }
    return result;
}

int GetCharacteristics(const std::string& name) {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    AuthorizationSet hardware_enforced_characteristics;
    AuthorizationSet software_enforced_characteristics;
    auto result = keystore->getKeyCharacteristics(name, &hardware_enforced_characteristics,
                                                  &software_enforced_characteristics);
    printf("GetCharacteristics: %d\n", int32_t(result));
    if (result.isOk()) {
        PrintKeyCharacteristics(hardware_enforced_characteristics,
                                software_enforced_characteristics);
    }
    return result;
}

int ExportKey(const std::string& name) {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    std::string data;
    int32_t result = keystore->exportKey(KeyFormat::X509, name, &data);
    printf("ExportKey: %d (%zu)\n", result, data.size());
    return result;
}

int DeleteKey(const std::string& name) {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    int32_t result = keystore->deleteKey(name);
    printf("DeleteKey: %d\n", result);
    return result;
}

int DeleteAllKeys() {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    int32_t result = keystore->deleteAllKeys();
    printf("DeleteAllKeys: %d\n", result);
    return result;
}

int DoesKeyExist(const std::string& name) {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    printf("DoesKeyExist: %s\n", keystore->doesKeyExist(name) ? "yes" : "no");
    return 0;
}

int List(const std::string& prefix) {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    std::vector<std::string> key_list;
    if (!keystore->listKeys(prefix, &key_list)) {
        printf("ListKeys failed.\n");
        return 1;
    }
    printf("Keys:\n");
    for (const auto& key_name : key_list) {
        printf("  %s\n", key_name.c_str());
    }
    return 0;
}

int SignAndVerify(const std::string& name) {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    AuthorizationSetBuilder sign_params;
    sign_params.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
    sign_params.Digest(Digest::SHA_2_256);
    AuthorizationSet output_params;
    uint64_t handle;
    auto result =
        keystore->beginOperation(KeyPurpose::SIGN, name, sign_params, &output_params, &handle);
    if (!result.isOk()) {
        printf("Sign: BeginOperation failed: %d\n", int32_t(result));
        return result;
    }
    AuthorizationSet empty_params;
    size_t num_input_bytes_consumed;
    std::string output_data;
    result = keystore->updateOperation(handle, empty_params, "data_to_sign",
                                       &num_input_bytes_consumed, &output_params, &output_data);
    if (!result.isOk()) {
        printf("Sign: UpdateOperation failed: %d\n", int32_t(result));
        return result;
    }
    result = keystore->finishOperation(handle, empty_params, std::string() /*signature_to_verify*/,
                                       &output_params, &output_data);
    if (!result.isOk()) {
        printf("Sign: FinishOperation failed: %d\n", int32_t(result));
        return result;
    }
    printf("Sign: %zu bytes.\n", output_data.size());
    // We have a signature, now verify it.
    std::string signature_to_verify = output_data;
    output_data.clear();
    result =
        keystore->beginOperation(KeyPurpose::VERIFY, name, sign_params, &output_params, &handle);
    if (!result.isOk()) {
        printf("Verify: BeginOperation failed: %d\n", int32_t(result));
        return result;
    }
    result = keystore->updateOperation(handle, empty_params, "data_to_sign",
                                       &num_input_bytes_consumed, &output_params, &output_data);
    if (!result.isOk()) {
        printf("Verify: UpdateOperation failed: %d\n", int32_t(result));
        return result;
    }
    result = keystore->finishOperation(handle, empty_params, signature_to_verify, &output_params,
                                       &output_data);
    if (result == ErrorCode::VERIFICATION_FAILED) {
        printf("Verify: Failed to verify signature.\n");
        return result;
    }
    if (!result.isOk()) {
        printf("Verify: FinishOperation failed: %d\n", int32_t(result));
        return result;
    }
    printf("Verify: OK\n");
    return 0;
}

int Encrypt(const std::string& key_name, const std::string& input_filename,
            const std::string& output_filename) {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    std::string input = ReadFile(input_filename);
    std::string output;
    if (!keystore->encryptWithAuthentication(key_name, input, &output)) {
        printf("EncryptWithAuthentication failed.\n");
        return 1;
    }
    WriteFile(output_filename, output);
    return 0;
}

int Decrypt(const std::string& key_name, const std::string& input_filename,
            const std::string& output_filename) {
    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
    std::string input = ReadFile(input_filename);
    std::string output;
    if (!keystore->decryptWithAuthentication(key_name, input, &output)) {
        printf("DecryptWithAuthentication failed.\n");
        return 1;
    }
    WriteFile(output_filename, output);
    return 0;
}

}  // namespace

int main(int argc, char** argv) {
    CommandLine::Init(argc, argv);
    CommandLine* command_line = CommandLine::ForCurrentProcess();
    CommandLine::StringVector args = command_line->GetArgs();
    if (args.empty()) {
        PrintUsageAndExit();
    }
    if (args[0] == "brillo-platform-test") {
        return BrilloPlatformTest(command_line->GetSwitchValueASCII("prefix"),
                                  command_line->HasSwitch("test_for_0_3"));
    } else if (args[0] == "list-brillo-tests") {
        return ListTestCases();
    } else if (args[0] == "add-entropy") {
        return AddEntropy(command_line->GetSwitchValueASCII("input"));
    } else if (args[0] == "generate") {
        return GenerateKey(command_line->GetSwitchValueASCII("name"));
    } else if (args[0] == "get-chars") {
        return GetCharacteristics(command_line->GetSwitchValueASCII("name"));
    } else if (args[0] == "export") {
        return ExportKey(command_line->GetSwitchValueASCII("name"));
    } else if (args[0] == "delete") {
        return DeleteKey(command_line->GetSwitchValueASCII("name"));
    } else if (args[0] == "delete-all") {
        return DeleteAllKeys();
    } else if (args[0] == "exists") {
        return DoesKeyExist(command_line->GetSwitchValueASCII("name"));
    } else if (args[0] == "list") {
        return List(command_line->GetSwitchValueASCII("prefix"));
    } else if (args[0] == "sign-verify") {
        return SignAndVerify(command_line->GetSwitchValueASCII("name"));
    } else if (args[0] == "encrypt") {
        return Encrypt(command_line->GetSwitchValueASCII("name"),
                       command_line->GetSwitchValueASCII("in"),
                       command_line->GetSwitchValueASCII("out"));
    } else if (args[0] == "decrypt") {
        return Decrypt(command_line->GetSwitchValueASCII("name"),
                       command_line->GetSwitchValueASCII("in"),
                       command_line->GetSwitchValueASCII("out"));
    } else {
        PrintUsageAndExit();
    }
    return 0;
}
