enterprise_platform_keys_private_api.cc revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base64.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop/message_loop.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/prefs/pref_service.h" 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/stringprintf.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/browser_process.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/attestation/attestation_ca_client.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings_names.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/browser_policy_connector.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/signin/signin_manager.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/api/enterprise_platform_keys_private.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/attestation/attestation_constants.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/attestation/attestation_flow.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/cryptohome/async_method_caller.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/cryptohome_client.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_method_call_status.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions { 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace api_epkp = api::enterprise_platform_keys_private; 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base class 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char EPKPChallengeKeyBase::kChallengeBadBase64Error[] = 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Challenge is not base64 encoded."; 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char EPKPChallengeKeyBase::kDevicePolicyDisabledError[] = 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Remote attestation is not enabled for your device."; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char EPKPChallengeKeyBase::kExtensionNotWhitelistedError[] = 47a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch "The extension does not have permission to call this function."; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char EPKPChallengeKeyBase::kResponseBadBase64Error[] = 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Response cannot be encoded in base64."; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char EPKPChallengeKeyBase::kSignChallengeFailedError[] = 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Failed to sign the challenge."; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char EPKPChallengeKeyBase::kUserNotManaged[] = 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The user account is not enterprise managed."; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EPKPChallengeKeyBase::EPKPChallengeKeyBase() 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : cryptohome_client_( 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chromeos::DBusThreadManager::Get()->GetCryptohomeClient()), 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) async_caller_(cryptohome::AsyncMethodCaller::GetInstance()), 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install_attributes_(g_browser_process->browser_policy_connector()-> 60a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch GetInstallAttributes()) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<chromeos::attestation::ServerProxy> ca_client( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new chromeos::attestation::AttestationCAClient()); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_attestation_flow_.reset( 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new chromeos::attestation::AttestationFlow( 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_caller_, cryptohome_client_, ca_client.Pass())); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attestation_flow_ = default_attestation_flow_.get(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EPKPChallengeKeyBase::EPKPChallengeKeyBase( 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::CryptohomeClient* cryptohome_client, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cryptohome::AsyncMethodCaller* async_caller, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::attestation::AttestationFlow* attestation_flow, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy::EnterpriseInstallAttributes* install_attributes) : 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cryptohome_client_(cryptohome_client), 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_caller_(async_caller), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attestation_flow_(attestation_flow), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install_attributes_(install_attributes) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EPKPChallengeKeyBase::~EPKPChallengeKeyBase() { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EPKPChallengeKeyBase::GetDeviceAttestationEnabled( 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(bool)>& callback) const { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::CrosSettings* settings = chromeos::CrosSettings::Get(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::CrosSettingsProvider::TrustedStatus status = 876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) settings->PrepareTrustedValues( 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&EPKPChallengeKeyBase::GetDeviceAttestationEnabled, this, 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) callback)); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool value = false; 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) switch (status) { 9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case chromeos::CrosSettingsProvider::TRUSTED: 9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!settings->GetBoolean(chromeos::kDeviceAttestationEnabled, &value)) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = false; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED: 98424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Do nothing. This function will be called again when the values are 99424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // ready. 100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chromeos::CrosSettingsProvider::PERMANENTLY_UNTRUSTED: 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the value cannot be trusted, we assume that the device attestation 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is false to be on the safe side. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(value); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EPKPChallengeKeyBase::IsEnterpriseDevice() const { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return install_attributes_->IsEnterpriseDevice(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EPKPChallengeKeyBase::IsExtensionWhitelisted() const { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::ListValue* list = 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile()->GetPrefs()->GetList(prefs::kAttestationExtensionWhitelist); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringValue value(extension_->id()); 118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return list->Find(value) != list->end(); 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool EPKPChallengeKeyBase::IsUserManaged() const { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string email = GetUserEmail(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(davidyu): Use BrowserPolicyConnector::GetUserAffiliation() and fix 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the test. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return email.empty() ? false : 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gaia::ExtractDomainName(email) == GetEnterpriseDomain(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string EPKPChallengeKeyBase::GetEnterpriseDomain() const { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return install_attributes_->GetDomain(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string EPKPChallengeKeyBase::GetUserEmail() const { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SigninManagerBase* signin_manager = 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SigninManagerFactory::GetForProfile(profile()); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!signin_manager) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gaia::CanonicalizeEmail(signin_manager->GetAuthenticatedUsername()); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string EPKPChallengeKeyBase::GetDeviceId() const { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return install_attributes_->GetDeviceId(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EPKPChallengeKeyBase::PrepareKey( 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::attestation::AttestationKeyType key_type, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key_name, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::attestation::AttestationCertificateProfile certificate_profile, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool require_user_consent, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cryptohome_client_->TpmAttestationDoesKeyExist( 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_type, key_name, base::Bind( 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &EPKPChallengeKeyBase::DoesKeyExistCallback, this, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) certificate_profile, require_user_consent, callback)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void EPKPChallengeKeyBase::DoesKeyExistCallback( 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chromeos::attestation::AttestationCertificateProfile certificate_profile, 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool require_user_consent, 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback, 163bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch chromeos::DBusMethodCallStatus status, 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool result) { 165bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (status == chromeos::DBUS_METHOD_CALL_FAILURE) { 166bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch callback.Run(PREPARE_KEY_DBUS_ERROR); 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The key exists. Do nothing more. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(PREPARE_KEY_OK); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The key does not exist. Create a new key and have it signed by PCA. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (require_user_consent) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should ask the user explicitly before sending any private 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // information to PCA. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AskForUserConsent( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&EPKPChallengeKeyBase::AskForUserConsentCallback, this, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) certificate_profile, callback)); 1810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } else { 1820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // User consent is not required. Skip to the next step. 1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch AskForUserConsentCallback(certificate_profile, callback, true); 1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EPKPChallengeKeyBase::AskForUserConsent( 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Callback<void(bool)>& callback) const { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(davidyu): right now we just simply reject the request before we have 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // a way to ask for user consent. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(false); 193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EPKPChallengeKeyBase::AskForUserConsentCallback( 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::attestation::AttestationCertificateProfile certificate_profile, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The user rejects the request. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(PREPARE_KEY_USER_REJECTED); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Generate a new key and have it signed by PCA. 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) attestation_flow_->GetCertificate( 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) certificate_profile, 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true, // Force a new key to be generated. 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&EPKPChallengeKeyBase::GetCertificateCallback, this, 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback)); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EPKPChallengeKeyBase::GetCertificateCallback( 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(PrepareKeyResult)>& callback, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& pem_certificate_chain) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(PREPARE_KEY_GET_CERTIFICATE_FAILED); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(PREPARE_KEY_OK); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implementation of ChallengeMachineKey() 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char EPKPChallengeMachineKey::kGetCertificateFailedError[] = 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Failed to get Enterprise machine certificate. Error code = %d"; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char EPKPChallengeMachineKey::kNonEnterpriseDeviceError[] = 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The device is not enterprise enrolled."; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char EPKPChallengeMachineKey::kKeyName[] = "attest-ent-machine"; 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EPKPChallengeMachineKey::EPKPChallengeMachineKey() : EPKPChallengeKeyBase() { 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EPKPChallengeMachineKey::EPKPChallengeMachineKey( 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::CryptohomeClient* cryptohome_client, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cryptohome::AsyncMethodCaller* async_caller, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::attestation::AttestationFlow* attestation_flow, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy::EnterpriseInstallAttributes* install_attributes) : 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EPKPChallengeKeyBase(cryptohome_client, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_caller, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attestation_flow, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install_attributes) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EPKPChallengeMachineKey::~EPKPChallengeMachineKey() { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EPKPChallengeMachineKey::RunImpl() { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<api_epkp::ChallengeMachineKey::Params> 25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) params(api_epkp::ChallengeMachineKey::Params::Create(*args_)); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string challenge; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::Base64Decode(params->challenge, &challenge)) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(kChallengeBadBase64Error); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the device is enterprise enrolled. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsEnterpriseDevice()) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(kNonEnterpriseDeviceError); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the extension is whitelisted in the user policy. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsExtensionWhitelisted()) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(kExtensionNotWhitelistedError); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the user domain is the same as the enrolled enterprise domain. 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!IsUserManaged()) { 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetError(kUserNotManaged); 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Check if RA is enabled in the device policy. 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetDeviceAttestationEnabled( 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback, 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, challenge)); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback( 2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& challenge, bool enabled) { 2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!enabled) { 291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SetError(kDevicePolicyDisabledError); 292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SendResponse(false); 2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepareKey(chromeos::attestation::KEY_DEVICE, 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kKeyName, 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, // user consent is not required. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&EPKPChallengeMachineKey::PrepareKeyCallback, this, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) challenge)); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EPKPChallengeMachineKey::PrepareKeyCallback( 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& challenge, PrepareKeyResult result) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != PREPARE_KEY_OK) { 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetError(base::StringPrintf(kGetCertificateFailedError, result)); 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendResponse(false); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Everything is checked. Sign the challenge. 313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) async_caller_->TpmAttestationSignEnterpriseChallenge( 3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch chromeos::attestation::KEY_DEVICE, 3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kKeyName, 3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetEnterpriseDomain(), 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDeviceId(), 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::attestation::CHALLENGE_OPTION_NONE, 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) challenge, 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&EPKPChallengeMachineKey::SignChallengeCallback, this)); 321effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EPKPChallengeMachineKey::SignChallengeCallback( 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success, const std::string& response) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(kSignChallengeFailedError); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(false); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string encoded_response; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::Base64Encode(response, &encoded_response)) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(kResponseBadBase64Error); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(false); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = api_epkp::ChallengeMachineKey::Results::Create(encoded_response); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(true); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implementation of ChallengeUserKey() 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char EPKPChallengeUserKey::kGetCertificateFailedError[] = 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Failed to get Enterprise user certificate. Error code = %d"; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char EPKPChallengeUserKey::kKeyRegistrationFailedError[] = 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Key registration failed."; 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char EPKPChallengeUserKey::kUserPolicyDisabledError[] = 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Remote attestation is not enabled for your account."; 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char EPKPChallengeUserKey::kKeyName[] = "attest-ent-user"; 352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)EPKPChallengeUserKey::EPKPChallengeUserKey() : EPKPChallengeKeyBase() { 354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EPKPChallengeUserKey::EPKPChallengeUserKey( 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::CryptohomeClient* cryptohome_client, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cryptohome::AsyncMethodCaller* async_caller, 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::attestation::AttestationFlow* attestation_flow, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy::EnterpriseInstallAttributes* install_attributes) : 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EPKPChallengeKeyBase(cryptohome_client, 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_caller, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attestation_flow, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install_attributes) { 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 367d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)EPKPChallengeUserKey::~EPKPChallengeUserKey() { 368d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 369d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 370d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void EPKPChallengeUserKey::RegisterProfilePrefs( 371d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) user_prefs::PrefRegistrySyncable* registry) { 372d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) registry->RegisterBooleanPref( 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs::kAttestationEnabled, 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registry->RegisterListPref(prefs::kAttestationExtensionWhitelist, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EPKPChallengeUserKey::RunImpl() { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<api_epkp::ChallengeUserKey::Params> params( 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) api_epkp::ChallengeUserKey::Params::Create(*args_)); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string challenge; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::Base64Decode(params->challenge, &challenge)) { 387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SetError(kChallengeBadBase64Error); 388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Check if RA is enabled in the user policy. 392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!IsRemoteAttestationEnabledForUser()) { 393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SetError(kUserPolicyDisabledError); 394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the extension is whitelisted in the user policy. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsExtensionWhitelisted()) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(kExtensionNotWhitelistedError); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsEnterpriseDevice()) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the user domain is the same as the enrolled enterprise domain. 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsUserManaged()) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(kUserNotManaged); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if RA is enabled in the device policy. 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDeviceAttestationEnabled( 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&EPKPChallengeUserKey::GetDeviceAttestationEnabledCallback, 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) challenge, 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->register_key, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false)); // user consent is not required. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For personal devices, we don't need to check if RA is enabled in the 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // device, but we need to ask for user consent if the key does not exist. 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDeviceAttestationEnabledCallback( 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) challenge, 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->register_key, 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // user consent is required. 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true); // attestation is enabled. 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EPKPChallengeUserKey::GetDeviceAttestationEnabledCallback( 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& challenge, 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool register_key, 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool require_user_consent, 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled) { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!enabled) { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(kDevicePolicyDisabledError); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(false); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepareKey(chromeos::attestation::KEY_USER, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kKeyName, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE, 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) require_user_consent, 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&EPKPChallengeUserKey::PrepareKeyCallback, this, 44658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) challenge, register_key)); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EPKPChallengeUserKey::PrepareKeyCallback(const std::string& challenge, 4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool register_key, 4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrepareKeyResult result) { 4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (result != PREPARE_KEY_OK) { 4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetError(base::StringPrintf(kGetCertificateFailedError, result)); 4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SendResponse(false); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Everything is checked. Sign the challenge. 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) async_caller_->TpmAttestationSignEnterpriseChallenge( 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chromeos::attestation::KEY_USER, 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kKeyName, 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetUserEmail(), 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDeviceId(), 464424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) register_key ? 465424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) chromeos::attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY : 466424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) chromeos::attestation::CHALLENGE_OPTION_NONE, 467424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) challenge, 468424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&EPKPChallengeUserKey::SignChallengeCallback, this, 469010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) register_key)); 470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void EPKPChallengeUserKey::SignChallengeCallback(bool register_key, 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool success, 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& response) { 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!success) { 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetError(kSignChallengeFailedError); 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendResponse(false); 4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (register_key) { 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) async_caller_->TpmAttestationRegisterKey( 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chromeos::attestation::KEY_USER, 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kKeyName, 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&EPKPChallengeUserKey::RegisterKeyCallback, this, response)); 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 4870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RegisterKeyCallback(response, true, cryptohome::MOUNT_ERROR_NONE); 4880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 4890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EPKPChallengeUserKey::RegisterKeyCallback( 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& response, 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success, 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cryptohome::MountError return_code) { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success || return_code != cryptohome::MOUNT_ERROR_NONE) { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(kKeyRegistrationFailedError); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(false); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string encoded_response; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::Base64Encode(response, &encoded_response)) { 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(kResponseBadBase64Error); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(false); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = api_epkp::ChallengeUserKey::Results::Create(encoded_response); 509 SendResponse(true); 510} 511 512bool EPKPChallengeUserKey::IsRemoteAttestationEnabledForUser() const { 513 return profile()->GetPrefs()->GetBoolean(prefs::kAttestationEnabled); 514} 515 516} // namespace extensions 517