enterprise_platform_keys_private_api.cc revision 5e3f23d412006dc4db4e659864679f29341e113f
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" 135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/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) 42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char EPKPChallengeKeyBase::kChallengeBadBase64Error[] = 43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "Challenge is not base64 encoded."; 44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char EPKPChallengeKeyBase::kDevicePolicyDisabledError[] = 45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "Remote attestation is not enabled for your device."; 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char EPKPChallengeKeyBase::kExtensionNotWhitelistedError[] = 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "The extension does not have permission to call this function."; 48b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char EPKPChallengeKeyBase::kResponseBadBase64Error[] = 49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "Response cannot be encoded in base64."; 50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char EPKPChallengeKeyBase::kSignChallengeFailedError[] = 51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "Failed to sign the challenge."; 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char EPKPChallengeKeyBase::kUserNotManaged[] = 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "The user account is not enterprise managed."; 54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EPKPChallengeKeyBase::EPKPChallengeKeyBase() 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : cryptohome_client_( 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::DBusThreadManager::Get()->GetCryptohomeClient()), 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_caller_(cryptohome::AsyncMethodCaller::GetInstance()), 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) install_attributes_(g_browser_process->browser_policy_connector()-> 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetInstallAttributes()) { 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<chromeos::attestation::ServerProxy> ca_client( 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new chromeos::attestation::AttestationCAClient()); 63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) default_attestation_flow_.reset( 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new chromeos::attestation::AttestationFlow( 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_caller_, cryptohome_client_, ca_client.Pass())); 66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) attestation_flow_ = default_attestation_flow_.get(); 67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)EPKPChallengeKeyBase::EPKPChallengeKeyBase( 70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) chromeos::CryptohomeClient* cryptohome_client, 71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) cryptohome::AsyncMethodCaller* async_caller, 72b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) chromeos::attestation::AttestationFlow* attestation_flow, 73b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) policy::EnterpriseInstallAttributes* install_attributes) : 74b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) cryptohome_client_(cryptohome_client), 75b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) async_caller_(async_caller), 76b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) attestation_flow_(attestation_flow), 77b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) install_attributes_(install_attributes) { 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EPKPChallengeKeyBase::~EPKPChallengeKeyBase() { 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::GetDeviceAttestationEnabled( 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(bool)>& callback) const { 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::CrosSettings* settings = chromeos::CrosSettings::Get(); 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::CrosSettingsProvider::TrustedStatus status = 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) settings->PrepareTrustedValues( 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeKeyBase::GetDeviceAttestationEnabled, this, 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback)); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool value = false; 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (status) { 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case chromeos::CrosSettingsProvider::TRUSTED: 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!settings->GetBoolean(chromeos::kDeviceAttestationEnabled, &value)) 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) value = false; 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED: 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Do nothing. This function will be called again when the values are 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // ready. 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case chromeos::CrosSettingsProvider::PERMANENTLY_UNTRUSTED: 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the value cannot be trusted, we assume that the device attestation 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // is false to be on the safe side. 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(value); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EPKPChallengeKeyBase::IsEnterpriseDevice() const { 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return install_attributes_->IsEnterpriseDevice(); 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool EPKPChallengeKeyBase::IsExtensionWhitelisted() const { 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::ListValue* list = 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) profile()->GetPrefs()->GetList(prefs::kAttestationExtensionWhitelist); 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StringValue value(extension_->id()); 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return list->Find(value) != list->end(); 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool EPKPChallengeKeyBase::IsUserManaged() const { 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string email = GetUserEmail(); 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(davidyu): Use BrowserPolicyConnector::GetUserAffiliation() and fix 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // the test. 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return email.empty() ? false : 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gaia::ExtractDomainName(email) == GetEnterpriseDomain(); 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string EPKPChallengeKeyBase::GetEnterpriseDomain() const { 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return install_attributes_->GetDomain(); 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string EPKPChallengeKeyBase::GetUserEmail() const { 135a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) SigninManagerBase* signin_manager = 136a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) SigninManagerFactory::GetForProfile(profile()); 137a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!signin_manager) 138a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return std::string(); 139a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return gaia::CanonicalizeEmail(signin_manager->GetAuthenticatedUsername()); 141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 142a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string EPKPChallengeKeyBase::GetDeviceId() const { 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return install_attributes_->GetDeviceId(); 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::PrepareKey( 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::AttestationKeyType key_type, 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& key_name, 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::AttestationCertificateProfile certificate_profile, 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool require_user_consent, 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback) { 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cryptohome_client_->TpmAttestationDoesKeyExist( 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key_type, key_name, base::Bind( 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &EPKPChallengeKeyBase::DoesKeyExistCallback, this, 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) certificate_profile, require_user_consent, callback)); 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::DoesKeyExistCallback( 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::AttestationCertificateProfile certificate_profile, 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool require_user_consent, 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback, 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::DBusMethodCallStatus status, 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool result) { 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status == chromeos::DBUS_METHOD_CALL_FAILURE) { 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(PREPARE_KEY_DBUS_ERROR); 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result) { 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The key exists. Do nothing more. 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(PREPARE_KEY_OK); 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The key does not exist. Create a new key and have it signed by PCA. 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (require_user_consent) { 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We should ask the user explicitly before sending any private 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // information to PCA. 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AskForUserConsent( 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeKeyBase::AskForUserConsentCallback, this, 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) certificate_profile, callback)); 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // User consent is not required. Skip to the next step. 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AskForUserConsentCallback(certificate_profile, callback, true); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::AskForUserConsent( 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(bool)>& callback) const { 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(davidyu): right now we just simply reject the request before we have 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // a way to ask for user consent. 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(false); 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::AskForUserConsentCallback( 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::AttestationCertificateProfile certificate_profile, 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback, 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool result) { 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result) { 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The user rejects the request. 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(PREPARE_KEY_USER_REJECTED); 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Generate a new key and have it signed by PCA. 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) attestation_flow_->GetCertificate( 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) certificate_profile, 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true, // Force a new key to be generated. 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeKeyBase::GetCertificateCallback, this, 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback)); 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeKeyBase::GetCertificateCallback( 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback, 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success, 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& pem_certificate_chain) { 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!success) { 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(PREPARE_KEY_GET_CERTIFICATE_FAILED); 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(PREPARE_KEY_OK); 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation of ChallengeMachineKey() 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 227b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char EPKPChallengeMachineKey::kGetCertificateFailedError[] = 228b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "Failed to get Enterprise machine certificate. Error code = %d"; 229b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char EPKPChallengeMachineKey::kNonEnterpriseDeviceError[] = 230b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "The device is not enterprise enrolled."; 231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char EPKPChallengeMachineKey::kKeyName[] = "attest-ent-machine"; 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 234b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)EPKPChallengeMachineKey::EPKPChallengeMachineKey() : EPKPChallengeKeyBase() { 235b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 236b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 237b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)EPKPChallengeMachineKey::EPKPChallengeMachineKey( 238b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) chromeos::CryptohomeClient* cryptohome_client, 239b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) cryptohome::AsyncMethodCaller* async_caller, 240b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) chromeos::attestation::AttestationFlow* attestation_flow, 241b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) policy::EnterpriseInstallAttributes* install_attributes) : 242b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EPKPChallengeKeyBase(cryptohome_client, 243b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) async_caller, 244b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) attestation_flow, 245b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) install_attributes) { 246b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EPKPChallengeMachineKey::~EPKPChallengeMachineKey() { 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EPKPChallengeMachineKey::RunImpl() { 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<api_epkp::ChallengeMachineKey::Params> 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params(api_epkp::ChallengeMachineKey::Params::Create(*args_)); 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string challenge; 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!base::Base64Decode(params->challenge, &challenge)) { 258b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kChallengeBadBase64Error); 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if the device is enterprise enrolled. 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsEnterpriseDevice()) { 264b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kNonEnterpriseDeviceError); 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Check if the extension is whitelisted in the user policy. 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!IsExtensionWhitelisted()) { 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetError(kExtensionNotWhitelistedError); 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Check if the user domain is the same as the enrolled enterprise domain. 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!IsUserManaged()) { 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetError(kUserNotManaged); 277a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 278a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 279a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if RA is enabled in the device policy. 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDeviceAttestationEnabled( 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback, 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, challenge)); 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback( 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& challenge, bool enabled) { 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!enabled) { 291b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kDevicePolicyDisabledError); 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrepareKey(chromeos::attestation::KEY_DEVICE, 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kKeyName, 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE, 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false, // user consent is not required. 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeMachineKey::PrepareKeyCallback, this, 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) challenge)); 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeMachineKey::PrepareKeyCallback( 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& challenge, PrepareKeyResult result) { 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result != PREPARE_KEY_OK) { 307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(base::StringPrintf(kGetCertificateFailedError, result)); 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Everything is checked. Sign the challenge. 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_caller_->TpmAttestationSignEnterpriseChallenge( 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::KEY_DEVICE, 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kKeyName, 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetEnterpriseDomain(), 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDeviceId(), 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::CHALLENGE_OPTION_NONE, 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) challenge, 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeMachineKey::SignChallengeCallback, this)); 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeMachineKey::SignChallengeCallback( 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success, const std::string& response) { 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!success) { 326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kSignChallengeFailedError); 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string encoded_response; 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!base::Base64Encode(response, &encoded_response)) { 333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kResponseBadBase64Error); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) results_ = api_epkp::ChallengeMachineKey::Results::Create(encoded_response); 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(true); 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation of ChallengeUserKey() 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 344b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char EPKPChallengeUserKey::kGetCertificateFailedError[] = 345b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "Failed to get Enterprise user certificate. Error code = %d"; 346b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char EPKPChallengeUserKey::kKeyRegistrationFailedError[] = 347b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "Key registration failed."; 348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char EPKPChallengeUserKey::kUserPolicyDisabledError[] = 349b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "Remote attestation is not enabled for your account."; 350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char EPKPChallengeUserKey::kKeyName[] = "attest-ent-user"; 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 353b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)EPKPChallengeUserKey::EPKPChallengeUserKey() : EPKPChallengeKeyBase() { 354b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 356b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)EPKPChallengeUserKey::EPKPChallengeUserKey( 357b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) chromeos::CryptohomeClient* cryptohome_client, 358b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) cryptohome::AsyncMethodCaller* async_caller, 359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) chromeos::attestation::AttestationFlow* attestation_flow, 360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) policy::EnterpriseInstallAttributes* install_attributes) : 361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EPKPChallengeKeyBase(cryptohome_client, 362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) async_caller, 363b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) attestation_flow, 364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) install_attributes) { 365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EPKPChallengeUserKey::~EPKPChallengeUserKey() { 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeUserKey::RegisterUserPrefs( 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable* registry) { 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) registry->RegisterBooleanPref( 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) prefs::kAttestationEnabled, 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false, 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) registry->RegisterListPref(prefs::kAttestationExtensionWhitelist, 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EPKPChallengeUserKey::RunImpl() { 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<api_epkp::ChallengeUserKey::Params> params( 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) api_epkp::ChallengeUserKey::Params::Create(*args_)); 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string challenge; 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!base::Base64Decode(params->challenge, &challenge)) { 387b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kChallengeBadBase64Error); 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if RA is enabled in the user policy. 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsRemoteAttestationEnabledForUser()) { 393b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kUserPolicyDisabledError); 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if the extension is whitelisted in the user policy. 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsExtensionWhitelisted()) { 399b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kExtensionNotWhitelistedError); 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsEnterpriseDevice()) { 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if the user domain is the same as the enrolled enterprise domain. 40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!IsUserManaged()) { 40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetError(kUserNotManaged); 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if RA is enabled in the device policy. 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDeviceAttestationEnabled( 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeUserKey::GetDeviceAttestationEnabledCallback, 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) challenge, 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params->register_key, 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false)); // user consent is not required. 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // For personal devices, we don't need to check if RA is enabled in the 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // device, but we need to ask for user consent if the key does not exist. 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDeviceAttestationEnabledCallback( 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) challenge, 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params->register_key, 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true, // user consent is required. 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true); // attestation is enabled. 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeUserKey::GetDeviceAttestationEnabledCallback( 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& challenge, 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool register_key, 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool require_user_consent, 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool enabled) { 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!enabled) { 436b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kDevicePolicyDisabledError); 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrepareKey(chromeos::attestation::KEY_USER, 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kKeyName, 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE, 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) require_user_consent, 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeUserKey::PrepareKeyCallback, this, 44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) challenge, register_key)); 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeUserKey::PrepareKeyCallback(const std::string& challenge, 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool register_key, 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrepareKeyResult result) { 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result != PREPARE_KEY_OK) { 453b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(base::StringPrintf(kGetCertificateFailedError, result)); 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Everything is checked. Sign the challenge. 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_caller_->TpmAttestationSignEnterpriseChallenge( 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::KEY_USER, 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kKeyName, 46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetUserEmail(), 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDeviceId(), 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) register_key ? 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY : 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::CHALLENGE_OPTION_NONE, 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) challenge, 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeUserKey::SignChallengeCallback, this, 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) register_key)); 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeUserKey::SignChallengeCallback(bool register_key, 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success, 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& response) { 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!success) { 476b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kSignChallengeFailedError); 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (register_key) { 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_caller_->TpmAttestationRegisterKey( 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::attestation::KEY_USER, 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kKeyName, 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EPKPChallengeUserKey::RegisterKeyCallback, this, response)); 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RegisterKeyCallback(response, true, cryptohome::MOUNT_ERROR_NONE); 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EPKPChallengeUserKey::RegisterKeyCallback( 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& response, 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success, 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cryptohome::MountError return_code) { 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!success || return_code != cryptohome::MOUNT_ERROR_NONE) { 496b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kKeyRegistrationFailedError); 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string encoded_response; 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!base::Base64Encode(response, &encoded_response)) { 503b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SetError(kResponseBadBase64Error); 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(false); 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) results_ = api_epkp::ChallengeUserKey::Results::Create(encoded_response); 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(true); 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EPKPChallengeUserKey::IsRemoteAttestationEnabledForUser() const { 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return profile()->GetPrefs()->GetBoolean(prefs::kAttestationEnabled); 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace extensions 517