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