main.cc revision bc0c74963418442991072b2c87baec839eec9c20
16bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen// Copyright 2014 The Chromium OS Authors. All rights reserved. 26bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen// Use of this source code is governed by a BSD-style license that can be 36bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen// found in the LICENSE file. 46bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen 50752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <stdio.h> 60752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <sysexits.h> 70752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 845fc1234b4f1a1c1cfdd44774350a70b26b9b630Alex Vakulenko#include <memory> 9b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahn#include <string> 1045fc1234b4f1a1c1cfdd44774350a70b26b9b630Alex Vakulenko 110752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <base/command_line.h> 122e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn#include <base/files/file_util.h> 130752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <base/message_loop/message_loop.h> 140752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <chromeos/bind_lambda.h> 150752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <chromeos/daemons/daemon.h> 160752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <chromeos/syslog_logging.h> 170752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 18b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahn#include "attestation/client/dbus_proxy.h" 19b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahn#include "attestation/common/attestation_ca.pb.h" 202e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn#include "attestation/common/crypto_utility_impl.h" 21b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahn#include "attestation/common/interface.pb.h" 226bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen 230752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnnamespace attestation { 240752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 2562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahnconst char kCreateAndCertifyCommand[] = "create_and_certify"; 260752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnconst char kCreateCommand[] = "create"; 276222defa52eb13c0d90673f642f2647f7753478bDarren Krahnconst char kInfoCommand[] = "info"; 28cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahnconst char kEndorsementCommand[] = "endorsement"; 29566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahnconst char kAttestationKeyCommand[] = "attestation_key"; 302e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahnconst char kActivateCommand[] = "activate"; 312e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahnconst char kEncryptForActivateCommand[] = "encrypt_for_activate"; 32bc0c74963418442991072b2c87baec839eec9c20Darren Krahnconst char kEncryptCommand[] = "encrypt"; 33bc0c74963418442991072b2c87baec839eec9c20Darren Krahnconst char kDecryptCommand[] = "decrypt"; 340752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnconst char kUsage[] = R"( 350752bd25ba9f45c07bc989d42bf5272133a85afaDarren KrahnUsage: attestation_client <command> [<args>] 360752bd25ba9f45c07bc989d42bf5272133a85afaDarren KrahnCommands: 3762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn create_and_certify [--user=<email>] [--label=<keylabel>] 3862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Creates a key and requests certification by the Google Attestation CA. 3962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn This is the default command. 40bc0c74963418442991072b2c87baec839eec9c20Darren Krahn create [--user=<email>] [--label=<keylabel] [--usage=sign|decrypt] 4162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Creates a certifiable key. 422e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 4362c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn info [--user=<email>] [--label=<keylabel>] 4462c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Prints info about a key. 4562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn endorsement 4662c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Prints info about the TPM endorsement. 4762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn attestation_key 4862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Prints info about the TPM attestation key. 492e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 5062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn activate --input=<input_file> 5162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Activates an attestation key using the encrypted credential in 5262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn |input_file|. 5362c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn encrypt_for_activate --input=<input_file> --output=<output_file> 5462c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Encrypts the content of |input_file| as required by the TPM for activating 5562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn an attestation key. The result is written to |output_file|. 56bc0c74963418442991072b2c87baec839eec9c20Darren Krahn 57bc0c74963418442991072b2c87baec839eec9c20Darren Krahn encrypt [--user=<email>] [--label=<keylabel>] --input=<input_file> 58bc0c74963418442991072b2c87baec839eec9c20Darren Krahn --output=<output_file> 59bc0c74963418442991072b2c87baec839eec9c20Darren Krahn Encrypts the content of |input_file| as required by the TPM for a decrypt 60bc0c74963418442991072b2c87baec839eec9c20Darren Krahn operation. The result is written to |output_file|. 61bc0c74963418442991072b2c87baec839eec9c20Darren Krahn decrypt [--user=<email>] [--label=<keylabel>] --input=<input_file> 62bc0c74963418442991072b2c87baec839eec9c20Darren Krahn Decrypts the content of |input_file|. 630752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn)"; 640752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 650752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn// The Daemon class works well as a client loop as well. 660752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnusing ClientLoopBase = chromeos::Daemon; 670752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 680752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnclass ClientLoop : public ClientLoopBase { 690752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn public: 700752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn ClientLoop() = default; 710752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn ~ClientLoop() override = default; 720752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 730752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn protected: 740752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn int OnInit() override { 750752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn int exit_code = ClientLoopBase::OnInit(); 760752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn if (exit_code != EX_OK) { 770752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return exit_code; 780752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 790752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn attestation_.reset(new attestation::DBusProxy()); 800752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn if (!attestation_->Initialize()) { 810752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return EX_UNAVAILABLE; 820752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 830752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn exit_code = ScheduleCommand(); 840752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn if (exit_code == EX_USAGE) { 850752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn printf("%s", kUsage); 860752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 870752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return exit_code; 880752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 890752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 900752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn void OnShutdown(int* exit_code) override { 910752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn attestation_.reset(); 920752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn ClientLoopBase::OnShutdown(exit_code); 93b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahn } 940752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 950752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn private: 960752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn // Posts tasks according to the command line options. 970752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn int ScheduleCommand() { 980752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn base::Closure task; 9959d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 10059d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn const auto& args = command_line->GetArgs(); 101566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn if (command_line->HasSwitch("help") || command_line->HasSwitch("h") || 102bc0c74963418442991072b2c87baec839eec9c20Darren Krahn (!args.empty() && args.front() == "help")) { 103566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn return EX_USAGE; 104566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 10562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn if (args.empty() || args.front() == kCreateAndCertifyCommand) { 1060752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn task = base::Bind(&ClientLoop::CallCreateGoogleAttestedKey, 10759d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn weak_factory_.GetWeakPtr(), 10859d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn command_line->GetSwitchValueASCII("label"), 10959d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn command_line->GetSwitchValueASCII("user")); 11062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn } else if (args.front() == kCreateCommand) { 111bc0c74963418442991072b2c87baec839eec9c20Darren Krahn std::string usage_str = command_line->GetSwitchValueASCII("usage"); 112bc0c74963418442991072b2c87baec839eec9c20Darren Krahn KeyUsage usage; 113bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (usage_str.empty() || usage_str == "sign") { 114bc0c74963418442991072b2c87baec839eec9c20Darren Krahn usage = KEY_USAGE_SIGN; 115bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } else if (usage_str == "decrypt") { 116bc0c74963418442991072b2c87baec839eec9c20Darren Krahn usage = KEY_USAGE_DECRYPT; 117bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } else { 118bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return EX_USAGE; 119bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 12062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn task = base::Bind(&ClientLoop::CallCreateCertifiableKey, 12162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn weak_factory_.GetWeakPtr(), 12262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn command_line->GetSwitchValueASCII("label"), 123bc0c74963418442991072b2c87baec839eec9c20Darren Krahn command_line->GetSwitchValueASCII("user"), 124bc0c74963418442991072b2c87baec839eec9c20Darren Krahn usage); 1256222defa52eb13c0d90673f642f2647f7753478bDarren Krahn } else if (args.front() == kInfoCommand) { 1266222defa52eb13c0d90673f642f2647f7753478bDarren Krahn task = base::Bind(&ClientLoop::CallGetKeyInfo, 1276222defa52eb13c0d90673f642f2647f7753478bDarren Krahn weak_factory_.GetWeakPtr(), 1286222defa52eb13c0d90673f642f2647f7753478bDarren Krahn command_line->GetSwitchValueASCII("label"), 1296222defa52eb13c0d90673f642f2647f7753478bDarren Krahn command_line->GetSwitchValueASCII("user")); 130cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn } else if (args.front() == kEndorsementCommand) { 131cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn task = base::Bind(&ClientLoop::CallGetEndorsementInfo, 132cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn weak_factory_.GetWeakPtr()); 133566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } else if (args.front() == kAttestationKeyCommand) { 134566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn task = base::Bind(&ClientLoop::CallGetAttestationKeyInfo, 135566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn weak_factory_.GetWeakPtr()); 1362e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } else if (args.front() == kActivateCommand) { 1372e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!command_line->HasSwitch("input")) { 1382e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return EX_USAGE; 1392e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 1402e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn std::string input; 1412e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::FilePath filename(command_line->GetSwitchValueASCII("input")); 1422e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!base::ReadFileToString(filename, &input)) { 1432e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn LOG(ERROR) << "Failed to read file: " << filename.value(); 1442e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return EX_NOINPUT; 1452e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 1462e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn task = base::Bind(&ClientLoop::CallActivateAttestationKey, 1472e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn weak_factory_.GetWeakPtr(), 1482e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn input); 1492e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } else if (args.front() == kEncryptForActivateCommand) { 1502e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!command_line->HasSwitch("input") || 1512e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn !command_line->HasSwitch("output")) { 1522e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return EX_USAGE; 1532e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 1542e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn std::string input; 1552e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::FilePath filename(command_line->GetSwitchValueASCII("input")); 1562e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!base::ReadFileToString(filename, &input)) { 1572e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn LOG(ERROR) << "Failed to read file: " << filename.value(); 1582e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return EX_NOINPUT; 1592e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 1602e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn task = base::Bind(&ClientLoop::EncryptForActivate, 1612e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn weak_factory_.GetWeakPtr(), 1622e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn input); 163bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } else if (args.front() == kEncryptCommand) { 164bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!command_line->HasSwitch("input") || 165bc0c74963418442991072b2c87baec839eec9c20Darren Krahn !command_line->HasSwitch("output")) { 166bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return EX_USAGE; 167bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 168bc0c74963418442991072b2c87baec839eec9c20Darren Krahn std::string input; 169bc0c74963418442991072b2c87baec839eec9c20Darren Krahn base::FilePath filename(command_line->GetSwitchValueASCII("input")); 170bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!base::ReadFileToString(filename, &input)) { 171bc0c74963418442991072b2c87baec839eec9c20Darren Krahn LOG(ERROR) << "Failed to read file: " << filename.value(); 172bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return EX_NOINPUT; 173bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 174bc0c74963418442991072b2c87baec839eec9c20Darren Krahn task = base::Bind(&ClientLoop::Encrypt, 175bc0c74963418442991072b2c87baec839eec9c20Darren Krahn weak_factory_.GetWeakPtr(), 176bc0c74963418442991072b2c87baec839eec9c20Darren Krahn command_line->GetSwitchValueASCII("label"), 177bc0c74963418442991072b2c87baec839eec9c20Darren Krahn command_line->GetSwitchValueASCII("user"), 178bc0c74963418442991072b2c87baec839eec9c20Darren Krahn input); 179bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } else if (args.front() == kDecryptCommand) { 180bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!command_line->HasSwitch("input")) { 181bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return EX_USAGE; 182bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 183bc0c74963418442991072b2c87baec839eec9c20Darren Krahn std::string input; 184bc0c74963418442991072b2c87baec839eec9c20Darren Krahn base::FilePath filename(command_line->GetSwitchValueASCII("input")); 185bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!base::ReadFileToString(filename, &input)) { 186bc0c74963418442991072b2c87baec839eec9c20Darren Krahn LOG(ERROR) << "Failed to read file: " << filename.value(); 187bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return EX_NOINPUT; 188bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 189bc0c74963418442991072b2c87baec839eec9c20Darren Krahn task = base::Bind(&ClientLoop::CallDecrypt, 190bc0c74963418442991072b2c87baec839eec9c20Darren Krahn weak_factory_.GetWeakPtr(), 191bc0c74963418442991072b2c87baec839eec9c20Darren Krahn command_line->GetSwitchValueASCII("label"), 192bc0c74963418442991072b2c87baec839eec9c20Darren Krahn command_line->GetSwitchValueASCII("user"), 193bc0c74963418442991072b2c87baec839eec9c20Darren Krahn input); 1940752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } else { 1950752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return EX_USAGE; 1960752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 1970752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn base::MessageLoop::current()->PostTask(FROM_HERE, task); 1980752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return EX_OK; 1990752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 2000752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 2016222defa52eb13c0d90673f642f2647f7753478bDarren Krahn template <typename ProtobufType> 2026222defa52eb13c0d90673f642f2647f7753478bDarren Krahn void PrintReplyAndQuit(const ProtobufType& reply) { 203b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn reply.PrintDebugString(); 2040752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn Quit(); 2050752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 2060752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 2072e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn void WriteOutput(const std::string& output) { 2082e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::FilePath filename(base::CommandLine::ForCurrentProcess()-> 2092e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn GetSwitchValueASCII("output")); 2102e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (base::WriteFile(filename, output.data(), output.size()) != 2112e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn static_cast<int>(output.size())) { 2122e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn LOG(ERROR) << "Failed to write file: " << filename.value(); 2132e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn QuitWithExitCode(EX_IOERR); 2142e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 2152e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 2162e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 21759d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn void CallCreateGoogleAttestedKey(const std::string& label, 21859d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn const std::string& username) { 219b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn CreateGoogleAttestedKeyRequest request; 220b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.set_key_label(label); 221b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.set_key_type(KEY_TYPE_RSA); 222b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.set_key_usage(KEY_USAGE_SIGN); 223b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE); 224b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.set_username(username); 2250752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn attestation_->CreateGoogleAttestedKey( 226b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request, 2276222defa52eb13c0d90673f642f2647f7753478bDarren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<CreateGoogleAttestedKeyReply>, 2286222defa52eb13c0d90673f642f2647f7753478bDarren Krahn weak_factory_.GetWeakPtr())); 2296222defa52eb13c0d90673f642f2647f7753478bDarren Krahn } 2306222defa52eb13c0d90673f642f2647f7753478bDarren Krahn 2316222defa52eb13c0d90673f642f2647f7753478bDarren Krahn void CallGetKeyInfo(const std::string& label, const std::string& username) { 2326222defa52eb13c0d90673f642f2647f7753478bDarren Krahn GetKeyInfoRequest request; 2336222defa52eb13c0d90673f642f2647f7753478bDarren Krahn request.set_key_label(label); 2346222defa52eb13c0d90673f642f2647f7753478bDarren Krahn request.set_username(username); 2356222defa52eb13c0d90673f642f2647f7753478bDarren Krahn attestation_->GetKeyInfo( 2366222defa52eb13c0d90673f642f2647f7753478bDarren Krahn request, 2376222defa52eb13c0d90673f642f2647f7753478bDarren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<GetKeyInfoReply>, 2380752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn weak_factory_.GetWeakPtr())); 23945fc1234b4f1a1c1cfdd44774350a70b26b9b630Alex Vakulenko } 2400752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 241cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn void CallGetEndorsementInfo() { 242cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn GetEndorsementInfoRequest request; 243cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn request.set_key_type(KEY_TYPE_RSA); 244cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn attestation_->GetEndorsementInfo( 245cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn request, 246cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<GetEndorsementInfoReply>, 247cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn weak_factory_.GetWeakPtr())); 248cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn } 249cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn 250566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn void CallGetAttestationKeyInfo() { 251566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn GetAttestationKeyInfoRequest request; 252566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn request.set_key_type(KEY_TYPE_RSA); 253566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn attestation_->GetAttestationKeyInfo( 254566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn request, 255566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<GetAttestationKeyInfoReply>, 256566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn weak_factory_.GetWeakPtr())); 257566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 258566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn 2592e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn void CallActivateAttestationKey(const std::string& input) { 2602e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn ActivateAttestationKeyRequest request; 2612e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.set_key_type(KEY_TYPE_RSA); 2622e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.mutable_encrypted_certificate()->ParseFromString(input); 2632e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.set_save_certificate(true); 2642e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn attestation_->ActivateAttestationKey( 2652e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request, 2662e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<ActivateAttestationKeyReply>, 2672e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn weak_factory_.GetWeakPtr())); 2682e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 2692e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 2702e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn void EncryptForActivate(const std::string& input) { 2712e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn GetEndorsementInfoRequest request; 2722e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.set_key_type(KEY_TYPE_RSA); 2732e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn attestation_->GetEndorsementInfo( 2742e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request, 2752e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::Bind(&ClientLoop::EncryptForActivate2, 2762e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn weak_factory_.GetWeakPtr(), 2772e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn input)); 2782e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 2792e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 2802e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn void EncryptForActivate2(const std::string& input, 2812e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const GetEndorsementInfoReply& endorsement_info) { 2822e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (endorsement_info.status() != STATUS_SUCCESS) { 2832e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn PrintReplyAndQuit(endorsement_info); 2842e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 2852e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn GetAttestationKeyInfoRequest request; 2862e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.set_key_type(KEY_TYPE_RSA); 2872e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn attestation_->GetAttestationKeyInfo( 2882e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request, 2892e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::Bind(&ClientLoop::EncryptForActivate3, 2902e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn weak_factory_.GetWeakPtr(), 2912e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn input, 2922e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn endorsement_info)); 2932e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 2942e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 2952e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn void EncryptForActivate3( 2962e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const std::string& input, 2972e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const GetEndorsementInfoReply& endorsement_info, 2982e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const GetAttestationKeyInfoReply& attestation_key_info) { 2992e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (attestation_key_info.status() != STATUS_SUCCESS) { 3002e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn PrintReplyAndQuit(attestation_key_info); 3012e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3022e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn CryptoUtilityImpl crypto(nullptr); 3032e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn EncryptedIdentityCredential encrypted; 3042e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!crypto.EncryptIdentityCredential( 3052e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn input, 3062e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn endorsement_info.ek_public_key(), 3072e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn attestation_key_info.public_key_tpm_format(), 3082e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn &encrypted)) { 3092e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn QuitWithExitCode(EX_SOFTWARE); 3102e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3112e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn std::string output; 3122e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn encrypted.SerializeToString(&output); 3132e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn WriteOutput(output); 3142e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn Quit(); 3152e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3162e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 31762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn void CallCreateCertifiableKey(const std::string& label, 318bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const std::string& username, 319bc0c74963418442991072b2c87baec839eec9c20Darren Krahn KeyUsage usage) { 32062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn CreateCertifiableKeyRequest request; 32162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn request.set_key_label(label); 32262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn request.set_username(username); 323bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_key_type(KEY_TYPE_RSA); 324bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_key_usage(usage); 32562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn attestation_->CreateCertifiableKey( 32662c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn request, 32762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<CreateCertifiableKeyReply>, 32862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn weak_factory_.GetWeakPtr())); 32962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn } 33062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn 331bc0c74963418442991072b2c87baec839eec9c20Darren Krahn void Encrypt(const std::string& label, 332bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const std::string& username, 333bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const std::string& input) { 334bc0c74963418442991072b2c87baec839eec9c20Darren Krahn GetKeyInfoRequest request; 335bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_key_label(label); 336bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_username(username); 337bc0c74963418442991072b2c87baec839eec9c20Darren Krahn attestation_->GetKeyInfo(request, base::Bind(&ClientLoop::Encrypt2, 338bc0c74963418442991072b2c87baec839eec9c20Darren Krahn weak_factory_.GetWeakPtr(), 339bc0c74963418442991072b2c87baec839eec9c20Darren Krahn input)); 340bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 341bc0c74963418442991072b2c87baec839eec9c20Darren Krahn 342bc0c74963418442991072b2c87baec839eec9c20Darren Krahn void Encrypt2(const std::string& input, 343bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const GetKeyInfoReply& key_info) { 344bc0c74963418442991072b2c87baec839eec9c20Darren Krahn CryptoUtilityImpl crypto(nullptr); 345bc0c74963418442991072b2c87baec839eec9c20Darren Krahn std::string output; 346bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!crypto.EncryptForUnbind(key_info.public_key(), input, &output)) { 347bc0c74963418442991072b2c87baec839eec9c20Darren Krahn QuitWithExitCode(EX_SOFTWARE); 348bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 349bc0c74963418442991072b2c87baec839eec9c20Darren Krahn WriteOutput(output); 350bc0c74963418442991072b2c87baec839eec9c20Darren Krahn Quit(); 351bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 352bc0c74963418442991072b2c87baec839eec9c20Darren Krahn 353bc0c74963418442991072b2c87baec839eec9c20Darren Krahn void CallDecrypt(const std::string& label, 354bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const std::string& username, 355bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const std::string& input) { 356bc0c74963418442991072b2c87baec839eec9c20Darren Krahn DecryptRequest request; 357bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_key_label(label); 358bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_username(username); 359bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_encrypted_data(input); 360bc0c74963418442991072b2c87baec839eec9c20Darren Krahn attestation_->Decrypt( 361bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request, 362bc0c74963418442991072b2c87baec839eec9c20Darren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<DecryptReply>, 363bc0c74963418442991072b2c87baec839eec9c20Darren Krahn weak_factory_.GetWeakPtr())); 364bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 365bc0c74963418442991072b2c87baec839eec9c20Darren Krahn 3660752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn std::unique_ptr<attestation::AttestationInterface> attestation_; 3670752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 3680752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn // Declare this last so weak pointers will be destroyed first. 3690752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn base::WeakPtrFactory<ClientLoop> weak_factory_{this}; 3700752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 3710752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn DISALLOW_COPY_AND_ASSIGN(ClientLoop); 3720752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn}; 3730752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 3740752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn} // namespace attestation 3750752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 3760752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnint main(int argc, char* argv[]) { 3770752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn base::CommandLine::Init(argc, argv); 3780752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn chromeos::InitLog(chromeos::kLogToSyslog | chromeos::kLogToStderr); 3790752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn attestation::ClientLoop loop; 3800752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return loop.Run(); 3816bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen} 382