13daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// 23daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// Copyright (C) 2015 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 17ab0cddda9971f97781fc9f6cbc76095ba7542abfAlex Vakulenko#include "attestation/server/attestation_service.h" 186bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen 19d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn#include <string> 20d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 210752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn#include <base/callback.h> 22e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko#include <brillo/bind_lambda.h> 23e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko#include <brillo/data_encoding.h> 24e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko#include <brillo/http/http_utils.h> 25e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko#include <brillo/mime_utils.h> 26d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn#include <crypto/sha2.h> 270752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahn 28d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn#include "attestation/common/attestation_ca.pb.h" 29d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn#include "attestation/common/database.pb.h" 3030a5bba00647d29e324111005deb76a0466f8c6bDarren Krahn#include "attestation/server/database_impl.h" 3130a5bba00647d29e324111005deb76a0466f8c6bDarren Krahn 32d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnnamespace { 33d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 34d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn#ifndef USE_TEST_ACA 35d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnconst char kACAWebOrigin[] = "https://chromeos-ca.gstatic.com"; 36d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn#else 37d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnconst char kACAWebOrigin[] = "https://asbestos-qa.corp.google.com"; 38d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn#endif 39d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnconst size_t kNonceSize = 20; // As per TPM_NONCE definition. 40d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnconst int kNumTemporalValues = 5; 41d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 42d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} // namespace 43d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 446bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyennamespace attestation { 456bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen 46d66389850c33614ffbbbbc3f768621182fd853baDarren KrahnAttestationService::AttestationService() 47d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn : attestation_ca_origin_(kACAWebOrigin), 48d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn weak_factory_(this) {} 49d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 50b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahnbool AttestationService::Initialize() { 51d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(INFO) << "Attestation service started."; 52d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn worker_thread_.reset(new base::Thread("Attestation Service Worker")); 5391b43220439ab46096af0efc47f9b706abc3b108Darren Krahn worker_thread_->StartWithOptions( 5491b43220439ab46096af0efc47f9b706abc3b108Darren Krahn base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 5559d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn if (!tpm_utility_) { 5659d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn default_tpm_utility_.reset(new TpmUtilityV1()); 5759d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn if (!default_tpm_utility_->Initialize()) { 5859d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn return false; 5959d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn } 6059d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn tpm_utility_ = default_tpm_utility_.get(); 6159d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn } 6259d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn if (!crypto_utility_) { 6359d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn default_crypto_utility_.reset(new CryptoUtilityImpl(tpm_utility_)); 6459d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn crypto_utility_ = default_crypto_utility_.get(); 6559d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn } 6630a5bba00647d29e324111005deb76a0466f8c6bDarren Krahn if (!database_) { 67d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn default_database_.reset(new DatabaseImpl(crypto_utility_)); 6891b43220439ab46096af0efc47f9b706abc3b108Darren Krahn worker_thread_->task_runner()->PostTask(FROM_HERE, base::Bind( 6991b43220439ab46096af0efc47f9b706abc3b108Darren Krahn &DatabaseImpl::Initialize, 7091b43220439ab46096af0efc47f9b706abc3b108Darren Krahn base::Unretained(default_database_.get()))); 7130a5bba00647d29e324111005deb76a0466f8c6bDarren Krahn database_ = default_database_.get(); 7230a5bba00647d29e324111005deb76a0466f8c6bDarren Krahn } 7359d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn if (!key_store_) { 7459d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn pkcs11_token_manager_.reset(new chaps::TokenManagerClient()); 7559d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn default_key_store_.reset(new Pkcs11KeyStore(pkcs11_token_manager_.get())); 7659d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn key_store_ = default_key_store_.get(); 7759d7aa26782d3c6efd707e3b936d56c893a2555aDarren Krahn } 78b91fd4923f411705be97fbc5c0ada37481c0cd8dDarren Krahn return true; 796bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen} 806bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen 810752bd25ba9f45c07bc989d42bf5272133a85afaDarren Krahnvoid AttestationService::CreateGoogleAttestedKey( 82b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn const CreateGoogleAttestedKeyRequest& request, 83d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const CreateGoogleAttestedKeyCallback& callback) { 84b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn auto result = std::make_shared<CreateGoogleAttestedKeyReply>(); 85d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn base::Closure task = base::Bind( 86d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn &AttestationService::CreateGoogleAttestedKeyTask, 87d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn base::Unretained(this), 88b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request, 89d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn result); 90d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn base::Closure reply = base::Bind( 91cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn &AttestationService::TaskRelayCallback<CreateGoogleAttestedKeyReply>, 92d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn GetWeakPtr(), 93d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn callback, 94d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn result); 95d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, task, reply); 96d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 97d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 98d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnvoid AttestationService::CreateGoogleAttestedKeyTask( 99b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn const CreateGoogleAttestedKeyRequest& request, 100b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn const std::shared_ptr<CreateGoogleAttestedKeyReply>& result) { 101b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn LOG(INFO) << "Creating attested key: " << request.key_label(); 102d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!IsPreparedForEnrollment()) { 103d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << "Attestation: TPM is not ready."; 104b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn result->set_status(STATUS_NOT_READY); 105d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return; 106d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 107d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!IsEnrolled()) { 108d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string enroll_request; 109d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!CreateEnrollRequest(&enroll_request)) { 110b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 111d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return; 112d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 113d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string enroll_reply; 114d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!SendACARequestAndBlock(kEnroll, 115d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn enroll_request, 116d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn &enroll_reply)) { 117b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn result->set_status(STATUS_CA_NOT_AVAILABLE); 118d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return; 119d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 120d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string server_error; 121b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn if (!FinishEnroll(enroll_reply, &server_error)) { 1222e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (server_error.empty()) { 1232e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 1242e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return; 1252e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 126b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn result->set_status(STATUS_REQUEST_DENIED_BY_CA); 127b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn result->set_server_error(server_error); 128d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return; 129d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 130d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 13162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn CertifiedKey key; 132b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn if (!CreateKey(request.username(), request.key_label(), request.key_type(), 13362c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn request.key_usage(), &key)) { 134b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 13508d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn return; 136d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 137d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string certificate_request; 138d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string message_id; 139b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn if (!CreateCertificateRequest(request.username(), 14062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn key, 141b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.certificate_profile(), 142b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.origin(), 143d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn &certificate_request, 144d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn &message_id)) { 145b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 146d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return; 147d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 148d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string certificate_reply; 149d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!SendACARequestAndBlock(kGetCertificate, 150d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn certificate_request, 151d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn &certificate_reply)) { 152b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn result->set_status(STATUS_CA_NOT_AVAILABLE); 153d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return; 154d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 155d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string certificate_chain; 156d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string server_error; 157d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!FinishCertificateRequest(certificate_reply, 158b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.username(), 159b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn request.key_label(), 160d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn message_id, 16162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn &key, 162b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn &certificate_chain, 163b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn &server_error)) { 1642e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (server_error.empty()) { 1652e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 1662e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return; 1672e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 168b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn result->set_status(STATUS_REQUEST_DENIED_BY_CA); 169b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn result->set_server_error(server_error); 170d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return; 171d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 172b48a50fc394b9c8a1059463c9eaba4c8d1985b9bDarren Krahn result->set_certificate_chain(certificate_chain); 173d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 174d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 1756222defa52eb13c0d90673f642f2647f7753478bDarren Krahnvoid AttestationService::GetKeyInfo(const GetKeyInfoRequest& request, 1766222defa52eb13c0d90673f642f2647f7753478bDarren Krahn const GetKeyInfoCallback& callback) { 1776222defa52eb13c0d90673f642f2647f7753478bDarren Krahn auto result = std::make_shared<GetKeyInfoReply>(); 1786222defa52eb13c0d90673f642f2647f7753478bDarren Krahn base::Closure task = base::Bind( 1796222defa52eb13c0d90673f642f2647f7753478bDarren Krahn &AttestationService::GetKeyInfoTask, 1806222defa52eb13c0d90673f642f2647f7753478bDarren Krahn base::Unretained(this), 1816222defa52eb13c0d90673f642f2647f7753478bDarren Krahn request, 1826222defa52eb13c0d90673f642f2647f7753478bDarren Krahn result); 1836222defa52eb13c0d90673f642f2647f7753478bDarren Krahn base::Closure reply = base::Bind( 184cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn &AttestationService::TaskRelayCallback<GetKeyInfoReply>, 1856222defa52eb13c0d90673f642f2647f7753478bDarren Krahn GetWeakPtr(), 1866222defa52eb13c0d90673f642f2647f7753478bDarren Krahn callback, 1876222defa52eb13c0d90673f642f2647f7753478bDarren Krahn result); 1886222defa52eb13c0d90673f642f2647f7753478bDarren Krahn worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, task, reply); 1896222defa52eb13c0d90673f642f2647f7753478bDarren Krahn} 1906222defa52eb13c0d90673f642f2647f7753478bDarren Krahn 1916222defa52eb13c0d90673f642f2647f7753478bDarren Krahnvoid AttestationService::GetKeyInfoTask( 1926222defa52eb13c0d90673f642f2647f7753478bDarren Krahn const GetKeyInfoRequest& request, 1936222defa52eb13c0d90673f642f2647f7753478bDarren Krahn const std::shared_ptr<GetKeyInfoReply>& result) { 1946222defa52eb13c0d90673f642f2647f7753478bDarren Krahn CertifiedKey key; 1956222defa52eb13c0d90673f642f2647f7753478bDarren Krahn if (!FindKeyByLabel(request.username(), request.key_label(), &key)) { 1966222defa52eb13c0d90673f642f2647f7753478bDarren Krahn result->set_status(STATUS_INVALID_PARAMETER); 1976222defa52eb13c0d90673f642f2647f7753478bDarren Krahn return; 1986222defa52eb13c0d90673f642f2647f7753478bDarren Krahn } 1996222defa52eb13c0d90673f642f2647f7753478bDarren Krahn std::string public_key_info; 2006222defa52eb13c0d90673f642f2647f7753478bDarren Krahn if (!GetSubjectPublicKeyInfo(key.key_type(), key.public_key(), 2016222defa52eb13c0d90673f642f2647f7753478bDarren Krahn &public_key_info)) { 2026222defa52eb13c0d90673f642f2647f7753478bDarren Krahn LOG(ERROR) << __func__ << ": Bad public key."; 2036222defa52eb13c0d90673f642f2647f7753478bDarren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 2046222defa52eb13c0d90673f642f2647f7753478bDarren Krahn return; 2056222defa52eb13c0d90673f642f2647f7753478bDarren Krahn } 2066222defa52eb13c0d90673f642f2647f7753478bDarren Krahn result->set_key_type(key.key_type()); 2076222defa52eb13c0d90673f642f2647f7753478bDarren Krahn result->set_key_usage(key.key_usage()); 2086222defa52eb13c0d90673f642f2647f7753478bDarren Krahn result->set_public_key(public_key_info); 2096222defa52eb13c0d90673f642f2647f7753478bDarren Krahn result->set_certify_info(key.certified_key_info()); 2106222defa52eb13c0d90673f642f2647f7753478bDarren Krahn result->set_certify_info_signature(key.certified_key_proof()); 2116222defa52eb13c0d90673f642f2647f7753478bDarren Krahn if (key.has_intermediate_ca_cert()) { 2126222defa52eb13c0d90673f642f2647f7753478bDarren Krahn result->set_certificate(CreatePEMCertificateChain(key)); 2136222defa52eb13c0d90673f642f2647f7753478bDarren Krahn } else { 2146222defa52eb13c0d90673f642f2647f7753478bDarren Krahn result->set_certificate(key.certified_key_credential()); 2156222defa52eb13c0d90673f642f2647f7753478bDarren Krahn } 2166222defa52eb13c0d90673f642f2647f7753478bDarren Krahn} 2176222defa52eb13c0d90673f642f2647f7753478bDarren Krahn 218cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahnvoid AttestationService::GetEndorsementInfo( 219cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn const GetEndorsementInfoRequest& request, 220cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn const GetEndorsementInfoCallback& callback) { 221cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn auto result = std::make_shared<GetEndorsementInfoReply>(); 222cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn base::Closure task = base::Bind( 223cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn &AttestationService::GetEndorsementInfoTask, 224cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn base::Unretained(this), 225cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn request, 226cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn result); 227cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn base::Closure reply = base::Bind( 228cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn &AttestationService::TaskRelayCallback<GetEndorsementInfoReply>, 229cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn GetWeakPtr(), 230cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn callback, 231cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn result); 232cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, task, reply); 233cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn} 234cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn 235cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahnvoid AttestationService::GetEndorsementInfoTask( 236cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn const GetEndorsementInfoRequest& request, 237cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn const std::shared_ptr<GetEndorsementInfoReply>& result) { 238cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn if (request.key_type() != KEY_TYPE_RSA) { 239cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn result->set_status(STATUS_INVALID_PARAMETER); 240cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn return; 241cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn } 242cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn auto database_pb = database_->GetProtobuf(); 243cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn if (!database_pb.has_credentials() || 244cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn !database_pb.credentials().has_endorsement_public_key()) { 245cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn // Try to read the public key directly. 246cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn std::string public_key; 247cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn if (!tpm_utility_->GetEndorsementPublicKey(&public_key)) { 248cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn result->set_status(STATUS_NOT_AVAILABLE); 249cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn return; 250cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn } 251cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn database_pb.mutable_credentials()->set_endorsement_public_key(public_key); 252cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn } 253566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn std::string public_key_info; 254566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn if (!GetSubjectPublicKeyInfo( 255566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn request.key_type(), 256566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn database_pb.credentials().endorsement_public_key(), 257566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn &public_key_info)) { 258566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn LOG(ERROR) << __func__ << ": Bad public key."; 259566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 260566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn return; 261566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 262566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn result->set_ek_public_key(public_key_info); 263cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn if (database_pb.credentials().has_endorsement_credential()) { 264cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn result->set_ek_certificate( 265cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn database_pb.credentials().endorsement_credential()); 266cd5486df897619718b68223ebefc1322a1f5ab29Darren Krahn } 2676222defa52eb13c0d90673f642f2647f7753478bDarren Krahn} 2686222defa52eb13c0d90673f642f2647f7753478bDarren Krahn 269566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahnvoid AttestationService::GetAttestationKeyInfo( 270566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn const GetAttestationKeyInfoRequest& request, 271566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn const GetAttestationKeyInfoCallback& callback) { 272566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn auto result = std::make_shared<GetAttestationKeyInfoReply>(); 273566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn base::Closure task = base::Bind( 274566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn &AttestationService::GetAttestationKeyInfoTask, 275566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn base::Unretained(this), 276566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn request, 277566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn result); 278566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn base::Closure reply = base::Bind( 279566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn &AttestationService::TaskRelayCallback<GetAttestationKeyInfoReply>, 280566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn GetWeakPtr(), 281566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn callback, 282566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn result); 283566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, task, reply); 284566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn} 285566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn 286566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahnvoid AttestationService::GetAttestationKeyInfoTask( 287566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn const GetAttestationKeyInfoRequest& request, 288566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn const std::shared_ptr<GetAttestationKeyInfoReply>& result) { 289566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn if (request.key_type() != KEY_TYPE_RSA) { 290566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn result->set_status(STATUS_INVALID_PARAMETER); 291566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn return; 292566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 293566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn auto database_pb = database_->GetProtobuf(); 294566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn if (!IsPreparedForEnrollment() || !database_pb.has_identity_key()) { 295566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn result->set_status(STATUS_NOT_AVAILABLE); 296566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn return; 297566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 298566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn if (database_pb.identity_key().has_identity_public_key()) { 299566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn std::string public_key_info; 300566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn if (!GetSubjectPublicKeyInfo( 301566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn request.key_type(), 302566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn database_pb.identity_key().identity_public_key(), 303566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn &public_key_info)) { 304566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn LOG(ERROR) << __func__ << ": Bad public key."; 305566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 306566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn return; 307566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 308566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn result->set_public_key(public_key_info); 309566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 3102e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (database_pb.has_identity_binding() && 3112e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn database_pb.identity_binding().has_identity_public_key()) { 3122e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn result->set_public_key_tpm_format( 3132e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn database_pb.identity_binding().identity_public_key()); 3142e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 315566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn if (database_pb.identity_key().has_identity_credential()) { 316566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn result->set_certificate(database_pb.identity_key().identity_credential()); 317566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 318566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn if (database_pb.has_pcr0_quote()) { 319566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn *result->mutable_pcr0_quote() = database_pb.pcr0_quote(); 320566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 321566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn if (database_pb.has_pcr1_quote()) { 322566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn *result->mutable_pcr1_quote() = database_pb.pcr1_quote(); 323566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn } 324566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn} 325566c836c403212d5c13428b02ed65e5ff6e49a6bDarren Krahn 3262e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahnvoid AttestationService::ActivateAttestationKey( 3272e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const ActivateAttestationKeyRequest& request, 3282e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const ActivateAttestationKeyCallback& callback) { 3292e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn auto result = std::make_shared<ActivateAttestationKeyReply>(); 3302e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::Closure task = base::Bind( 3312e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn &AttestationService::ActivateAttestationKeyTask, 3322e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::Unretained(this), 3332e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request, 3342e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn result); 3352e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn base::Closure reply = base::Bind( 3362e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn &AttestationService::TaskRelayCallback<ActivateAttestationKeyReply>, 3372e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn GetWeakPtr(), 3382e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn callback, 3392e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn result); 3402e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, task, reply); 3412e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn} 3422e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 3432e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahnvoid AttestationService::ActivateAttestationKeyTask( 3442e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const ActivateAttestationKeyRequest& request, 3452e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn const std::shared_ptr<ActivateAttestationKeyReply>& result) { 3462e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (request.key_type() != KEY_TYPE_RSA) { 3472e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn result->set_status(STATUS_INVALID_PARAMETER); 3482e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return; 3492e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3502e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn std::string certificate; 3512e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn auto database_pb = database_->GetProtobuf(); 3522e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!tpm_utility_->ActivateIdentity( 3532e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn database_pb.delegate().blob(), 3542e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn database_pb.delegate().secret(), 3552e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn database_pb.identity_key().identity_key_blob(), 3562e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.encrypted_certificate().asym_ca_contents(), 3572e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn request.encrypted_certificate().sym_ca_attestation(), 3582e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn &certificate)) { 3592e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn LOG(ERROR) << __func__ << ": Failed to activate identity."; 3602e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 3612e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn return; 3622e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3632e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (request.save_certificate()) { 3642e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn database_->GetMutableProtobuf()->mutable_identity_key()-> 3652e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn set_identity_credential(certificate); 3662e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn if (!database_->SaveChanges()) { 3672e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn LOG(ERROR) << __func__ << ": Failed to persist database changes."; 3682e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 3692e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3702e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn } 3712e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn result->set_certificate(certificate); 3722e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn} 3732e89ba764046e015ae90a1668f7cb3eb29cf509dDarren Krahn 37462c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahnvoid AttestationService::CreateCertifiableKey( 37562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn const CreateCertifiableKeyRequest& request, 37662c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn const CreateCertifiableKeyCallback& callback) { 37762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn auto result = std::make_shared<CreateCertifiableKeyReply>(); 37862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn base::Closure task = base::Bind( 37962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn &AttestationService::CreateCertifiableKeyTask, 38062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn base::Unretained(this), 38162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn request, 38262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn result); 38362c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn base::Closure reply = base::Bind( 38462c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn &AttestationService::TaskRelayCallback<CreateCertifiableKeyReply>, 38562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn GetWeakPtr(), 38662c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn callback, 38762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn result); 38862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, task, reply); 38962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn} 39062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn 39162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahnvoid AttestationService::CreateCertifiableKeyTask( 39262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn const CreateCertifiableKeyRequest& request, 39362c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn const std::shared_ptr<CreateCertifiableKeyReply>& result) { 39462c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn CertifiedKey key; 39562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn if (!CreateKey(request.username(), request.key_label(), request.key_type(), 39662c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn request.key_usage(), &key)) { 39762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 39862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn return; 39962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn } 40062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn std::string public_key_info; 40162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn if (!GetSubjectPublicKeyInfo(key.key_type(), key.public_key(), 40262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn &public_key_info)) { 40362c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn LOG(ERROR) << __func__ << ": Bad public key."; 40462c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 40562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn return; 40662c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn } 40762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn result->set_public_key(public_key_info); 40862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn result->set_certify_info(key.certified_key_info()); 40962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn result->set_certify_info_signature(key.certified_key_proof()); 41062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn} 41162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn 412bc0c74963418442991072b2c87baec839eec9c20Darren Krahnvoid AttestationService::Decrypt(const DecryptRequest& request, 413bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const DecryptCallback& callback) { 414bc0c74963418442991072b2c87baec839eec9c20Darren Krahn auto result = std::make_shared<DecryptReply>(); 415bc0c74963418442991072b2c87baec839eec9c20Darren Krahn base::Closure task = base::Bind( 416bc0c74963418442991072b2c87baec839eec9c20Darren Krahn &AttestationService::DecryptTask, 417bc0c74963418442991072b2c87baec839eec9c20Darren Krahn base::Unretained(this), 418bc0c74963418442991072b2c87baec839eec9c20Darren Krahn request, 419bc0c74963418442991072b2c87baec839eec9c20Darren Krahn result); 420bc0c74963418442991072b2c87baec839eec9c20Darren Krahn base::Closure reply = base::Bind( 421bc0c74963418442991072b2c87baec839eec9c20Darren Krahn &AttestationService::TaskRelayCallback<DecryptReply>, 422bc0c74963418442991072b2c87baec839eec9c20Darren Krahn GetWeakPtr(), 423bc0c74963418442991072b2c87baec839eec9c20Darren Krahn callback, 424bc0c74963418442991072b2c87baec839eec9c20Darren Krahn result); 425bc0c74963418442991072b2c87baec839eec9c20Darren Krahn worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, task, reply); 426bc0c74963418442991072b2c87baec839eec9c20Darren Krahn} 427bc0c74963418442991072b2c87baec839eec9c20Darren Krahn 428bc0c74963418442991072b2c87baec839eec9c20Darren Krahnvoid AttestationService::DecryptTask( 429bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const DecryptRequest& request, 430bc0c74963418442991072b2c87baec839eec9c20Darren Krahn const std::shared_ptr<DecryptReply>& result) { 431bc0c74963418442991072b2c87baec839eec9c20Darren Krahn CertifiedKey key; 432bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!FindKeyByLabel(request.username(), request.key_label(), &key)) { 433bc0c74963418442991072b2c87baec839eec9c20Darren Krahn result->set_status(STATUS_INVALID_PARAMETER); 434bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return; 435bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 436bc0c74963418442991072b2c87baec839eec9c20Darren Krahn std::string data; 437bc0c74963418442991072b2c87baec839eec9c20Darren Krahn if (!tpm_utility_->Unbind(key.key_blob(), request.encrypted_data(), &data)) { 438bc0c74963418442991072b2c87baec839eec9c20Darren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 439bc0c74963418442991072b2c87baec839eec9c20Darren Krahn return; 440bc0c74963418442991072b2c87baec839eec9c20Darren Krahn } 441bc0c74963418442991072b2c87baec839eec9c20Darren Krahn result->set_decrypted_data(data); 442bc0c74963418442991072b2c87baec839eec9c20Darren Krahn} 443bc0c74963418442991072b2c87baec839eec9c20Darren Krahn 444ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahnvoid AttestationService::Sign(const SignRequest& request, 445ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn const SignCallback& callback) { 446ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn auto result = std::make_shared<SignReply>(); 447ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn base::Closure task = base::Bind( 448ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn &AttestationService::SignTask, 449ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn base::Unretained(this), 450ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn request, 451ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn result); 452ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn base::Closure reply = base::Bind( 453ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn &AttestationService::TaskRelayCallback<SignReply>, 454ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn GetWeakPtr(), 455ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn callback, 456ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn result); 457ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, task, reply); 458ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn} 459ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn 460ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahnvoid AttestationService::SignTask(const SignRequest& request, 461ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn const std::shared_ptr<SignReply>& result) { 462ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn CertifiedKey key; 463ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn if (!FindKeyByLabel(request.username(), request.key_label(), &key)) { 464ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn result->set_status(STATUS_INVALID_PARAMETER); 465ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn return; 466ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 467ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn std::string signature; 468ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn if (!tpm_utility_->Sign(key.key_blob(), request.data_to_sign(), &signature)) { 469ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 470ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn return; 471ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn } 472ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn result->set_signature(signature); 473ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn} 474ccf90703bb6989e659b12a6494e84fdb921008edDarren Krahn 475594849c7cf872d055575277b930f4f596bef1988Darren Krahnvoid AttestationService::RegisterKeyWithChapsToken( 476594849c7cf872d055575277b930f4f596bef1988Darren Krahn const RegisterKeyWithChapsTokenRequest& request, 477594849c7cf872d055575277b930f4f596bef1988Darren Krahn const RegisterKeyWithChapsTokenCallback& callback) { 478594849c7cf872d055575277b930f4f596bef1988Darren Krahn auto result = std::make_shared<RegisterKeyWithChapsTokenReply>(); 479594849c7cf872d055575277b930f4f596bef1988Darren Krahn base::Closure task = base::Bind( 480594849c7cf872d055575277b930f4f596bef1988Darren Krahn &AttestationService::RegisterKeyWithChapsTokenTask, 481594849c7cf872d055575277b930f4f596bef1988Darren Krahn base::Unretained(this), 482594849c7cf872d055575277b930f4f596bef1988Darren Krahn request, 483594849c7cf872d055575277b930f4f596bef1988Darren Krahn result); 484594849c7cf872d055575277b930f4f596bef1988Darren Krahn base::Closure reply = base::Bind( 485594849c7cf872d055575277b930f4f596bef1988Darren Krahn &AttestationService::TaskRelayCallback<RegisterKeyWithChapsTokenReply>, 486594849c7cf872d055575277b930f4f596bef1988Darren Krahn GetWeakPtr(), 487594849c7cf872d055575277b930f4f596bef1988Darren Krahn callback, 488594849c7cf872d055575277b930f4f596bef1988Darren Krahn result); 489594849c7cf872d055575277b930f4f596bef1988Darren Krahn worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, task, reply); 490594849c7cf872d055575277b930f4f596bef1988Darren Krahn} 491594849c7cf872d055575277b930f4f596bef1988Darren Krahn 492594849c7cf872d055575277b930f4f596bef1988Darren Krahnvoid AttestationService::RegisterKeyWithChapsTokenTask( 493594849c7cf872d055575277b930f4f596bef1988Darren Krahn const RegisterKeyWithChapsTokenRequest& request, 494594849c7cf872d055575277b930f4f596bef1988Darren Krahn const std::shared_ptr<RegisterKeyWithChapsTokenReply>& result) { 495594849c7cf872d055575277b930f4f596bef1988Darren Krahn CertifiedKey key; 496594849c7cf872d055575277b930f4f596bef1988Darren Krahn if (!FindKeyByLabel(request.username(), request.key_label(), &key)) { 497594849c7cf872d055575277b930f4f596bef1988Darren Krahn result->set_status(STATUS_INVALID_PARAMETER); 498594849c7cf872d055575277b930f4f596bef1988Darren Krahn return; 499594849c7cf872d055575277b930f4f596bef1988Darren Krahn } 500594849c7cf872d055575277b930f4f596bef1988Darren Krahn if (!key_store_->Register(request.username(), request.key_label(), 501594849c7cf872d055575277b930f4f596bef1988Darren Krahn key.key_type(), key.key_usage(), key.key_blob(), 502594849c7cf872d055575277b930f4f596bef1988Darren Krahn key.public_key(), key.certified_key_credential())) { 503594849c7cf872d055575277b930f4f596bef1988Darren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 504594849c7cf872d055575277b930f4f596bef1988Darren Krahn return; 505594849c7cf872d055575277b930f4f596bef1988Darren Krahn } 506594849c7cf872d055575277b930f4f596bef1988Darren Krahn if (key.has_intermediate_ca_cert() && 507594849c7cf872d055575277b930f4f596bef1988Darren Krahn !key_store_->RegisterCertificate(request.username(), 508594849c7cf872d055575277b930f4f596bef1988Darren Krahn key.intermediate_ca_cert())) { 509594849c7cf872d055575277b930f4f596bef1988Darren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 510594849c7cf872d055575277b930f4f596bef1988Darren Krahn return; 511594849c7cf872d055575277b930f4f596bef1988Darren Krahn } 512594849c7cf872d055575277b930f4f596bef1988Darren Krahn for (int i = 0; i < key.additional_intermediate_ca_cert_size(); ++i) { 513594849c7cf872d055575277b930f4f596bef1988Darren Krahn if (!key_store_->RegisterCertificate( 514594849c7cf872d055575277b930f4f596bef1988Darren Krahn request.username(), 515594849c7cf872d055575277b930f4f596bef1988Darren Krahn key.additional_intermediate_ca_cert(i))) { 516594849c7cf872d055575277b930f4f596bef1988Darren Krahn result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); 517594849c7cf872d055575277b930f4f596bef1988Darren Krahn return; 518594849c7cf872d055575277b930f4f596bef1988Darren Krahn } 519594849c7cf872d055575277b930f4f596bef1988Darren Krahn } 520594849c7cf872d055575277b930f4f596bef1988Darren Krahn DeleteKey(request.username(), request.key_label()); 521594849c7cf872d055575277b930f4f596bef1988Darren Krahn} 522594849c7cf872d055575277b930f4f596bef1988Darren Krahn 523d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbool AttestationService::IsPreparedForEnrollment() { 524d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!tpm_utility_->IsTpmReady()) { 525d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 526d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 527d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn auto database_pb = database_->GetProtobuf(); 528d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!database_pb.has_credentials()) { 529d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 530d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 531d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return (database_pb.credentials().has_endorsement_credential() || 532d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb.credentials() 533d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn .has_default_encrypted_endorsement_credential()); 534d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 535d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 536d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbool AttestationService::IsEnrolled() { 537d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn auto database_pb = database_->GetProtobuf(); 538d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return database_pb.has_identity_key() && 539d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb.identity_key().has_identity_credential(); 540d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 541d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 542d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbool AttestationService::CreateEnrollRequest(std::string* enroll_request) { 543d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!IsPreparedForEnrollment()) { 544d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Enrollment is not possible, attestation data " 545d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn << "does not exist."; 546d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 547d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 548d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn auto database_pb = database_->GetProtobuf(); 549d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn AttestationEnrollmentRequest request_pb; 550d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn *request_pb.mutable_encrypted_endorsement_credential() = 551d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb.credentials().default_encrypted_endorsement_credential(); 552d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn request_pb.set_identity_public_key( 553d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb.identity_binding().identity_public_key()); 554d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn *request_pb.mutable_pcr0_quote() = database_pb.pcr0_quote(); 555d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn *request_pb.mutable_pcr1_quote() = database_pb.pcr1_quote(); 556d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!request_pb.SerializeToString(enroll_request)) { 557d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Failed to serialize protobuf."; 558d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 559d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 560d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return true; 561d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 562d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 563d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbool AttestationService::FinishEnroll(const std::string& enroll_response, 564d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string* server_error) { 565d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!tpm_utility_->IsTpmReady()) { 566d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 567d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 568d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn AttestationEnrollmentResponse response_pb; 569d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!response_pb.ParseFromString(enroll_response)) { 570d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Failed to parse response from CA."; 571d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 572d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 573d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (response_pb.status() != OK) { 574d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn *server_error = response_pb.detail(); 575d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Error received from CA: " 576d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn << response_pb.detail(); 577d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 578d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 579d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string credential; 580d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn auto database_pb = database_->GetProtobuf(); 581d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!tpm_utility_->ActivateIdentity( 582d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb.delegate().blob(), 583d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb.delegate().secret(), 584d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb.identity_key().identity_key_blob(), 585d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn response_pb.encrypted_identity_credential().asym_ca_contents(), 586d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn response_pb.encrypted_identity_credential().sym_ca_attestation(), 587d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn &credential)) { 588d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Failed to activate identity."; 589d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 590d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 591d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_->GetMutableProtobuf()->mutable_identity_key()-> 592d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn set_identity_credential(credential); 593d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!database_->SaveChanges()) { 594d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Failed to persist database changes."; 595d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 596d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 597d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(INFO) << "Attestation: Enrollment complete."; 598d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return true; 599d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 600d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 601d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbool AttestationService::CreateCertificateRequest( 602d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& username, 60362c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn const CertifiedKey& key, 604d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn CertificateProfile profile, 605d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& origin, 606d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string* certificate_request, 607d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string* message_id) { 608d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!tpm_utility_->IsTpmReady()) { 609d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 610d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 611d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!IsEnrolled()) { 612d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Device is not enrolled for attestation."; 613d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 614d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 615d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn AttestationCertificateRequest request_pb; 616d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!crypto_utility_->GetRandom(kNonceSize, message_id)) { 617d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": GetRandom(message_id) failed."; 618d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 619d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 620d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn request_pb.set_message_id(*message_id); 621d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn auto database_pb = database_->GetProtobuf(); 622d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn request_pb.set_identity_credential( 623d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb.identity_key().identity_credential()); 624d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn request_pb.set_profile(profile); 625d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!origin.empty() && 626d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn (profile == CONTENT_PROTECTION_CERTIFICATE_WITH_STABLE_ID)) { 627d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn request_pb.set_origin(origin); 628d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn request_pb.set_temporal_index(ChooseTemporalIndex(username, origin)); 629d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 63008d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn request_pb.set_certified_public_key(key.public_key_tpm_format()); 63108d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn request_pb.set_certified_key_info(key.certified_key_info()); 63208d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn request_pb.set_certified_key_proof(key.certified_key_proof()); 633d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!request_pb.SerializeToString(certificate_request)) { 634d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Failed to serialize protobuf."; 635d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 636d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 637d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return true; 638d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 639d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 640d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbool AttestationService::FinishCertificateRequest( 641d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& certificate_response, 642d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& username, 643d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& key_label, 644d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& message_id, 64562c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn CertifiedKey* key, 646d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string* certificate_chain, 647d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string* server_error) { 648d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!tpm_utility_->IsTpmReady()) { 649d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 650d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 651d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn AttestationCertificateResponse response_pb; 652d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!response_pb.ParseFromString(certificate_response)) { 653d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Failed to parse response from Privacy CA."; 654d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 655d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 656d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (response_pb.status() != OK) { 657d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn *server_error = response_pb.detail(); 658d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Error received from Privacy CA: " 659d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn << response_pb.detail(); 660d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 661d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 662d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (message_id != response_pb.message_id()) { 663d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Message ID mismatch."; 664d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 665d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 666d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 667d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn // Finish populating the CertifiedKey protobuf and store it. 66862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn key->set_certified_key_credential(response_pb.certified_key_credential()); 66962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn key->set_intermediate_ca_cert(response_pb.intermediate_ca_cert()); 67062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn key->mutable_additional_intermediate_ca_cert()->MergeFrom( 671d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn response_pb.additional_intermediate_ca_cert()); 67262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn if (!SaveKey(username, key_label, *key)) { 673d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 674d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 675d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(INFO) << "Attestation: Certified key credential received and stored."; 67662c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn *certificate_chain = CreatePEMCertificateChain(*key); 677d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return true; 678d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 679d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 680d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbool AttestationService::SendACARequestAndBlock(ACARequestType request_type, 681d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& request, 682d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string* reply) { 683e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko std::shared_ptr<brillo::http::Transport> transport = http_transport_; 684d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!transport) { 685e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko transport = brillo::http::Transport::CreateDefault(); 686d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 687e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko std::unique_ptr<brillo::http::Response> response = PostBinaryAndBlock( 688d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn GetACAURL(request_type), 689d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn request.data(), 690d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn request.size(), 691e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko brillo::mime::application::kOctet_stream, 692d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn {}, // headers 693d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn transport, 694d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn nullptr); // error 695d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!response || !response->IsSuccessful()) { 696d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << "HTTP request to Attestation CA failed."; 697d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 698d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 699d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn *reply = response->ExtractDataAsString(); 700d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return true; 701d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 702d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 703d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbool AttestationService::FindKeyByLabel(const std::string& username, 704d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& key_label, 705d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn CertifiedKey* key) { 706d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!username.empty()) { 707d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string key_data; 708d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!key_store_->Read(username, key_label, &key_data)) { 709d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(INFO) << "Key not found: " << key_label; 710d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 711d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 712d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (key && !key->ParseFromString(key_data)) { 713d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << "Failed to parse key: " << key_label; 714d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 715d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 716d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return true; 717d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 718d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn auto database_pb = database_->GetProtobuf(); 719d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn for (int i = 0; i < database_pb.device_keys_size(); ++i) { 720d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (database_pb.device_keys(i).key_name() == key_label) { 721d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn *key = database_pb.device_keys(i); 722d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return true; 723d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 724d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 725d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(INFO) << "Key not found: " << key_label; 726d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 727d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 728d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 729d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbool AttestationService::CreateKey(const std::string& username, 730d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& key_label, 731d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn KeyType key_type, 73262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn KeyUsage key_usage, 73362c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn CertifiedKey* key) { 73408d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn std::string nonce; 73508d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn if (!crypto_utility_->GetRandom(kNonceSize, &nonce)) { 73608d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn LOG(ERROR) << __func__ << ": GetRandom(nonce) failed."; 73708d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn return false; 73808d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn } 739d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string key_blob; 740d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string public_key; 74108d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn std::string public_key_tpm_format; 74208d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn std::string key_info; 74308d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn std::string proof; 74408d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn auto database_pb = database_->GetProtobuf(); 74508d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn if (!tpm_utility_->CreateCertifiedKey( 74608d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn key_type, 74708d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn key_usage, 74808d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn database_pb.identity_key().identity_key_blob(), 74908d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn nonce, 75008d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn &key_blob, 75108d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn &public_key, 75208d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn &public_key_tpm_format, 75308d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn &key_info, 75408d544a489c1a2608b01ff240bddb26d4a92b277Darren Krahn &proof)) { 755d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 756d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 75762c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn key->set_key_blob(key_blob); 75862c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn key->set_public_key(public_key); 75962c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn key->set_key_name(key_label); 76062c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn key->set_public_key_tpm_format(public_key_tpm_format); 76162c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn key->set_certified_key_info(key_info); 76262c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn key->set_certified_key_proof(proof); 76362c73fa5a343fbbf6a0b0176dd789352b85c44e5Darren Krahn return SaveKey(username, key_label, *key); 764d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 765d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 766d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbool AttestationService::SaveKey(const std::string& username, 767d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& key_label, 768d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const CertifiedKey& key) { 769d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!username.empty()) { 770d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string key_data; 771d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!key.SerializeToString(&key_data)) { 772d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Failed to serialize protobuf."; 773d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 774d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 775d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!key_store_->Write(username, key_label, key_data)) { 776d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Failed to store certified key for user."; 777d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 778d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 779d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } else { 780d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!AddDeviceKey(key_label, key)) { 781d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(ERROR) << __func__ << ": Failed to store certified key for device."; 782d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return false; 783d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 784d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 785d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return true; 786d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 787d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 788d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnvoid AttestationService::DeleteKey(const std::string& username, 789d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& key_label) { 790d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!username.empty()) { 791d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn key_store_->Delete(username, key_label); 792d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } else { 793d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn RemoveDeviceKey(key_label); 794d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 795d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 796d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 797d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbool AttestationService::AddDeviceKey(const std::string& key_label, 798d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const CertifiedKey& key) { 799d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn // If a key by this name already exists, reuse the field. 800d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn auto* database_pb = database_->GetMutableProtobuf(); 801d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn bool found = false; 802d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn for (int i = 0; i < database_pb->device_keys_size(); ++i) { 803d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (database_pb->device_keys(i).key_name() == key_label) { 804d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn found = true; 805d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn *database_pb->mutable_device_keys(i) = key; 806d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn break; 807d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 808d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 809d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!found) 810d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn *database_pb->add_device_keys() = key; 811d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return database_->SaveChanges(); 812d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 813d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 814d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnvoid AttestationService::RemoveDeviceKey(const std::string& key_label) { 815d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn auto* database_pb = database_->GetMutableProtobuf(); 816d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn bool found = false; 817d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn for (int i = 0; i < database_pb->device_keys_size(); ++i) { 818d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (database_pb->device_keys(i).key_name() == key_label) { 819d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn found = true; 820d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn int last = database_pb->device_keys_size() - 1; 821d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (i < last) { 822d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb->mutable_device_keys()->SwapElements(i, last); 823d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 824d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb->mutable_device_keys()->RemoveLast(); 825d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn break; 826d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 827d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 828d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (found) { 829d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!database_->SaveChanges()) { 830d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(WARNING) << __func__ << ": Failed to persist key deletion."; 831d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 832d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 833d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 834d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 835d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnstd::string AttestationService::CreatePEMCertificateChain( 836d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const CertifiedKey& key) { 837d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (key.certified_key_credential().empty()) { 838d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(WARNING) << "Certificate is empty."; 839d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return std::string(); 840d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 841d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string pem = CreatePEMCertificate(key.certified_key_credential()); 842d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (!key.intermediate_ca_cert().empty()) { 843d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn pem += "\n"; 844d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn pem += CreatePEMCertificate(key.intermediate_ca_cert()); 845d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 846d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn for (int i = 0; i < key.additional_intermediate_ca_cert_size(); ++i) { 847d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn pem += "\n"; 848d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn pem += CreatePEMCertificate(key.additional_intermediate_ca_cert(i)); 849d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 850d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return pem; 851d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 852d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 853d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnstd::string AttestationService::CreatePEMCertificate( 854d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& certificate) { 855d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const char kBeginCertificate[] = "-----BEGIN CERTIFICATE-----\n"; 856d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const char kEndCertificate[] = "-----END CERTIFICATE-----"; 857d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 858d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string pem = kBeginCertificate; 859e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko pem += brillo::data_encoding::Base64EncodeWrapLines(certificate); 860d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn pem += kEndCertificate; 861d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return pem; 862d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 863d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 864d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 865d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnint AttestationService::ChooseTemporalIndex(const std::string& user, 866d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const std::string& origin) { 867d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string user_hash = crypto::SHA256HashString(user); 868d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string origin_hash = crypto::SHA256HashString(origin); 869d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn int histogram[kNumTemporalValues] = {}; 870d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn auto database_pb = database_->GetProtobuf(); 871d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn for (int i = 0; i < database_pb.temporal_index_record_size(); ++i) { 872d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn const AttestationDatabase::TemporalIndexRecord& record = 873d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb.temporal_index_record(i); 874d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn // Ignore out-of-range index values. 875d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (record.temporal_index() < 0 || 876d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn record.temporal_index() >= kNumTemporalValues) 877d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn continue; 878d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (record.origin_hash() == origin_hash) { 879d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (record.user_hash() == user_hash) { 880d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn // We've previously chosen this index for this user, reuse it. 881d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return record.temporal_index(); 882d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } else { 883d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn // We've previously chosen this index for another user. 884d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn ++histogram[record.temporal_index()]; 885d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 886d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 887d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 888d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn int least_used_index = 0; 889d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn for (int i = 1; i < kNumTemporalValues; ++i) { 890d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (histogram[i] < histogram[least_used_index]) 891d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn least_used_index = i; 892d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 893d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn if (histogram[least_used_index] > 0) { 894d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn LOG(WARNING) << "Unique origin-specific identifiers have been exhausted."; 895d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 896d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn // Record our choice for later reference. 897d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn AttestationDatabase::TemporalIndexRecord* new_record = 898d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_pb.add_temporal_index_record(); 899d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn new_record->set_origin_hash(origin_hash); 900d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn new_record->set_user_hash(user_hash); 901d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn new_record->set_temporal_index(least_used_index); 902d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn database_->SaveChanges(); 903d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return least_used_index; 904d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 905d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 906d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnstd::string AttestationService::GetACAURL(ACARequestType request_type) const { 907d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn std::string url = attestation_ca_origin_; 908d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn switch (request_type) { 909d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn case kEnroll: 910d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn url += "/enroll"; 911d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn break; 912d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn case kGetCertificate: 913d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn url += "/sign"; 914d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn break; 915d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn default: 916d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn NOTREACHED(); 917d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn } 918d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return url; 919d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn} 920d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn 9216222defa52eb13c0d90673f642f2647f7753478bDarren Krahnbool AttestationService::GetSubjectPublicKeyInfo( 9226222defa52eb13c0d90673f642f2647f7753478bDarren Krahn KeyType key_type, 9236222defa52eb13c0d90673f642f2647f7753478bDarren Krahn const std::string& public_key, 9246222defa52eb13c0d90673f642f2647f7753478bDarren Krahn std::string* public_key_info) const { 9256222defa52eb13c0d90673f642f2647f7753478bDarren Krahn // Only RSA is supported currently. 9266222defa52eb13c0d90673f642f2647f7753478bDarren Krahn if (key_type != KEY_TYPE_RSA) { 9276222defa52eb13c0d90673f642f2647f7753478bDarren Krahn return false; 9286222defa52eb13c0d90673f642f2647f7753478bDarren Krahn } 9296222defa52eb13c0d90673f642f2647f7753478bDarren Krahn return crypto_utility_->GetRSASubjectPublicKeyInfo(public_key, 9306222defa52eb13c0d90673f642f2647f7753478bDarren Krahn public_key_info); 9316222defa52eb13c0d90673f642f2647f7753478bDarren Krahn} 9326222defa52eb13c0d90673f642f2647f7753478bDarren Krahn 933d66389850c33614ffbbbbc3f768621182fd853baDarren Krahnbase::WeakPtr<AttestationService> AttestationService::GetWeakPtr() { 934d66389850c33614ffbbbbc3f768621182fd853baDarren Krahn return weak_factory_.GetWeakPtr(); 9356bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen} 9366bead48129845a2bc0d6ff347f3d7e232004d59Nam T. Nguyen 937ab0cddda9971f97781fc9f6cbc76095ba7542abfAlex Vakulenko} // namespace attestation 938