enterprise_platform_keys_private_api.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/base64.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/callback.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/message_loop.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/prefs/pref_service.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/stringprintf.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/browser_process.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/attestation/attestation_ca_client.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings_names.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/policy/browser_policy_connector.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/signin/signin_manager.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h" 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/api/enterprise_platform_keys_private.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/pref_names.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/attestation/attestation_constants.h" 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/attestation/attestation_flow.h" 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/cryptohome/async_method_caller.h" 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/cryptohome_client.h" 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/dbus_method_call_status.h" 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h" 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h" 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace extensions { 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace api_epkp = api::enterprise_platform_keys_private; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Base class 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EPKPChallengeKeyBase::EPKPChallengeKeyBase() 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : cryptohome_client_( 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::DBusThreadManager::Get()->GetCryptohomeClient()), 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_caller_(cryptohome::AsyncMethodCaller::GetInstance()), 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) install_attributes_(g_browser_process->browser_policy_connector()-> 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetInstallAttributes()) { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<chromeos::attestation::ServerProxy> ca_client( 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new chromeos::attestation::AttestationCAClient()); 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) attestation_flow_.reset( 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new chromeos::attestation::AttestationFlow( 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_caller_, cryptohome_client_, ca_client.Pass())); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EPKPChallengeKeyBase::~EPKPChallengeKeyBase() { 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::GetDeviceAttestationEnabled( 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(bool)>& callback) const { 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::CrosSettings* settings = chromeos::CrosSettings::Get(); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::CrosSettingsProvider::TrustedStatus status = 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) settings->PrepareTrustedValues( 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeKeyBase::GetDeviceAttestationEnabled, this, 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback)); 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool value = false; 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (status) { 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case chromeos::CrosSettingsProvider::TRUSTED: 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!settings->GetBoolean(chromeos::kDeviceAttestationEnabled, &value)) 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) value = false; 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED: 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Do nothing. This function will be called again when the values are 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // ready. 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case chromeos::CrosSettingsProvider::PERMANENTLY_UNTRUSTED: 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the value cannot be trusted, we assume that the device attestation 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // is false to be on the safe side. 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(value); 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EPKPChallengeKeyBase::IsEnterpriseDevice() const { 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return install_attributes_->IsEnterpriseDevice(); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string EPKPChallengeKeyBase::GetEnterpriseDomain() const { 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return install_attributes_->GetDomain(); 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string EPKPChallengeKeyBase::GetDeviceId() const { 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return install_attributes_->GetDeviceId(); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::PrepareKey( 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::AttestationKeyType key_type, 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& key_name, 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::AttestationCertificateProfile certificate_profile, 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool require_user_consent, 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback) { 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cryptohome_client_->TpmAttestationDoesKeyExist( 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key_type, key_name, base::Bind( 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &EPKPChallengeKeyBase::DoesKeyExistCallback, this, 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) certificate_profile, require_user_consent, callback)); 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::DoesKeyExistCallback( 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::AttestationCertificateProfile certificate_profile, 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool require_user_consent, 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback, 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::DBusMethodCallStatus status, 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool result) { 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status == chromeos::DBUS_METHOD_CALL_FAILURE) { 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(PREPARE_KEY_DBUS_ERROR); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result) { 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The key exists. Do nothing more. 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(PREPARE_KEY_OK); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The key does not exist. Create a new key and have it signed by PCA. 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (require_user_consent) { 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We should ask the user explicitly before sending any private 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // information to PCA. 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AskForUserConsent( 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeKeyBase::AskForUserConsentCallback, this, 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) certificate_profile, callback)); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // User consent is not required. Skip to the next step. 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AskForUserConsentCallback(certificate_profile, callback, true); 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::AskForUserConsent( 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(bool)>& callback) const { 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(davidyu): right now we just simply reject the request before we have 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // a way to ask for user consent. 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(false); 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::AskForUserConsentCallback( 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::AttestationCertificateProfile certificate_profile, 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback, 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool result) { 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result) { 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The user rejects the request. 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(PREPARE_KEY_USER_REJECTED); 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Generate a new key and have it signed by PCA. 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) attestation_flow_->GetCertificate( 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) certificate_profile, 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true, // Force a new key to be generated. 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeKeyBase::GetCertificateCallback, this, 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback)); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::GetCertificateCallback( 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback, 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success, 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& pem_certificate_chain) { 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!success) { 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(PREPARE_KEY_GET_CERTIFICATE_FAILED); 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(PREPARE_KEY_OK); 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation of ChallengeMachineKey() 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char EPKPChallengeMachineKey::kKeyName[] = "attest-ent-machine"; 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EPKPChallengeMachineKey::~EPKPChallengeMachineKey() { 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EPKPChallengeMachineKey::RunImpl() { 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<api_epkp::ChallengeMachineKey::Params> 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params(api_epkp::ChallengeMachineKey::Params::Create(*args_)); 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string challenge; 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!base::Base64Decode(params->challenge, &challenge)) { 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("Challenge is not base64 encoded."); 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if the device is enterprise enrolled. 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsEnterpriseDevice()) { 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("The device is not enterprise enrolled."); 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if RA is enabled in the device policy. 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDeviceAttestationEnabled( 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback, 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, challenge)); 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback( 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& challenge, bool enabled) { 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!enabled) { 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("Remote attestation is not enabled for your device."); 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrepareKey(chromeos::attestation::KEY_DEVICE, 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kKeyName, 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE, 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false, // user consent is not required. 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeMachineKey::PrepareKeyCallback, this, 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) challenge)); 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeMachineKey::PrepareKeyCallback( 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& challenge, PrepareKeyResult result) { 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result != PREPARE_KEY_OK) { 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError(base::StringPrintf( 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "Failed to get Enterprise machince certificate. Error code = %d", 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result)); 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Everything is checked. Sign the challenge. 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_caller_->TpmAttestationSignEnterpriseChallenge( 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::KEY_DEVICE, 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kKeyName, 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetEnterpriseDomain(), 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDeviceId(), 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::CHALLENGE_OPTION_NONE, 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) challenge, 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeMachineKey::SignChallengeCallback, this)); 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeMachineKey::SignChallengeCallback( 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success, const std::string& response) { 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!success) { 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("Challenge failed."); 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string encoded_response; 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!base::Base64Encode(response, &encoded_response)) { 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("Response cannot be encoded in base64."); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) results_ = api_epkp::ChallengeMachineKey::Results::Create(encoded_response); 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(true); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation of ChallengeUserKey() 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char EPKPChallengeUserKey::kKeyName[] = "attest-ent-user"; 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EPKPChallengeUserKey::~EPKPChallengeUserKey() { 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeUserKey::RegisterUserPrefs( 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable* registry) { 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) registry->RegisterBooleanPref( 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) prefs::kAttestationEnabled, 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false, 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) registry->RegisterListPref(prefs::kAttestationExtensionWhitelist, 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EPKPChallengeUserKey::RunImpl() { 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<api_epkp::ChallengeUserKey::Params> params( 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) api_epkp::ChallengeUserKey::Params::Create(*args_)); 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string challenge; 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!base::Base64Decode(params->challenge, &challenge)) { 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("Challenge is not base64 encoded."); 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if RA is enabled in the user policy. 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsRemoteAttestationEnabledForUser()) { 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("Remote attestation is not enabled for your account."); 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if the extension is whitelisted in the user policy. 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsExtensionWhitelisted()) { 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("The extension does not have permission to call this function."); 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string user_domain = GetUserDomain(); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsEnterpriseDevice()) { 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if the user domain is the same as the enrolled enterprise domain. 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string enterprise_domain = GetEnterpriseDomain(); 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (user_domain != enterprise_domain) { 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("User domain " + user_domain + " and Enterprise domain " + 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) enterprise_domain + " don't match"); 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if RA is enabled in the device policy. 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDeviceAttestationEnabled( 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeUserKey::GetDeviceAttestationEnabledCallback, 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) challenge, 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params->register_key, 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_domain, 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false)); // user consent is not required. 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // For personal devices, we don't need to check if RA is enabled in the 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // device, but we need to ask for user consent if the key does not exist. 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDeviceAttestationEnabledCallback( 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) challenge, 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params->register_key, 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_domain, 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true, // user consent is required. 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true); // attestation is enabled. 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeUserKey::GetDeviceAttestationEnabledCallback( 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& challenge, 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool register_key, 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& domain, 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool require_user_consent, 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool enabled) { 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!enabled) { 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("Remote attestation is not enabled for your device."); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrepareKey(chromeos::attestation::KEY_USER, 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kKeyName, 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE, 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) require_user_consent, 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeUserKey::PrepareKeyCallback, this, 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) challenge, register_key, domain)); 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeUserKey::PrepareKeyCallback(const std::string& challenge, 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool register_key, 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& domain, 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrepareKeyResult result) { 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result != PREPARE_KEY_OK) { 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError(base::StringPrintf( 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "Cannot get a key to sign the challenge. Error code = %d", result)); 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Everything is checked. Sign the challenge. 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_caller_->TpmAttestationSignEnterpriseChallenge( 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::KEY_USER, 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kKeyName, 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) domain, 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDeviceId(), 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) register_key ? 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY : 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::CHALLENGE_OPTION_NONE, 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) challenge, 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeUserKey::SignChallengeCallback, this, 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) register_key)); 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeUserKey::SignChallengeCallback(bool register_key, 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success, 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& response) { 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!success) { 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("Challenge failed."); 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (register_key) { 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_caller_->TpmAttestationRegisterKey( 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::KEY_USER, 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kKeyName, 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeUserKey::RegisterKeyCallback, this, response)); 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RegisterKeyCallback(response, true, cryptohome::MOUNT_ERROR_NONE); 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeUserKey::RegisterKeyCallback( 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& response, 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success, 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cryptohome::MountError return_code) { 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!success || return_code != cryptohome::MOUNT_ERROR_NONE) { 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("Key registration failed."); 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string encoded_response; 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!base::Base64Encode(response, &encoded_response)) { 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetError("Response cannot be encoded in base64."); 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) results_ = api_epkp::ChallengeUserKey::Results::Create(encoded_response); 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(true); 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EPKPChallengeUserKey::IsExtensionWhitelisted() const { 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue* list = 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile()->GetPrefs()->GetList(prefs::kAttestationExtensionWhitelist); 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringValue value(extension_->id()); 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return list->Find(value) != list->end(); 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EPKPChallengeUserKey::IsRemoteAttestationEnabledForUser() const { 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return profile()->GetPrefs()->GetBoolean(prefs::kAttestationEnabled); 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string EPKPChallengeUserKey::GetUserDomain() const { 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SigninManagerBase* signin_manager = 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SigninManagerFactory::GetForProfile(profile()); 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!signin_manager) 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return gaia::ExtractDomainName( 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gaia::CanonicalizeEmail(signin_manager->GetAuthenticatedUsername())); 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace extensions 449