13daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// 23daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// Copyright (C) 2014 The Android Open Source Project 33daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// 43daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License"); 53daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// you may not use this file except in compliance with the License. 63daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// You may obtain a copy of the License at 73daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// 83daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// http://www.apache.org/licenses/LICENSE-2.0 93daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// 103daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// Unless required by applicable law or agreed to in writing, software 113daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS, 123daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// See the License for the specific language governing permissions and 143daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// limitations under the License. 153daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// 166bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen 170752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <stdio.h> 180752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <sysexits.h> 190752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 2045fc1234b4f1a1c1cfdd44774350a70b26b9b630Alex Vakulenko#include <memory> 21b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahn#include <string> 2245fc1234b4f1a1c1cfdd44774350a70b26b9b630Alex Vakulenko 230752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <base/command_line.h> 242e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn#include <base/files/file_util.h> 250752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <base/message_loop/message_loop.h> 26e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko#include <brillo/bind_lambda.h> 27e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko#include <brillo/daemons/daemon.h> 28e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko#include <brillo/syslog_logging.h> 290752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 30b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahn#include "attestation/client/dbus_proxy.h" 31b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahn#include "attestation/common/attestation_ca.pb.h" 322e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn#include "attestation/common/crypto_utility_impl.h" 33b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahn#include "attestation/common/interface.pb.h" 3459ea81cf9e7b293ec3241e5d442092b0278a3643Darren Krahn#include "attestation/common/print_interface_proto.h" 356bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen 360752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnnamespace attestation { 370752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 3862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahnconst char kCreateAndCertifyCommand[] = "create_and_certify"; 390752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnconst char kCreateCommand[] = "create"; 406222defa52eb13c0d90673f642f2647f7753478bDarren Krahnconst char kInfoCommand[] = "info"; 41cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahnconst char kEndorsementCommand[] = "endorsement"; 42566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahnconst char kAttestationKeyCommand[] = "attestation_key"; 432e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahnconst char kActivateCommand[] = "activate"; 442e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahnconst char kEncryptForActivateCommand[] = "encrypt_for_activate"; 45bc0c74963418442991072b2c87baec839eec9c20Darren Krahnconst char kEncryptCommand[] = "encrypt"; 46bc0c74963418442991072b2c87baec839eec9c20Darren Krahnconst char kDecryptCommand[] = "decrypt"; 47ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahnconst char kSignCommand[] = "sign"; 48ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahnconst char kVerifyCommand[] = "verify"; 49594849c7cf872d055575277b930f4f596bef1988Darren Krahnconst char kRegisterCommand[] = "register"; 500752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnconst char kUsage[] = R"( 510752bd25ba9f45c07bc989d42bf5272133a85afaDarren KrahnUsage: attestation_client <command> [<args>] 520752bd25ba9f45c07bc989d42bf5272133a85afaDarren KrahnCommands: 5362c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn create_and_certify [--user=<email>] [--label=<keylabel>] 5462c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Creates a key and requests certification by the Google Attestation CA. 5562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn This is the default command. 56bc0c74963418442991072b2c87baec839eec9c20Darren Krahn create [--user=<email>] [--label=<keylabel] [--usage=sign|decrypt] 5762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Creates a certifiable key. 582e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 5962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn info [--user=<email>] [--label=<keylabel>] 6062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Prints info about a key. 6162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn endorsement 6262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Prints info about the TPM endorsement. 6362c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn attestation_key 6462c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Prints info about the TPM attestation key. 652e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 6662c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn activate --input=<input_file> 6762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Activates an attestation key using the encrypted credential in 6862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn |input_file|. 6962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn encrypt_for_activate --input=<input_file> --output=<output_file> 7062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn Encrypts the content of |input_file| as required by the TPM for activating 7162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn an attestation key. The result is written to |output_file|. 72bc0c74963418442991072b2c87baec839eec9c20Darren Krahn 73bc0c74963418442991072b2c87baec839eec9c20Darren Krahn encrypt [--user=<email>] [--label=<keylabel>] --input=<input_file> 74bc0c74963418442991072b2c87baec839eec9c20Darren Krahn --output=<output_file> 75ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn Encrypts the contents of |input_file| as required by the TPM for a decrypt 76bc0c74963418442991072b2c87baec839eec9c20Darren Krahn operation. The result is written to |output_file|. 77bc0c74963418442991072b2c87baec839eec9c20Darren Krahn decrypt [--user=<email>] [--label=<keylabel>] --input=<input_file> 78ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn Decrypts the contents of |input_file|. 79ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn 80ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn sign [--user=<email>] [--label=<keylabel>] --input=<input_file> 81ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn [--output=<output_file>] 82ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn Signs the contents of |input_file|. 83ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn verify [--user=<email>] [--label=<keylabel] --input=<signed_data_file> 84ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn --signature=<signature_file> 85ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn Verifies the signature in |signature_file| against the contents of 86ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn |input_file|. 87594849c7cf872d055575277b930f4f596bef1988Darren Krahn 88594849c7cf872d055575277b930f4f596bef1988Darren Krahn register [--user=<email>] [--label=<keylabel] 89594849c7cf872d055575277b930f4f596bef1988Darren Krahn Registers a key with a PKCS #11 token. 900752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn)"; 910752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 920752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn// The Daemon class works well as a client loop as well. 93e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenkousing ClientLoopBase = brillo::Daemon; 940752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 950752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnclass ClientLoop : public ClientLoopBase { 960752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn public: 970752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn ClientLoop() = default; 980752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn ~ClientLoop() override = default; 990752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 1000752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn protected: 1010752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn int OnInit() override { 1020752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn int exit_code = ClientLoopBase::OnInit(); 1030752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn if (exit_code != EX_OK) { 1040752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return exit_code; 1050752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 1060752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn attestation_.reset(new attestation::DBusProxy()); 1070752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn if (!attestation_->Initialize()) { 1080752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return EX_UNAVAILABLE; 1090752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 1100752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn exit_code = ScheduleCommand(); 1110752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn if (exit_code == EX_USAGE) { 1120752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn printf("%s", kUsage); 1130752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 1140752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return exit_code; 1150752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 1160752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 1170752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn void OnShutdown(int* exit_code) override { 1180752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn attestation_.reset(); 1190752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn ClientLoopBase::OnShutdown(exit_code); 120b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahn } 1210752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 1220752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn private: 1230752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn // Posts tasks according to the command line options. 1240752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn int ScheduleCommand() { 1250752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn base::Closure task; 12659d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 12759d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn const auto& args = command_line->GetArgs(); 128566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn if (command_line->HasSwitch("help") || command_line->HasSwitch("h") || 129bc0c74963418442991072b2c87baec839eec9c20Darren Krahn (!args.empty() && args.front() == "help")) { 130566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn return EX_USAGE; 131566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 13262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn if (args.empty() || args.front() == kCreateAndCertifyCommand) { 1330752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn task = base::Bind(&ClientLoop::CallCreateGoogleAttestedKey, 13459d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn weak_factory_.GetWeakPtr(), 13559d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn command_line->GetSwitchValueASCII("label"), 13659d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn command_line->GetSwitchValueASCII("user")); 13762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn } else if (args.front() == kCreateCommand) { 138bc0c74963418442991072b2c87baec839eec9c20Darren Krahn std::string usage_str = command_line->GetSwitchValueASCII("usage"); 139bc0c74963418442991072b2c87baec839eec9c20Darren Krahn KeyUsage usage; 140bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (usage_str.empty() || usage_str == "sign") { 141bc0c74963418442991072b2c87baec839eec9c20Darren Krahn usage = KEY_USAGE_SIGN; 142bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } else if (usage_str == "decrypt") { 143bc0c74963418442991072b2c87baec839eec9c20Darren Krahn usage = KEY_USAGE_DECRYPT; 144bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } else { 145bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return EX_USAGE; 146bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 14762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn task = base::Bind(&ClientLoop::CallCreateCertifiableKey, 14862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn weak_factory_.GetWeakPtr(), 14962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn command_line->GetSwitchValueASCII("label"), 150bc0c74963418442991072b2c87baec839eec9c20Darren Krahn command_line->GetSwitchValueASCII("user"), 151bc0c74963418442991072b2c87baec839eec9c20Darren Krahn usage); 1526222defa52eb13c0d90673f642f2647f7753478bDarren Krahn } else if (args.front() == kInfoCommand) { 1536222defa52eb13c0d90673f642f2647f7753478bDarren Krahn task = base::Bind(&ClientLoop::CallGetKeyInfo, 1546222defa52eb13c0d90673f642f2647f7753478bDarren Krahn weak_factory_.GetWeakPtr(), 1556222defa52eb13c0d90673f642f2647f7753478bDarren Krahn command_line->GetSwitchValueASCII("label"), 1566222defa52eb13c0d90673f642f2647f7753478bDarren Krahn command_line->GetSwitchValueASCII("user")); 157cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn } else if (args.front() == kEndorsementCommand) { 158cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn task = base::Bind(&ClientLoop::CallGetEndorsementInfo, 159cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn weak_factory_.GetWeakPtr()); 160566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } else if (args.front() == kAttestationKeyCommand) { 161566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn task = base::Bind(&ClientLoop::CallGetAttestationKeyInfo, 162566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn weak_factory_.GetWeakPtr()); 1632e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } else if (args.front() == kActivateCommand) { 1642e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!command_line->HasSwitch("input")) { 1652e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return EX_USAGE; 1662e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 1672e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn std::string input; 1682e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::FilePath filename(command_line->GetSwitchValueASCII("input")); 1692e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!base::ReadFileToString(filename, &input)) { 1702e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn LOG(ERROR) << "Failed to read file: " << filename.value(); 1712e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return EX_NOINPUT; 1722e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 1732e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn task = base::Bind(&ClientLoop::CallActivateAttestationKey, 1742e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn weak_factory_.GetWeakPtr(), 1752e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn input); 1762e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } else if (args.front() == kEncryptForActivateCommand) { 1772e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!command_line->HasSwitch("input") || 1782e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn !command_line->HasSwitch("output")) { 1792e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return EX_USAGE; 1802e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 1812e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn std::string input; 1822e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::FilePath filename(command_line->GetSwitchValueASCII("input")); 1832e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!base::ReadFileToString(filename, &input)) { 1842e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn LOG(ERROR) << "Failed to read file: " << filename.value(); 1852e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return EX_NOINPUT; 1862e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 1872e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn task = base::Bind(&ClientLoop::EncryptForActivate, 1882e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn weak_factory_.GetWeakPtr(), 1892e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn input); 190bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } else if (args.front() == kEncryptCommand) { 191bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!command_line->HasSwitch("input") || 192bc0c74963418442991072b2c87baec839eec9c20Darren Krahn !command_line->HasSwitch("output")) { 193bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return EX_USAGE; 194bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 195bc0c74963418442991072b2c87baec839eec9c20Darren Krahn std::string input; 196bc0c74963418442991072b2c87baec839eec9c20Darren Krahn base::FilePath filename(command_line->GetSwitchValueASCII("input")); 197bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!base::ReadFileToString(filename, &input)) { 198bc0c74963418442991072b2c87baec839eec9c20Darren Krahn LOG(ERROR) << "Failed to read file: " << filename.value(); 199bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return EX_NOINPUT; 200bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 201bc0c74963418442991072b2c87baec839eec9c20Darren Krahn task = base::Bind(&ClientLoop::Encrypt, 202bc0c74963418442991072b2c87baec839eec9c20Darren Krahn weak_factory_.GetWeakPtr(), 203bc0c74963418442991072b2c87baec839eec9c20Darren Krahn command_line->GetSwitchValueASCII("label"), 204bc0c74963418442991072b2c87baec839eec9c20Darren Krahn command_line->GetSwitchValueASCII("user"), 205bc0c74963418442991072b2c87baec839eec9c20Darren Krahn input); 206bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } else if (args.front() == kDecryptCommand) { 207bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!command_line->HasSwitch("input")) { 208bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return EX_USAGE; 209bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 210bc0c74963418442991072b2c87baec839eec9c20Darren Krahn std::string input; 211bc0c74963418442991072b2c87baec839eec9c20Darren Krahn base::FilePath filename(command_line->GetSwitchValueASCII("input")); 212bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!base::ReadFileToString(filename, &input)) { 213bc0c74963418442991072b2c87baec839eec9c20Darren Krahn LOG(ERROR) << "Failed to read file: " << filename.value(); 214bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return EX_NOINPUT; 215bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 216bc0c74963418442991072b2c87baec839eec9c20Darren Krahn task = base::Bind(&ClientLoop::CallDecrypt, 217bc0c74963418442991072b2c87baec839eec9c20Darren Krahn weak_factory_.GetWeakPtr(), 218bc0c74963418442991072b2c87baec839eec9c20Darren Krahn command_line->GetSwitchValueASCII("label"), 219bc0c74963418442991072b2c87baec839eec9c20Darren Krahn command_line->GetSwitchValueASCII("user"), 220bc0c74963418442991072b2c87baec839eec9c20Darren Krahn input); 221ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } else if (args.front() == kSignCommand) { 222ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn if (!command_line->HasSwitch("input")) { 223ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn return EX_USAGE; 224ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 225ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn std::string input; 226ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn base::FilePath filename(command_line->GetSwitchValueASCII("input")); 227ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn if (!base::ReadFileToString(filename, &input)) { 228ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn LOG(ERROR) << "Failed to read file: " << filename.value(); 229ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn return EX_NOINPUT; 230ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 231ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn task = base::Bind(&ClientLoop::CallSign, 232ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn weak_factory_.GetWeakPtr(), 233ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn command_line->GetSwitchValueASCII("label"), 234ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn command_line->GetSwitchValueASCII("user"), 235ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn input); 236ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } else if (args.front() == kVerifyCommand) { 237ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn if (!command_line->HasSwitch("input") || 238ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn !command_line->HasSwitch("signature")) { 239ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn return EX_USAGE; 240ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 241ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn std::string input; 242ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn base::FilePath filename(command_line->GetSwitchValueASCII("input")); 243ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn if (!base::ReadFileToString(filename, &input)) { 244ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn LOG(ERROR) << "Failed to read file: " << filename.value(); 245ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn return EX_NOINPUT; 246ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 247ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn std::string signature; 248ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn base::FilePath filename2(command_line->GetSwitchValueASCII("signature")); 249ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn if (!base::ReadFileToString(filename2, &signature)) { 250ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn LOG(ERROR) << "Failed to read file: " << filename2.value(); 251ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn return EX_NOINPUT; 252ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 253ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn task = base::Bind(&ClientLoop::VerifySignature, 254ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn weak_factory_.GetWeakPtr(), 255ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn command_line->GetSwitchValueASCII("label"), 256ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn command_line->GetSwitchValueASCII("user"), 257ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn input, 258ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn signature); 259594849c7cf872d055575277b930f4f596bef1988Darren Krahn } else if (args.front() == kRegisterCommand) { 260594849c7cf872d055575277b930f4f596bef1988Darren Krahn task = base::Bind(&ClientLoop::CallRegister, 261594849c7cf872d055575277b930f4f596bef1988Darren Krahn weak_factory_.GetWeakPtr(), 262594849c7cf872d055575277b930f4f596bef1988Darren Krahn command_line->GetSwitchValueASCII("label"), 263594849c7cf872d055575277b930f4f596bef1988Darren Krahn command_line->GetSwitchValueASCII("user")); 2640752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } else { 2650752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return EX_USAGE; 2660752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 2670752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn base::MessageLoop::current()->PostTask(FROM_HERE, task); 2680752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return EX_OK; 2690752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 2700752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 2716222defa52eb13c0d90673f642f2647f7753478bDarren Krahn template <typename ProtobufType> 2726222defa52eb13c0d90673f642f2647f7753478bDarren Krahn void PrintReplyAndQuit(const ProtobufType& reply) { 27359ea81cf9e7b293ec3241e5d442092b0278a3643Darren Krahn printf("%s\n", GetProtoDebugString(reply).c_str()); 2740752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn Quit(); 2750752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn } 2760752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 2772e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn void WriteOutput(const std::string& output) { 2782e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::FilePath filename(base::CommandLine::ForCurrentProcess()-> 2792e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn GetSwitchValueASCII("output")); 2802e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (base::WriteFile(filename, output.data(), output.size()) != 2812e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn static_cast<int>(output.size())) { 2822e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn LOG(ERROR) << "Failed to write file: " << filename.value(); 2832e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn QuitWithExitCode(EX_IOERR); 2842e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 2852e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 2862e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 28759d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn void CallCreateGoogleAttestedKey(const std::string& label, 28859d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn const std::string& username) { 289b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn CreateGoogleAttestedKeyRequest request; 290b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.set_key_label(label); 291b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.set_key_type(KEY_TYPE_RSA); 292b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.set_key_usage(KEY_USAGE_SIGN); 293b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE); 294b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.set_username(username); 2950752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn attestation_->CreateGoogleAttestedKey( 296b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request, 2976222defa52eb13c0d90673f642f2647f7753478bDarren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<CreateGoogleAttestedKeyReply>, 2986222defa52eb13c0d90673f642f2647f7753478bDarren Krahn weak_factory_.GetWeakPtr())); 2996222defa52eb13c0d90673f642f2647f7753478bDarren Krahn } 3006222defa52eb13c0d90673f642f2647f7753478bDarren Krahn 3016222defa52eb13c0d90673f642f2647f7753478bDarren Krahn void CallGetKeyInfo(const std::string& label, const std::string& username) { 3026222defa52eb13c0d90673f642f2647f7753478bDarren Krahn GetKeyInfoRequest request; 3036222defa52eb13c0d90673f642f2647f7753478bDarren Krahn request.set_key_label(label); 3046222defa52eb13c0d90673f642f2647f7753478bDarren Krahn request.set_username(username); 3056222defa52eb13c0d90673f642f2647f7753478bDarren Krahn attestation_->GetKeyInfo( 3066222defa52eb13c0d90673f642f2647f7753478bDarren Krahn request, 3076222defa52eb13c0d90673f642f2647f7753478bDarren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<GetKeyInfoReply>, 3080752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn weak_factory_.GetWeakPtr())); 30945fc1234b4f1a1c1cfdd44774350a70b26b9b630Alex Vakulenko } 3100752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 311cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn void CallGetEndorsementInfo() { 312cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn GetEndorsementInfoRequest request; 313cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn request.set_key_type(KEY_TYPE_RSA); 314cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn attestation_->GetEndorsementInfo( 315cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn request, 316cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<GetEndorsementInfoReply>, 317cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn weak_factory_.GetWeakPtr())); 318cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn } 319cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn 320566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn void CallGetAttestationKeyInfo() { 321566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn GetAttestationKeyInfoRequest request; 322566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn request.set_key_type(KEY_TYPE_RSA); 323566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn attestation_->GetAttestationKeyInfo( 324566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn request, 325566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<GetAttestationKeyInfoReply>, 326566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn weak_factory_.GetWeakPtr())); 327566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 328566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn 3292e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn void CallActivateAttestationKey(const std::string& input) { 3302e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn ActivateAttestationKeyRequest request; 3312e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.set_key_type(KEY_TYPE_RSA); 3322e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.mutable_encrypted_certificate()->ParseFromString(input); 3332e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.set_save_certificate(true); 3342e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn attestation_->ActivateAttestationKey( 3352e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request, 3362e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<ActivateAttestationKeyReply>, 3372e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn weak_factory_.GetWeakPtr())); 3382e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3392e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 3402e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn void EncryptForActivate(const std::string& input) { 3412e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn GetEndorsementInfoRequest request; 3422e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.set_key_type(KEY_TYPE_RSA); 3432e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn attestation_->GetEndorsementInfo( 3442e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request, 3452e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::Bind(&ClientLoop::EncryptForActivate2, 3462e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn weak_factory_.GetWeakPtr(), 3472e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn input)); 3482e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3492e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 3502e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn void EncryptForActivate2(const std::string& input, 3512e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const GetEndorsementInfoReply& endorsement_info) { 3522e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (endorsement_info.status() != STATUS_SUCCESS) { 3532e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn PrintReplyAndQuit(endorsement_info); 3542e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3552e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn GetAttestationKeyInfoRequest request; 3562e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.set_key_type(KEY_TYPE_RSA); 3572e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn attestation_->GetAttestationKeyInfo( 3582e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request, 3592e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::Bind(&ClientLoop::EncryptForActivate3, 3602e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn weak_factory_.GetWeakPtr(), 3612e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn input, 3622e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn endorsement_info)); 3632e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3642e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 3652e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn void EncryptForActivate3( 3662e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const std::string& input, 3672e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const GetEndorsementInfoReply& endorsement_info, 3682e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const GetAttestationKeyInfoReply& attestation_key_info) { 3692e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (attestation_key_info.status() != STATUS_SUCCESS) { 3702e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn PrintReplyAndQuit(attestation_key_info); 3712e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3722e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn CryptoUtilityImpl crypto(nullptr); 3732e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn EncryptedIdentityCredential encrypted; 3742e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!crypto.EncryptIdentityCredential( 3752e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn input, 3762e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn endorsement_info.ek_public_key(), 3772e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn attestation_key_info.public_key_tpm_format(), 3782e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn &encrypted)) { 3792e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn QuitWithExitCode(EX_SOFTWARE); 3802e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3812e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn std::string output; 3822e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn encrypted.SerializeToString(&output); 3832e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn WriteOutput(output); 3842e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn Quit(); 3852e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3862e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 38762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn void CallCreateCertifiableKey(const std::string& label, 388bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const std::string& username, 389bc0c74963418442991072b2c87baec839eec9c20Darren Krahn KeyUsage usage) { 39062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn CreateCertifiableKeyRequest request; 39162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn request.set_key_label(label); 39262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn request.set_username(username); 393bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_key_type(KEY_TYPE_RSA); 394bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_key_usage(usage); 39562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn attestation_->CreateCertifiableKey( 39662c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn request, 39762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<CreateCertifiableKeyReply>, 39862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn weak_factory_.GetWeakPtr())); 39962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn } 40062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn 401bc0c74963418442991072b2c87baec839eec9c20Darren Krahn void Encrypt(const std::string& label, 402bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const std::string& username, 403bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const std::string& input) { 404bc0c74963418442991072b2c87baec839eec9c20Darren Krahn GetKeyInfoRequest request; 405bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_key_label(label); 406bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_username(username); 407bc0c74963418442991072b2c87baec839eec9c20Darren Krahn attestation_->GetKeyInfo(request, base::Bind(&ClientLoop::Encrypt2, 408bc0c74963418442991072b2c87baec839eec9c20Darren Krahn weak_factory_.GetWeakPtr(), 409bc0c74963418442991072b2c87baec839eec9c20Darren Krahn input)); 410bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 411bc0c74963418442991072b2c87baec839eec9c20Darren Krahn 412bc0c74963418442991072b2c87baec839eec9c20Darren Krahn void Encrypt2(const std::string& input, 413bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const GetKeyInfoReply& key_info) { 414bc0c74963418442991072b2c87baec839eec9c20Darren Krahn CryptoUtilityImpl crypto(nullptr); 415bc0c74963418442991072b2c87baec839eec9c20Darren Krahn std::string output; 416bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!crypto.EncryptForUnbind(key_info.public_key(), input, &output)) { 417bc0c74963418442991072b2c87baec839eec9c20Darren Krahn QuitWithExitCode(EX_SOFTWARE); 418bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 419bc0c74963418442991072b2c87baec839eec9c20Darren Krahn WriteOutput(output); 420bc0c74963418442991072b2c87baec839eec9c20Darren Krahn Quit(); 421bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 422bc0c74963418442991072b2c87baec839eec9c20Darren Krahn 423bc0c74963418442991072b2c87baec839eec9c20Darren Krahn void CallDecrypt(const std::string& label, 424bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const std::string& username, 425bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const std::string& input) { 426bc0c74963418442991072b2c87baec839eec9c20Darren Krahn DecryptRequest request; 427bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_key_label(label); 428bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_username(username); 429bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request.set_encrypted_data(input); 430bc0c74963418442991072b2c87baec839eec9c20Darren Krahn attestation_->Decrypt( 431bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request, 432bc0c74963418442991072b2c87baec839eec9c20Darren Krahn base::Bind(&ClientLoop::PrintReplyAndQuit<DecryptReply>, 433bc0c74963418442991072b2c87baec839eec9c20Darren Krahn weak_factory_.GetWeakPtr())); 434bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 435bc0c74963418442991072b2c87baec839eec9c20Darren Krahn 436ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn void CallSign(const std::string& label, 437ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn const std::string& username, 438ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn const std::string& input) { 439ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn SignRequest request; 440ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn request.set_key_label(label); 441ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn request.set_username(username); 442ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn request.set_data_to_sign(input); 443ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn attestation_->Sign(request, base::Bind(&ClientLoop::OnSignComplete, 444ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn weak_factory_.GetWeakPtr())); 445ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 446ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn 447ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn void OnSignComplete(const SignReply& reply) { 448ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn if (reply.status() == STATUS_SUCCESS && 449ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn base::CommandLine::ForCurrentProcess()->HasSwitch("output")) { 450ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn WriteOutput(reply.signature()); 451ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 452ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn PrintReplyAndQuit<SignReply>(reply); 453ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 454ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn 455ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn void VerifySignature(const std::string& label, 456ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn const std::string& username, 457ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn const std::string& input, 458ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn const std::string& signature) { 459ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn GetKeyInfoRequest request; 460ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn request.set_key_label(label); 461ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn request.set_username(username); 462ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn attestation_->GetKeyInfo(request, base::Bind(&ClientLoop::VerifySignature2, 463ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn weak_factory_.GetWeakPtr(), 464ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn input, signature)); 465ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 466ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn 467ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn void VerifySignature2(const std::string& input, 468ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn const std::string& signature, 469ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn const GetKeyInfoReply& key_info) { 470ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn CryptoUtilityImpl crypto(nullptr); 471ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn if (crypto.VerifySignature(key_info.public_key(), input, signature)) { 472ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn printf("Signature is OK!\n"); 473ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } else { 474ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn printf("Signature is BAD!\n"); 475ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 476ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn Quit(); 477ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 478ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn 479594849c7cf872d055575277b930f4f596bef1988Darren Krahn void CallRegister(const std::string& label, const std::string& username) { 480594849c7cf872d055575277b930f4f596bef1988Darren Krahn RegisterKeyWithChapsTokenRequest request; 481594849c7cf872d055575277b930f4f596bef1988Darren Krahn request.set_key_label(label); 482594849c7cf872d055575277b930f4f596bef1988Darren Krahn request.set_username(username); 483594849c7cf872d055575277b930f4f596bef1988Darren Krahn attestation_->RegisterKeyWithChapsToken(request, base::Bind( 484594849c7cf872d055575277b930f4f596bef1988Darren Krahn &ClientLoop::PrintReplyAndQuit<RegisterKeyWithChapsTokenReply>, 485594849c7cf872d055575277b930f4f596bef1988Darren Krahn weak_factory_.GetWeakPtr())); 486594849c7cf872d055575277b930f4f596bef1988Darren Krahn } 487594849c7cf872d055575277b930f4f596bef1988Darren Krahn 4880752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn std::unique_ptr<attestation::AttestationInterface> attestation_; 4890752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 4900752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn // Declare this last so weak pointers will be destroyed first. 4910752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn base::WeakPtrFactory<ClientLoop> weak_factory_{this}; 4920752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 4930752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn DISALLOW_COPY_AND_ASSIGN(ClientLoop); 4940752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn}; 4950752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 4960752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn} // namespace attestation 4970752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 4980752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnint main(int argc, char* argv[]) { 4990752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn base::CommandLine::Init(argc, argv); 500b3c9cdcef463064d7ac8f1e6b4b88e62433f9d5dUtkarsh Sanghi brillo::InitLog(brillo::kLogToStderr); 5010752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn attestation::ClientLoop loop; 5020752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn return loop.Run(); 5036bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen} 504