Home | History | Annotate | Download | only in enterprise_platform_keys_private
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h"
      6 
      7 #include <string>
      8 
      9 #include "base/bind.h"
     10 #include "base/location.h"
     11 #include "base/message_loop/message_loop_proxy.h"
     12 #include "base/prefs/pref_service.h"
     13 #include "base/strings/stringprintf.h"
     14 #include "base/values.h"
     15 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
     16 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
     17 #include "chrome/browser/extensions/extension_function_test_utils.h"
     18 #include "chrome/common/pref_names.h"
     19 #include "chrome/test/base/browser_with_test_window_test.h"
     20 #include "chromeos/attestation/attestation_constants.h"
     21 #include "chromeos/attestation/mock_attestation_flow.h"
     22 #include "chromeos/cryptohome/async_method_caller.h"
     23 #include "chromeos/cryptohome/mock_async_method_caller.h"
     24 #include "chromeos/dbus/dbus_method_call_status.h"
     25 #include "chromeos/dbus/mock_cryptohome_client.h"
     26 #include "chromeos/settings/cros_settings_provider.h"
     27 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
     28 #include "extensions/common/test_util.h"
     29 #include "testing/gmock/include/gmock/gmock.h"
     30 #include "testing/gtest/include/gtest/gtest.h"
     31 #include "third_party/cros_system_api/dbus/service_constants.h"
     32 
     33 using testing::_;
     34 using testing::Invoke;
     35 using testing::NiceMock;
     36 using testing::Return;
     37 using testing::WithArgs;
     38 
     39 namespace utils = extension_function_test_utils;
     40 
     41 namespace extensions {
     42 namespace {
     43 
     44 // Certificate errors as reported to the calling extension.
     45 const int kDBusError = 1;
     46 const int kUserRejected = 2;
     47 const int kGetCertificateFailed = 3;
     48 const int kResetRequired = 4;
     49 
     50 // A simple functor to invoke a callback with predefined arguments.
     51 class FakeBoolDBusMethod {
     52  public:
     53   FakeBoolDBusMethod(chromeos::DBusMethodCallStatus status, bool value)
     54       : status_(status),
     55         value_(value) {}
     56 
     57   void operator() (const chromeos::BoolDBusMethodCallback& callback) {
     58     base::MessageLoopProxy::current()->PostTask(
     59         FROM_HERE,
     60         base::Bind(callback, status_, value_));
     61   }
     62 
     63  private:
     64   chromeos::DBusMethodCallStatus status_;
     65   bool value_;
     66 };
     67 
     68 void RegisterKeyCallbackTrue(
     69     chromeos::attestation::AttestationKeyType key_type,
     70     const std::string& user_id,
     71     const std::string& key_name,
     72     const cryptohome::AsyncMethodCaller::Callback& callback) {
     73   base::MessageLoopProxy::current()->PostTask(
     74       FROM_HERE,
     75       base::Bind(callback, true, cryptohome::MOUNT_ERROR_NONE));
     76 }
     77 
     78 void RegisterKeyCallbackFalse(
     79     chromeos::attestation::AttestationKeyType key_type,
     80     const std::string& user_id,
     81     const std::string& key_name,
     82     const cryptohome::AsyncMethodCaller::Callback& callback) {
     83   base::MessageLoopProxy::current()->PostTask(
     84       FROM_HERE,
     85       base::Bind(callback, false, cryptohome::MOUNT_ERROR_NONE));
     86 }
     87 
     88 void SignChallengeCallbackTrue(
     89     chromeos::attestation::AttestationKeyType key_type,
     90     const std::string& user_id,
     91     const std::string& key_name,
     92     const std::string& domain,
     93     const std::string& device_id,
     94     chromeos::attestation::AttestationChallengeOptions options,
     95     const std::string& challenge,
     96     const cryptohome::AsyncMethodCaller::DataCallback& callback) {
     97   base::MessageLoopProxy::current()->PostTask(
     98       FROM_HERE,
     99       base::Bind(callback, true, "response"));
    100 }
    101 
    102 void SignChallengeCallbackFalse(
    103     chromeos::attestation::AttestationKeyType key_type,
    104     const std::string& user_id,
    105     const std::string& key_name,
    106     const std::string& domain,
    107     const std::string& device_id,
    108     chromeos::attestation::AttestationChallengeOptions options,
    109     const std::string& challenge,
    110     const cryptohome::AsyncMethodCaller::DataCallback& callback) {
    111   base::MessageLoopProxy::current()->PostTask(
    112       FROM_HERE,
    113       base::Bind(callback, false, ""));
    114 }
    115 
    116 void GetCertificateCallbackTrue(
    117     chromeos::attestation::AttestationCertificateProfile certificate_profile,
    118     const std::string& user_id,
    119     const std::string& request_origin,
    120     bool force_new_key,
    121     const chromeos::attestation::AttestationFlow::CertificateCallback&
    122         callback) {
    123   base::MessageLoopProxy::current()->PostTask(
    124       FROM_HERE,
    125       base::Bind(callback, true, "certificate"));
    126 }
    127 
    128 void GetCertificateCallbackFalse(
    129     chromeos::attestation::AttestationCertificateProfile certificate_profile,
    130     const std::string& user_id,
    131     const std::string& request_origin,
    132     bool force_new_key,
    133     const chromeos::attestation::AttestationFlow::CertificateCallback&
    134         callback) {
    135   base::MessageLoopProxy::current()->PostTask(
    136       FROM_HERE,
    137       base::Bind(callback, false, ""));
    138 }
    139 
    140 class EPKPChallengeKeyTestBase : public BrowserWithTestWindowTest {
    141  protected:
    142   EPKPChallengeKeyTestBase() : extension_(test_util::CreateEmptyExtension()) {
    143     // Set up the default behavior of mocks.
    144     ON_CALL(mock_cryptohome_client_, TpmAttestationDoesKeyExist(_, _, _, _))
    145         .WillByDefault(WithArgs<3>(Invoke(FakeBoolDBusMethod(
    146             chromeos::DBUS_METHOD_CALL_SUCCESS, false))));
    147     ON_CALL(mock_cryptohome_client_, TpmAttestationIsPrepared(_))
    148         .WillByDefault(Invoke(FakeBoolDBusMethod(
    149             chromeos::DBUS_METHOD_CALL_SUCCESS, true)));
    150     ON_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _))
    151         .WillByDefault(Invoke(RegisterKeyCallbackTrue));
    152     ON_CALL(mock_async_method_caller_,
    153             TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _))
    154         .WillByDefault(Invoke(SignChallengeCallbackTrue));
    155     ON_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
    156         .WillByDefault(Invoke(GetCertificateCallbackTrue));
    157 
    158     // Set the Enterprise install attributes.
    159     stub_install_attributes_.SetDomain("google.com");
    160     stub_install_attributes_.SetRegistrationUser("test (at) google.com");
    161     stub_install_attributes_.SetDeviceId("device_id");
    162     stub_install_attributes_.SetMode(policy::DEVICE_MODE_ENTERPRISE);
    163 
    164     // Replace the default device setting provider with the stub.
    165     device_settings_provider_ = chromeos::CrosSettings::Get()->GetProvider(
    166         chromeos::kReportDeviceVersionInfo);
    167     EXPECT_TRUE(device_settings_provider_ != NULL);
    168     EXPECT_TRUE(chromeos::CrosSettings::Get()->
    169                 RemoveSettingsProvider(device_settings_provider_));
    170     chromeos::CrosSettings::Get()->
    171         AddSettingsProvider(&stub_settings_provider_);
    172 
    173     // Set the device settings.
    174     stub_settings_provider_.Set(chromeos::kDeviceAttestationEnabled,
    175                                 base::FundamentalValue(true));
    176   }
    177 
    178   virtual ~EPKPChallengeKeyTestBase() {
    179     EXPECT_TRUE(chromeos::CrosSettings::Get()->
    180                 RemoveSettingsProvider(&stub_settings_provider_));
    181     chromeos::CrosSettings::Get()->
    182         AddSettingsProvider(device_settings_provider_);
    183   }
    184 
    185   virtual void SetUp() OVERRIDE {
    186     BrowserWithTestWindowTest::SetUp();
    187 
    188     // Set the user preferences.
    189     prefs_ = browser()->profile()->GetPrefs();
    190     prefs_->SetString(prefs::kGoogleServicesUsername, "test (at) google.com");
    191     base::ListValue whitelist;
    192     whitelist.AppendString(extension_->id());
    193     prefs_->Set(prefs::kAttestationExtensionWhitelist, whitelist);
    194   }
    195 
    196   NiceMock<chromeos::MockCryptohomeClient> mock_cryptohome_client_;
    197   NiceMock<cryptohome::MockAsyncMethodCaller> mock_async_method_caller_;
    198   NiceMock<chromeos::attestation::MockAttestationFlow> mock_attestation_flow_;
    199   scoped_refptr<extensions::Extension> extension_;
    200   policy::StubEnterpriseInstallAttributes stub_install_attributes_;
    201   chromeos::CrosSettingsProvider* device_settings_provider_;
    202   chromeos::StubCrosSettingsProvider stub_settings_provider_;
    203   PrefService* prefs_;
    204 };
    205 
    206 class EPKPChallengeMachineKeyTest : public EPKPChallengeKeyTestBase {
    207  protected:
    208   static const char kArgs[];
    209 
    210   EPKPChallengeMachineKeyTest()
    211       : func_(new EPKPChallengeMachineKey(&mock_cryptohome_client_,
    212                                           &mock_async_method_caller_,
    213                                           &mock_attestation_flow_,
    214                                           &stub_install_attributes_)) {
    215     func_->set_extension(extension_.get());
    216   }
    217 
    218   // Returns an error string for the given code.
    219   std::string GetCertificateError(int error_code) {
    220     return base::StringPrintf(
    221         EPKPChallengeMachineKey::kGetCertificateFailedError,
    222         error_code);
    223   }
    224 
    225   scoped_refptr<EPKPChallengeMachineKey> func_;
    226 };
    227 
    228 // Base 64 encoding of 'challenge'.
    229 const char EPKPChallengeMachineKeyTest::kArgs[] = "[\"Y2hhbGxlbmdl\"]";
    230 
    231 TEST_F(EPKPChallengeMachineKeyTest, ChallengeBadBase64) {
    232   EXPECT_EQ(EPKPChallengeKeyBase::kChallengeBadBase64Error,
    233             utils::RunFunctionAndReturnError(
    234                 func_.get(), "[\"****\"]", browser()));
    235 }
    236 
    237 TEST_F(EPKPChallengeMachineKeyTest, NonEnterpriseDevice) {
    238   stub_install_attributes_.SetRegistrationUser("");
    239 
    240   EXPECT_EQ(EPKPChallengeMachineKey::kNonEnterpriseDeviceError,
    241             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    242 }
    243 
    244 TEST_F(EPKPChallengeMachineKeyTest, ExtensionNotWhitelisted) {
    245   base::ListValue empty_whitelist;
    246   prefs_->Set(prefs::kAttestationExtensionWhitelist, empty_whitelist);
    247 
    248   EXPECT_EQ(EPKPChallengeKeyBase::kExtensionNotWhitelistedError,
    249             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    250 }
    251 
    252 TEST_F(EPKPChallengeMachineKeyTest, UserNotManaged) {
    253   prefs_->SetString(prefs::kGoogleServicesUsername, "test (at) chromium.org");
    254 
    255   EXPECT_EQ(EPKPChallengeKeyBase::kUserNotManaged,
    256             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    257 }
    258 
    259 TEST_F(EPKPChallengeMachineKeyTest, DevicePolicyDisabled) {
    260   stub_settings_provider_.Set(chromeos::kDeviceAttestationEnabled,
    261                               base::FundamentalValue(false));
    262 
    263   EXPECT_EQ(EPKPChallengeKeyBase::kDevicePolicyDisabledError,
    264             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    265 }
    266 
    267 TEST_F(EPKPChallengeMachineKeyTest, DoesKeyExistDbusFailed) {
    268   EXPECT_CALL(mock_cryptohome_client_, TpmAttestationDoesKeyExist(_, _, _, _))
    269       .WillRepeatedly(WithArgs<3>(Invoke(FakeBoolDBusMethod(
    270           chromeos::DBUS_METHOD_CALL_FAILURE, false))));
    271 
    272   EXPECT_EQ(GetCertificateError(kDBusError),
    273             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    274 }
    275 
    276 TEST_F(EPKPChallengeMachineKeyTest, GetCertificateFailed) {
    277   EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
    278       .WillRepeatedly(Invoke(GetCertificateCallbackFalse));
    279 
    280   EXPECT_EQ(GetCertificateError(kGetCertificateFailed),
    281             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    282 }
    283 
    284 TEST_F(EPKPChallengeMachineKeyTest, SignChallengeFailed) {
    285   EXPECT_CALL(mock_async_method_caller_,
    286               TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _))
    287       .WillRepeatedly(Invoke(SignChallengeCallbackFalse));
    288 
    289   EXPECT_EQ(EPKPChallengeKeyBase::kSignChallengeFailedError,
    290             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    291 }
    292 
    293 TEST_F(EPKPChallengeMachineKeyTest, KeyExists) {
    294   EXPECT_CALL(mock_cryptohome_client_, TpmAttestationDoesKeyExist(_, _, _, _))
    295       .WillRepeatedly(WithArgs<3>(Invoke(FakeBoolDBusMethod(
    296           chromeos::DBUS_METHOD_CALL_SUCCESS, true))));
    297   // GetCertificate must not be called if the key exists.
    298   EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
    299       .Times(0);
    300 
    301   EXPECT_TRUE(utils::RunFunction(func_.get(), kArgs, browser(), utils::NONE));
    302 }
    303 
    304 TEST_F(EPKPChallengeMachineKeyTest, Success) {
    305   // GetCertificate must be called exactly once.
    306   EXPECT_CALL(mock_attestation_flow_,
    307               GetCertificate(
    308                   chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE,
    309                   _, _, _, _))
    310       .Times(1);
    311   // SignEnterpriseChallenge must be called exactly once.
    312   EXPECT_CALL(mock_async_method_caller_,
    313               TpmAttestationSignEnterpriseChallenge(
    314                   chromeos::attestation::KEY_DEVICE, "", "attest-ent-machine",
    315                   "google.com", "device_id", _, "challenge", _))
    316       .Times(1);
    317 
    318   scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
    319       func_.get(), kArgs, browser(), utils::NONE));
    320 
    321   std::string response;
    322   value->GetAsString(&response);
    323   EXPECT_EQ("cmVzcG9uc2U=" /* Base64 encoding of 'response' */, response);
    324 }
    325 
    326 TEST_F(EPKPChallengeMachineKeyTest, AttestationNotPrepared) {
    327   EXPECT_CALL(mock_cryptohome_client_, TpmAttestationIsPrepared(_))
    328       .WillRepeatedly(Invoke(FakeBoolDBusMethod(
    329           chromeos::DBUS_METHOD_CALL_SUCCESS, false)));
    330 
    331   EXPECT_EQ(GetCertificateError(kResetRequired),
    332             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    333 }
    334 
    335 TEST_F(EPKPChallengeMachineKeyTest, AttestationPreparedDbusFailed) {
    336   EXPECT_CALL(mock_cryptohome_client_, TpmAttestationIsPrepared(_))
    337       .WillRepeatedly(Invoke(FakeBoolDBusMethod(
    338           chromeos::DBUS_METHOD_CALL_FAILURE, true)));
    339 
    340   EXPECT_EQ(GetCertificateError(kDBusError),
    341             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    342 }
    343 
    344 class EPKPChallengeUserKeyTest : public EPKPChallengeKeyTestBase {
    345  protected:
    346   static const char kArgs[];
    347 
    348   EPKPChallengeUserKeyTest() :
    349       func_(new EPKPChallengeUserKey(&mock_cryptohome_client_,
    350                                      &mock_async_method_caller_,
    351                                      &mock_attestation_flow_,
    352                                      &stub_install_attributes_)) {
    353     func_->set_extension(extension_.get());
    354   }
    355 
    356   virtual void SetUp() OVERRIDE {
    357     EPKPChallengeKeyTestBase::SetUp();
    358 
    359     // Set the user preferences.
    360     prefs_->SetBoolean(prefs::kAttestationEnabled, true);
    361   }
    362 
    363   // Returns an error string for the given code.
    364   std::string GetCertificateError(int error_code) {
    365     return base::StringPrintf(EPKPChallengeUserKey::kGetCertificateFailedError,
    366                               error_code);
    367   }
    368 
    369   scoped_refptr<EPKPChallengeUserKey> func_;
    370 };
    371 
    372 // Base 64 encoding of 'challenge'
    373 const char EPKPChallengeUserKeyTest::kArgs[] = "[\"Y2hhbGxlbmdl\", true]";
    374 
    375 TEST_F(EPKPChallengeUserKeyTest, ChallengeBadBase64) {
    376   EXPECT_EQ(EPKPChallengeKeyBase::kChallengeBadBase64Error,
    377             utils::RunFunctionAndReturnError(
    378                 func_.get(), "[\"****\", true]", browser()));
    379 }
    380 
    381 TEST_F(EPKPChallengeUserKeyTest, UserPolicyDisabled) {
    382   prefs_->SetBoolean(prefs::kAttestationEnabled, false);
    383 
    384   EXPECT_EQ(EPKPChallengeUserKey::kUserPolicyDisabledError,
    385             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    386 }
    387 
    388 TEST_F(EPKPChallengeUserKeyTest, ExtensionNotWhitelisted) {
    389   base::ListValue empty_whitelist;
    390   prefs_->Set(prefs::kAttestationExtensionWhitelist, empty_whitelist);
    391 
    392   EXPECT_EQ(EPKPChallengeKeyBase::kExtensionNotWhitelistedError,
    393             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    394 }
    395 
    396 TEST_F(EPKPChallengeUserKeyTest, UserNotManaged) {
    397   prefs_->SetString(prefs::kGoogleServicesUsername, "test (at) chromium.org");
    398 
    399   EXPECT_EQ(EPKPChallengeKeyBase::kUserNotManaged,
    400             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    401 }
    402 
    403 TEST_F(EPKPChallengeUserKeyTest, DevicePolicyDisabled) {
    404   stub_settings_provider_.Set(chromeos::kDeviceAttestationEnabled,
    405                               base::FundamentalValue(false));
    406 
    407   EXPECT_EQ(EPKPChallengeKeyBase::kDevicePolicyDisabledError,
    408             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    409 }
    410 
    411 TEST_F(EPKPChallengeUserKeyTest, DoesKeyExistDbusFailed) {
    412   EXPECT_CALL(mock_cryptohome_client_, TpmAttestationDoesKeyExist(_, _, _, _))
    413       .WillRepeatedly(WithArgs<3>(Invoke(FakeBoolDBusMethod(
    414           chromeos::DBUS_METHOD_CALL_FAILURE, false))));
    415 
    416   EXPECT_EQ(GetCertificateError(kDBusError),
    417             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    418 }
    419 
    420 TEST_F(EPKPChallengeUserKeyTest, GetCertificateFailed) {
    421   EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
    422       .WillRepeatedly(Invoke(GetCertificateCallbackFalse));
    423 
    424   EXPECT_EQ(GetCertificateError(kGetCertificateFailed),
    425             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    426 }
    427 
    428 TEST_F(EPKPChallengeUserKeyTest, SignChallengeFailed) {
    429   EXPECT_CALL(mock_async_method_caller_,
    430               TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _))
    431       .WillRepeatedly(Invoke(SignChallengeCallbackFalse));
    432 
    433   EXPECT_EQ(EPKPChallengeKeyBase::kSignChallengeFailedError,
    434             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    435 }
    436 
    437 TEST_F(EPKPChallengeUserKeyTest, KeyRegistrationFailed) {
    438   EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _))
    439       .WillRepeatedly(Invoke(RegisterKeyCallbackFalse));
    440 
    441   EXPECT_EQ(EPKPChallengeUserKey::kKeyRegistrationFailedError,
    442             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    443 }
    444 
    445 TEST_F(EPKPChallengeUserKeyTest, KeyExists) {
    446   EXPECT_CALL(mock_cryptohome_client_, TpmAttestationDoesKeyExist(_, _, _, _))
    447       .WillRepeatedly(WithArgs<3>(Invoke(FakeBoolDBusMethod(
    448           chromeos::DBUS_METHOD_CALL_SUCCESS, true))));
    449   // GetCertificate must not be called if the key exists.
    450   EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
    451       .Times(0);
    452 
    453   EXPECT_TRUE(utils::RunFunction(func_.get(), kArgs, browser(), utils::NONE));
    454 }
    455 
    456 TEST_F(EPKPChallengeUserKeyTest, KeyNotRegistered) {
    457   EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _))
    458       .Times(0);
    459 
    460   EXPECT_TRUE(utils::RunFunction(
    461       func_.get(), "[\"Y2hhbGxlbmdl\", false]", browser(), utils::NONE));
    462 }
    463 
    464 TEST_F(EPKPChallengeUserKeyTest, PersonalDevice) {
    465   stub_install_attributes_.SetRegistrationUser("");
    466 
    467   // Currently personal devices are not supported.
    468   EXPECT_EQ(GetCertificateError(kUserRejected),
    469             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    470 }
    471 
    472 TEST_F(EPKPChallengeUserKeyTest, Success) {
    473   // GetCertificate must be called exactly once.
    474   EXPECT_CALL(mock_attestation_flow_,
    475               GetCertificate(
    476                   chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE,
    477                   _, _, _, _))
    478       .Times(1);
    479   // SignEnterpriseChallenge must be called exactly once.
    480   EXPECT_CALL(mock_async_method_caller_,
    481               TpmAttestationSignEnterpriseChallenge(
    482                   chromeos::attestation::KEY_USER, "test (at) google.com",
    483                   "attest-ent-user", "test (at) google.com", "device_id", _,
    484                   "challenge", _))
    485       .Times(1);
    486   // RegisterKey must be called exactly once.
    487   EXPECT_CALL(mock_async_method_caller_,
    488               TpmAttestationRegisterKey(chromeos::attestation::KEY_USER,
    489                                         "test (at) google.com",
    490                                         "attest-ent-user", _))
    491       .Times(1);
    492 
    493   scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
    494       func_.get(), kArgs, browser(), utils::NONE));
    495 
    496   std::string response;
    497   value->GetAsString(&response);
    498   EXPECT_EQ("cmVzcG9uc2U=" /* Base64 encoding of 'response' */, response);
    499 }
    500 
    501 TEST_F(EPKPChallengeUserKeyTest, AttestationNotPrepared) {
    502   EXPECT_CALL(mock_cryptohome_client_, TpmAttestationIsPrepared(_))
    503       .WillRepeatedly(Invoke(FakeBoolDBusMethod(
    504           chromeos::DBUS_METHOD_CALL_SUCCESS, false)));
    505 
    506   EXPECT_EQ(GetCertificateError(kResetRequired),
    507             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    508 }
    509 
    510 TEST_F(EPKPChallengeUserKeyTest, AttestationPreparedDbusFailed) {
    511   EXPECT_CALL(mock_cryptohome_client_, TpmAttestationIsPrepared(_))
    512       .WillRepeatedly(Invoke(FakeBoolDBusMethod(
    513           chromeos::DBUS_METHOD_CALL_FAILURE, true)));
    514 
    515   EXPECT_EQ(GetCertificateError(kDBusError),
    516             utils::RunFunctionAndReturnError(func_.get(), kArgs, browser()));
    517 }
    518 
    519 }  // namespace
    520 }  // namespace extensions
    521