Home | History | Annotate | Download | only in attestation
      1 // Copyright (c) 2012 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 "base/bind.h"
      6 #include "base/memory/scoped_ptr.h"
      7 #include "base/run_loop.h"
      8 #include "chromeos/attestation/mock_attestation_flow.h"
      9 #include "chromeos/cryptohome/mock_async_method_caller.h"
     10 #include "chromeos/dbus/mock_cryptohome_client.h"
     11 #include "testing/gmock/include/gmock/gmock.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 using testing::_;
     15 using testing::AtLeast;
     16 using testing::DoDefault;
     17 using testing::Invoke;
     18 using testing::NiceMock;
     19 using testing::Return;
     20 using testing::Sequence;
     21 using testing::StrictMock;
     22 using testing::WithArgs;
     23 
     24 namespace chromeos {
     25 namespace attestation {
     26 
     27 namespace {
     28 
     29 void DBusCallbackFalse(const BoolDBusMethodCallback& callback) {
     30   base::MessageLoop::current()->PostTask(
     31       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
     32 }
     33 
     34 void DBusCallbackTrue(const BoolDBusMethodCallback& callback) {
     35   base::MessageLoop::current()->PostTask(
     36       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
     37 }
     38 
     39 void DBusCallbackFail(const BoolDBusMethodCallback& callback) {
     40   base::MessageLoop::current()->PostTask(
     41       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_FAILURE, false));
     42 }
     43 
     44 void AsyncCallbackFalse(cryptohome::AsyncMethodCaller::Callback callback) {
     45   callback.Run(false, cryptohome::MOUNT_ERROR_NONE);
     46 }
     47 
     48 class FakeDBusData {
     49  public:
     50   explicit FakeDBusData(const std::string& data) : data_(data) {}
     51 
     52   void operator() (const CryptohomeClient::DataMethodCallback& callback) {
     53     base::MessageLoop::current()->PostTask(
     54         FROM_HERE,
     55         base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true, data_));
     56   }
     57 
     58  private:
     59   std::string data_;
     60 };
     61 
     62 }  // namespace
     63 
     64 class AttestationFlowTest : public testing::Test {
     65  protected:
     66   void Run() {
     67     base::RunLoop run_loop;
     68     run_loop.RunUntilIdle();
     69   }
     70   base::MessageLoop message_loop_;
     71 };
     72 
     73 TEST_F(AttestationFlowTest, GetCertificate) {
     74   // Verify the order of calls in a sequence.
     75   Sequence flow_order;
     76 
     77   // Use DBusCallbackFalse so the full enrollment flow is triggered.
     78   chromeos::MockCryptohomeClient client;
     79   EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
     80       .InSequence(flow_order)
     81       .WillRepeatedly(Invoke(DBusCallbackFalse));
     82 
     83   // Use StrictMock when we want to verify invocation frequency.
     84   StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
     85   async_caller.SetUp(true, cryptohome::MOUNT_ERROR_NONE);
     86   EXPECT_CALL(async_caller, AsyncTpmAttestationCreateEnrollRequest(_, _))
     87       .Times(1)
     88       .InSequence(flow_order);
     89 
     90   scoped_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
     91   proxy->DeferToFake(true);
     92   EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault());
     93   EXPECT_CALL(*proxy, SendEnrollRequest(
     94       cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest,
     95       _)).Times(1)
     96          .InSequence(flow_order);
     97 
     98   std::string fake_enroll_response =
     99       cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest;
    100   fake_enroll_response += "_response";
    101   EXPECT_CALL(async_caller,
    102               AsyncTpmAttestationEnroll(_, fake_enroll_response, _))
    103       .Times(1)
    104       .InSequence(flow_order);
    105 
    106   EXPECT_CALL(
    107       async_caller,
    108       AsyncTpmAttestationCreateCertRequest(_,
    109                                            PROFILE_ENTERPRISE_USER_CERTIFICATE,
    110                                            "fake (at) test.com", "fake_origin", _))
    111           .Times(1)
    112           .InSequence(flow_order);
    113 
    114   EXPECT_CALL(*proxy, SendCertificateRequest(
    115       cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest,
    116       _)).Times(1)
    117          .InSequence(flow_order);
    118 
    119   std::string fake_cert_response =
    120       cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest;
    121   fake_cert_response += "_response";
    122   EXPECT_CALL(async_caller,
    123               AsyncTpmAttestationFinishCertRequest(fake_cert_response,
    124                                                    KEY_USER,
    125                                                    "fake (at) test.com",
    126                                                    kEnterpriseUserKey,
    127                                                    _))
    128       .Times(1)
    129       .InSequence(flow_order);
    130 
    131   StrictMock<MockObserver> observer;
    132   EXPECT_CALL(observer, MockCertificateCallback(
    133       true,
    134       cryptohome::MockAsyncMethodCaller::kFakeAttestationCert))
    135       .Times(1)
    136       .InSequence(flow_order);
    137   AttestationFlow::CertificateCallback mock_callback = base::Bind(
    138       &MockObserver::MockCertificateCallback,
    139       base::Unretained(&observer));
    140 
    141   scoped_ptr<ServerProxy> proxy_interface(proxy.release());
    142   AttestationFlow flow(&async_caller, &client, proxy_interface.Pass());
    143   flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, "fake (at) test.com",
    144                       "fake_origin", true, mock_callback);
    145   Run();
    146 }
    147 
    148 TEST_F(AttestationFlowTest, GetCertificate_NoEK) {
    149   StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
    150   async_caller.SetUp(false, cryptohome::MOUNT_ERROR_NONE);
    151   EXPECT_CALL(async_caller, AsyncTpmAttestationCreateEnrollRequest(_, _))
    152       .Times(1);
    153 
    154   chromeos::MockCryptohomeClient client;
    155   EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
    156       .WillRepeatedly(Invoke(DBusCallbackFalse));
    157 
    158   // We're not expecting any server calls in this case; StrictMock will verify.
    159   scoped_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
    160   EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault());
    161 
    162   StrictMock<MockObserver> observer;
    163   EXPECT_CALL(observer, MockCertificateCallback(false, ""))
    164       .Times(1);
    165   AttestationFlow::CertificateCallback mock_callback = base::Bind(
    166       &MockObserver::MockCertificateCallback,
    167       base::Unretained(&observer));
    168 
    169   scoped_ptr<ServerProxy> proxy_interface(proxy.release());
    170   AttestationFlow flow(&async_caller, &client, proxy_interface.Pass());
    171   flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", true,
    172                       mock_callback);
    173   Run();
    174 }
    175 
    176 TEST_F(AttestationFlowTest, GetCertificate_EKRejected) {
    177   StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
    178   async_caller.SetUp(true, cryptohome::MOUNT_ERROR_NONE);
    179   EXPECT_CALL(async_caller, AsyncTpmAttestationCreateEnrollRequest(_, _))
    180       .Times(1);
    181 
    182   chromeos::MockCryptohomeClient client;
    183   EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
    184       .WillRepeatedly(Invoke(DBusCallbackFalse));
    185 
    186   scoped_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
    187   proxy->DeferToFake(false);
    188   EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault());
    189   EXPECT_CALL(*proxy, SendEnrollRequest(
    190       cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest,
    191       _)).Times(1);
    192 
    193   StrictMock<MockObserver> observer;
    194   EXPECT_CALL(observer, MockCertificateCallback(false, ""))
    195       .Times(1);
    196   AttestationFlow::CertificateCallback mock_callback = base::Bind(
    197       &MockObserver::MockCertificateCallback,
    198       base::Unretained(&observer));
    199 
    200   scoped_ptr<ServerProxy> proxy_interface(proxy.release());
    201   AttestationFlow flow(&async_caller, &client, proxy_interface.Pass());
    202   flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", true,
    203                       mock_callback);
    204   Run();
    205 }
    206 
    207 TEST_F(AttestationFlowTest, GetCertificate_FailEnroll) {
    208   StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
    209   async_caller.SetUp(true, cryptohome::MOUNT_ERROR_NONE);
    210   EXPECT_CALL(async_caller, AsyncTpmAttestationCreateEnrollRequest(_, _))
    211       .Times(1);
    212   std::string fake_enroll_response =
    213       cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest;
    214   fake_enroll_response += "_response";
    215   EXPECT_CALL(async_caller,
    216               AsyncTpmAttestationEnroll(_, fake_enroll_response, _))
    217       .WillOnce(WithArgs<2>(Invoke(AsyncCallbackFalse)));
    218 
    219   chromeos::MockCryptohomeClient client;
    220   EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
    221       .WillRepeatedly(Invoke(DBusCallbackFalse));
    222 
    223   scoped_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
    224   proxy->DeferToFake(true);
    225   EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault());
    226   EXPECT_CALL(*proxy, SendEnrollRequest(
    227       cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest,
    228       _)).Times(1);
    229 
    230   StrictMock<MockObserver> observer;
    231   EXPECT_CALL(observer, MockCertificateCallback(false, "")).Times(1);
    232   AttestationFlow::CertificateCallback mock_callback = base::Bind(
    233       &MockObserver::MockCertificateCallback,
    234       base::Unretained(&observer));
    235 
    236   scoped_ptr<ServerProxy> proxy_interface(proxy.release());
    237   AttestationFlow flow(&async_caller, &client, proxy_interface.Pass());
    238   flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", true,
    239                       mock_callback);
    240   Run();
    241 }
    242 
    243 TEST_F(AttestationFlowTest, GetMachineCertificateAlreadyEnrolled) {
    244   StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
    245   async_caller.SetUp(true, cryptohome::MOUNT_ERROR_NONE);
    246   EXPECT_CALL(async_caller,
    247               AsyncTpmAttestationCreateCertRequest(
    248                   _, PROFILE_ENTERPRISE_MACHINE_CERTIFICATE, "", "", _))
    249       .Times(1);
    250   std::string fake_cert_response =
    251       cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest;
    252   fake_cert_response += "_response";
    253   EXPECT_CALL(async_caller,
    254               AsyncTpmAttestationFinishCertRequest(fake_cert_response,
    255                                                    KEY_DEVICE,
    256                                                    "",
    257                                                    kEnterpriseMachineKey,
    258                                                    _))
    259       .Times(1);
    260 
    261   chromeos::MockCryptohomeClient client;
    262   EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
    263       .WillRepeatedly(Invoke(DBusCallbackTrue));
    264 
    265   scoped_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
    266   proxy->DeferToFake(true);
    267   EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault());
    268   EXPECT_CALL(*proxy, SendCertificateRequest(
    269       cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest,
    270       _)).Times(1);
    271 
    272   StrictMock<MockObserver> observer;
    273   EXPECT_CALL(observer, MockCertificateCallback(
    274       true,
    275       cryptohome::MockAsyncMethodCaller::kFakeAttestationCert)).Times(1);
    276   AttestationFlow::CertificateCallback mock_callback = base::Bind(
    277       &MockObserver::MockCertificateCallback,
    278       base::Unretained(&observer));
    279 
    280   scoped_ptr<ServerProxy> proxy_interface(proxy.release());
    281   AttestationFlow flow(&async_caller, &client, proxy_interface.Pass());
    282   flow.GetCertificate(PROFILE_ENTERPRISE_MACHINE_CERTIFICATE, "", "", true,
    283                       mock_callback);
    284   Run();
    285 }
    286 
    287 TEST_F(AttestationFlowTest, GetCertificate_FailCreateCertRequest) {
    288   StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
    289   async_caller.SetUp(false, cryptohome::MOUNT_ERROR_NONE);
    290   EXPECT_CALL(async_caller,
    291               AsyncTpmAttestationCreateCertRequest(
    292                   _, PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", _))
    293       .Times(1);
    294 
    295   chromeos::MockCryptohomeClient client;
    296   EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
    297       .WillRepeatedly(Invoke(DBusCallbackTrue));
    298 
    299   // We're not expecting any server calls in this case; StrictMock will verify.
    300   scoped_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
    301   EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault());
    302 
    303   StrictMock<MockObserver> observer;
    304   EXPECT_CALL(observer, MockCertificateCallback(false, "")).Times(1);
    305   AttestationFlow::CertificateCallback mock_callback = base::Bind(
    306       &MockObserver::MockCertificateCallback,
    307       base::Unretained(&observer));
    308 
    309   scoped_ptr<ServerProxy> proxy_interface(proxy.release());
    310   AttestationFlow flow(&async_caller, &client, proxy_interface.Pass());
    311   flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", true,
    312                       mock_callback);
    313   Run();
    314 }
    315 
    316 TEST_F(AttestationFlowTest, GetCertificate_CertRequestRejected) {
    317   StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
    318   async_caller.SetUp(true, cryptohome::MOUNT_ERROR_NONE);
    319   EXPECT_CALL(async_caller,
    320               AsyncTpmAttestationCreateCertRequest(
    321                   _, PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", _))
    322       .Times(1);
    323 
    324   chromeos::MockCryptohomeClient client;
    325   EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
    326       .WillRepeatedly(Invoke(DBusCallbackTrue));
    327 
    328   scoped_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
    329   proxy->DeferToFake(false);
    330   EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault());
    331   EXPECT_CALL(*proxy, SendCertificateRequest(
    332       cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest,
    333       _)).Times(1);
    334 
    335   StrictMock<MockObserver> observer;
    336   EXPECT_CALL(observer, MockCertificateCallback(false, "")).Times(1);
    337   AttestationFlow::CertificateCallback mock_callback = base::Bind(
    338       &MockObserver::MockCertificateCallback,
    339       base::Unretained(&observer));
    340 
    341   scoped_ptr<ServerProxy> proxy_interface(proxy.release());
    342   AttestationFlow flow(&async_caller, &client, proxy_interface.Pass());
    343   flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", true,
    344                       mock_callback);
    345   Run();
    346 }
    347 
    348 TEST_F(AttestationFlowTest, GetCertificate_FailIsEnrolled) {
    349   // We're not expecting any async calls in this case; StrictMock will verify.
    350   StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
    351 
    352   chromeos::MockCryptohomeClient client;
    353   EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
    354       .WillRepeatedly(Invoke(DBusCallbackFail));
    355 
    356   // We're not expecting any server calls in this case; StrictMock will verify.
    357   scoped_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
    358   EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault());
    359 
    360   StrictMock<MockObserver> observer;
    361   EXPECT_CALL(observer, MockCertificateCallback(false, "")).Times(1);
    362   AttestationFlow::CertificateCallback mock_callback = base::Bind(
    363       &MockObserver::MockCertificateCallback,
    364       base::Unretained(&observer));
    365 
    366   scoped_ptr<ServerProxy> proxy_interface(proxy.release());
    367   AttestationFlow flow(&async_caller, &client, proxy_interface.Pass());
    368   flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", true,
    369                       mock_callback);
    370   Run();
    371 }
    372 
    373 TEST_F(AttestationFlowTest, GetCertificate_CheckExisting) {
    374   StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
    375   async_caller.SetUp(true, cryptohome::MOUNT_ERROR_NONE);
    376   EXPECT_CALL(async_caller,
    377               AsyncTpmAttestationCreateCertRequest(
    378                   _, PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", _))
    379       .Times(1);
    380   std::string fake_cert_response =
    381       cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest;
    382   fake_cert_response += "_response";
    383   EXPECT_CALL(async_caller,
    384               AsyncTpmAttestationFinishCertRequest(fake_cert_response,
    385                                                    KEY_USER,
    386                                                    "",
    387                                                    kEnterpriseUserKey,
    388                                                    _))
    389       .Times(1);
    390 
    391   chromeos::MockCryptohomeClient client;
    392   EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
    393       .WillRepeatedly(Invoke(DBusCallbackTrue));
    394   EXPECT_CALL(client,
    395               TpmAttestationDoesKeyExist(KEY_USER, "", kEnterpriseUserKey, _))
    396       .WillRepeatedly(WithArgs<3>(Invoke(DBusCallbackFalse)));
    397 
    398   scoped_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
    399   proxy->DeferToFake(true);
    400   EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault());
    401   EXPECT_CALL(*proxy, SendCertificateRequest(
    402       cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest,
    403       _)).Times(1);
    404 
    405   StrictMock<MockObserver> observer;
    406   EXPECT_CALL(observer, MockCertificateCallback(
    407       true,
    408       cryptohome::MockAsyncMethodCaller::kFakeAttestationCert)).Times(1);
    409   AttestationFlow::CertificateCallback mock_callback = base::Bind(
    410       &MockObserver::MockCertificateCallback,
    411       base::Unretained(&observer));
    412 
    413   scoped_ptr<ServerProxy> proxy_interface(proxy.release());
    414   AttestationFlow flow(&async_caller, &client, proxy_interface.Pass());
    415   flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", false,
    416                       mock_callback);
    417   Run();
    418 }
    419 
    420 TEST_F(AttestationFlowTest, GetCertificate_AlreadyExists) {
    421   // We're not expecting any async calls in this case; StrictMock will verify.
    422   StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
    423 
    424   chromeos::MockCryptohomeClient client;
    425   EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
    426       .WillRepeatedly(Invoke(DBusCallbackTrue));
    427   EXPECT_CALL(client,
    428               TpmAttestationDoesKeyExist(KEY_USER, "", kEnterpriseUserKey, _))
    429       .WillRepeatedly(WithArgs<3>(Invoke(DBusCallbackTrue)));
    430   EXPECT_CALL(client,
    431               TpmAttestationGetCertificate(KEY_USER, "", kEnterpriseUserKey, _))
    432       .WillRepeatedly(WithArgs<3>(Invoke(FakeDBusData("fake_cert"))));
    433 
    434   // We're not expecting any server calls in this case; StrictMock will verify.
    435   scoped_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
    436   EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault());
    437 
    438   StrictMock<MockObserver> observer;
    439   EXPECT_CALL(observer, MockCertificateCallback(true, "fake_cert")).Times(1);
    440   AttestationFlow::CertificateCallback mock_callback = base::Bind(
    441       &MockObserver::MockCertificateCallback,
    442       base::Unretained(&observer));
    443 
    444   scoped_ptr<ServerProxy> proxy_interface(proxy.release());
    445   AttestationFlow flow(&async_caller, &client, proxy_interface.Pass());
    446   flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", false,
    447                       mock_callback);
    448   Run();
    449 }
    450 
    451 TEST_F(AttestationFlowTest, AlternatePCA) {
    452   // Strategy: Create a ServerProxy mock which reports ALTERNATE_PCA and check
    453   // that all calls to the AsyncMethodCaller reflect this PCA type.
    454   scoped_ptr<MockServerProxy> proxy(new NiceMock<MockServerProxy>());
    455   proxy->DeferToFake(true);
    456   EXPECT_CALL(*proxy, GetType()).WillRepeatedly(Return(ALTERNATE_PCA));
    457 
    458   chromeos::MockCryptohomeClient client;
    459   EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
    460       .WillRepeatedly(Invoke(DBusCallbackFalse));
    461 
    462   NiceMock<cryptohome::MockAsyncMethodCaller> async_caller;
    463   async_caller.SetUp(true, cryptohome::MOUNT_ERROR_NONE);
    464   EXPECT_CALL(async_caller,
    465               AsyncTpmAttestationCreateEnrollRequest(ALTERNATE_PCA, _))
    466       .Times(AtLeast(1));
    467   EXPECT_CALL(async_caller,
    468               AsyncTpmAttestationEnroll(ALTERNATE_PCA, _, _))
    469       .Times(AtLeast(1));
    470   EXPECT_CALL(async_caller,
    471               AsyncTpmAttestationCreateCertRequest(ALTERNATE_PCA, _, _, _, _))
    472       .Times(AtLeast(1));
    473 
    474   NiceMock<MockObserver> observer;
    475   AttestationFlow::CertificateCallback mock_callback = base::Bind(
    476       &MockObserver::MockCertificateCallback,
    477       base::Unretained(&observer));
    478 
    479   scoped_ptr<ServerProxy> proxy_interface(proxy.release());
    480   AttestationFlow flow(&async_caller, &client, proxy_interface.Pass());
    481   flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, "", "", true,
    482                       mock_callback);
    483   Run();
    484 }
    485 
    486 }  // namespace attestation
    487 }  // namespace chromeos
    488