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.
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"
15 using testing::Invoke
;
16 using testing::Sequence
;
17 using testing::StrictMock
;
18 using testing::WithArgs
;
21 namespace attestation
{
25 void DBusCallbackFalse(const BoolDBusMethodCallback
& callback
) {
26 base::MessageLoop::current()->PostTask(
27 FROM_HERE
, base::Bind(callback
, DBUS_METHOD_CALL_SUCCESS
, false));
30 void DBusCallbackTrue(const BoolDBusMethodCallback
& callback
) {
31 base::MessageLoop::current()->PostTask(
32 FROM_HERE
, base::Bind(callback
, DBUS_METHOD_CALL_SUCCESS
, true));
35 void DBusCallbackFail(const BoolDBusMethodCallback
& callback
) {
36 base::MessageLoop::current()->PostTask(
37 FROM_HERE
, base::Bind(callback
, DBUS_METHOD_CALL_FAILURE
, false));
40 void AsyncCallbackFalse(cryptohome::AsyncMethodCaller::Callback callback
) {
41 callback
.Run(false, cryptohome::MOUNT_ERROR_NONE
);
46 explicit FakeDBusData(const std::string
& data
) : data_(data
) {}
48 void operator() (const CryptohomeClient::DataMethodCallback
& callback
) {
49 base::MessageLoop::current()->PostTask(
51 base::Bind(callback
, DBUS_METHOD_CALL_SUCCESS
, true, data_
));
60 class AttestationFlowTest
: public testing::Test
{
63 base::RunLoop run_loop
;
64 run_loop
.RunUntilIdle();
66 base::MessageLoop message_loop_
;
69 TEST_F(AttestationFlowTest
, GetCertificate
) {
70 // Verify the order of calls in a sequence.
73 // Use DBusCallbackFalse so the full enrollment flow is triggered.
74 chromeos::MockCryptohomeClient client
;
75 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
76 .InSequence(flow_order
)
77 .WillRepeatedly(Invoke(DBusCallbackFalse
));
79 // Use StrictMock when we want to verify invocation frequency.
80 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
81 async_caller
.SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
82 EXPECT_CALL(async_caller
, AsyncTpmAttestationCreateEnrollRequest(_
))
84 .InSequence(flow_order
);
86 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
87 proxy
->DeferToFake(true);
88 EXPECT_CALL(*proxy
, SendEnrollRequest(
89 cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest
,
91 .InSequence(flow_order
);
93 std::string fake_enroll_response
=
94 cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest
;
95 fake_enroll_response
+= "_response";
96 EXPECT_CALL(async_caller
, AsyncTpmAttestationEnroll(fake_enroll_response
, _
))
98 .InSequence(flow_order
);
102 AsyncTpmAttestationCreateCertRequest(PROFILE_ENTERPRISE_USER_CERTIFICATE
,
103 "fake@test.com", "fake_origin", _
))
105 .InSequence(flow_order
);
107 EXPECT_CALL(*proxy
, SendCertificateRequest(
108 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
,
110 .InSequence(flow_order
);
112 std::string fake_cert_response
=
113 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
;
114 fake_cert_response
+= "_response";
115 EXPECT_CALL(async_caller
,
116 AsyncTpmAttestationFinishCertRequest(fake_cert_response
,
122 .InSequence(flow_order
);
124 StrictMock
<MockObserver
> observer
;
125 EXPECT_CALL(observer
, MockCertificateCallback(
127 cryptohome::MockAsyncMethodCaller::kFakeAttestationCert
))
129 .InSequence(flow_order
);
130 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
131 &MockObserver::MockCertificateCallback
,
132 base::Unretained(&observer
));
134 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
135 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
136 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "fake@test.com",
137 "fake_origin", true, mock_callback
);
141 TEST_F(AttestationFlowTest
, GetCertificate_NoEK
) {
142 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
143 async_caller
.SetUp(false, cryptohome::MOUNT_ERROR_NONE
);
144 EXPECT_CALL(async_caller
, AsyncTpmAttestationCreateEnrollRequest(_
))
147 chromeos::MockCryptohomeClient client
;
148 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
149 .WillRepeatedly(Invoke(DBusCallbackFalse
));
151 // We're not expecting any server calls in this case; StrictMock will verify.
152 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
154 StrictMock
<MockObserver
> observer
;
155 EXPECT_CALL(observer
, MockCertificateCallback(false, ""))
157 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
158 &MockObserver::MockCertificateCallback
,
159 base::Unretained(&observer
));
161 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
162 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
163 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
168 TEST_F(AttestationFlowTest
, GetCertificate_EKRejected
) {
169 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
170 async_caller
.SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
171 EXPECT_CALL(async_caller
, AsyncTpmAttestationCreateEnrollRequest(_
))
174 chromeos::MockCryptohomeClient client
;
175 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
176 .WillRepeatedly(Invoke(DBusCallbackFalse
));
178 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
179 proxy
->DeferToFake(false);
180 EXPECT_CALL(*proxy
, SendEnrollRequest(
181 cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest
,
184 StrictMock
<MockObserver
> observer
;
185 EXPECT_CALL(observer
, MockCertificateCallback(false, ""))
187 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
188 &MockObserver::MockCertificateCallback
,
189 base::Unretained(&observer
));
191 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
192 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
193 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
198 TEST_F(AttestationFlowTest
, GetCertificate_FailEnroll
) {
199 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
200 async_caller
.SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
201 EXPECT_CALL(async_caller
, AsyncTpmAttestationCreateEnrollRequest(_
))
203 std::string fake_enroll_response
=
204 cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest
;
205 fake_enroll_response
+= "_response";
206 EXPECT_CALL(async_caller
, AsyncTpmAttestationEnroll(fake_enroll_response
, _
))
207 .WillOnce(WithArgs
<1>(Invoke(AsyncCallbackFalse
)));
209 chromeos::MockCryptohomeClient client
;
210 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
211 .WillRepeatedly(Invoke(DBusCallbackFalse
));
213 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
214 proxy
->DeferToFake(true);
215 EXPECT_CALL(*proxy
, SendEnrollRequest(
216 cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest
,
219 StrictMock
<MockObserver
> observer
;
220 EXPECT_CALL(observer
, MockCertificateCallback(false, "")).Times(1);
221 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
222 &MockObserver::MockCertificateCallback
,
223 base::Unretained(&observer
));
225 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
226 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
227 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
232 TEST_F(AttestationFlowTest
, GetMachineCertificateAlreadyEnrolled
) {
233 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
234 async_caller
.SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
235 EXPECT_CALL(async_caller
,
236 AsyncTpmAttestationCreateCertRequest(
237 PROFILE_ENTERPRISE_MACHINE_CERTIFICATE
, "", "", _
))
239 std::string fake_cert_response
=
240 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
;
241 fake_cert_response
+= "_response";
242 EXPECT_CALL(async_caller
,
243 AsyncTpmAttestationFinishCertRequest(fake_cert_response
,
246 kEnterpriseMachineKey
,
250 chromeos::MockCryptohomeClient client
;
251 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
252 .WillRepeatedly(Invoke(DBusCallbackTrue
));
254 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
255 proxy
->DeferToFake(true);
256 EXPECT_CALL(*proxy
, SendCertificateRequest(
257 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
,
260 StrictMock
<MockObserver
> observer
;
261 EXPECT_CALL(observer
, MockCertificateCallback(
263 cryptohome::MockAsyncMethodCaller::kFakeAttestationCert
)).Times(1);
264 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
265 &MockObserver::MockCertificateCallback
,
266 base::Unretained(&observer
));
268 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
269 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
270 flow
.GetCertificate(PROFILE_ENTERPRISE_MACHINE_CERTIFICATE
, "", "", true,
275 TEST_F(AttestationFlowTest
, GetCertificate_FailCreateCertRequest
) {
276 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
277 async_caller
.SetUp(false, cryptohome::MOUNT_ERROR_NONE
);
278 EXPECT_CALL(async_caller
,
279 AsyncTpmAttestationCreateCertRequest(
280 PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", _
))
283 chromeos::MockCryptohomeClient client
;
284 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
285 .WillRepeatedly(Invoke(DBusCallbackTrue
));
287 // We're not expecting any server calls in this case; StrictMock will verify.
288 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
290 StrictMock
<MockObserver
> observer
;
291 EXPECT_CALL(observer
, MockCertificateCallback(false, "")).Times(1);
292 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
293 &MockObserver::MockCertificateCallback
,
294 base::Unretained(&observer
));
296 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
297 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
298 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
303 TEST_F(AttestationFlowTest
, GetCertificate_CertRequestRejected
) {
304 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
305 async_caller
.SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
306 EXPECT_CALL(async_caller
,
307 AsyncTpmAttestationCreateCertRequest(
308 PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", _
))
311 chromeos::MockCryptohomeClient client
;
312 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
313 .WillRepeatedly(Invoke(DBusCallbackTrue
));
315 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
316 proxy
->DeferToFake(false);
317 EXPECT_CALL(*proxy
, SendCertificateRequest(
318 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
,
321 StrictMock
<MockObserver
> observer
;
322 EXPECT_CALL(observer
, MockCertificateCallback(false, "")).Times(1);
323 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
324 &MockObserver::MockCertificateCallback
,
325 base::Unretained(&observer
));
327 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
328 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
329 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
334 TEST_F(AttestationFlowTest
, GetCertificate_FailIsEnrolled
) {
335 // We're not expecting any async calls in this case; StrictMock will verify.
336 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
338 chromeos::MockCryptohomeClient client
;
339 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
340 .WillRepeatedly(Invoke(DBusCallbackFail
));
342 // We're not expecting any server calls in this case; StrictMock will verify.
343 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
345 StrictMock
<MockObserver
> observer
;
346 EXPECT_CALL(observer
, MockCertificateCallback(false, "")).Times(1);
347 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
348 &MockObserver::MockCertificateCallback
,
349 base::Unretained(&observer
));
351 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
352 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
353 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
358 TEST_F(AttestationFlowTest
, GetCertificate_CheckExisting
) {
359 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
360 async_caller
.SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
361 EXPECT_CALL(async_caller
,
362 AsyncTpmAttestationCreateCertRequest(
363 PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", _
))
365 std::string fake_cert_response
=
366 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
;
367 fake_cert_response
+= "_response";
368 EXPECT_CALL(async_caller
,
369 AsyncTpmAttestationFinishCertRequest(fake_cert_response
,
376 chromeos::MockCryptohomeClient client
;
377 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
378 .WillRepeatedly(Invoke(DBusCallbackTrue
));
380 TpmAttestationDoesKeyExist(KEY_USER
, "", kEnterpriseUserKey
, _
))
381 .WillRepeatedly(WithArgs
<3>(Invoke(DBusCallbackFalse
)));
383 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
384 proxy
->DeferToFake(true);
385 EXPECT_CALL(*proxy
, SendCertificateRequest(
386 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
,
389 StrictMock
<MockObserver
> observer
;
390 EXPECT_CALL(observer
, MockCertificateCallback(
392 cryptohome::MockAsyncMethodCaller::kFakeAttestationCert
)).Times(1);
393 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
394 &MockObserver::MockCertificateCallback
,
395 base::Unretained(&observer
));
397 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
398 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
399 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", false,
404 TEST_F(AttestationFlowTest
, GetCertificate_AlreadyExists
) {
405 // We're not expecting any async calls in this case; StrictMock will verify.
406 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
408 chromeos::MockCryptohomeClient client
;
409 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
410 .WillRepeatedly(Invoke(DBusCallbackTrue
));
412 TpmAttestationDoesKeyExist(KEY_USER
, "", kEnterpriseUserKey
, _
))
413 .WillRepeatedly(WithArgs
<3>(Invoke(DBusCallbackTrue
)));
415 TpmAttestationGetCertificate(KEY_USER
, "", kEnterpriseUserKey
, _
))
416 .WillRepeatedly(WithArgs
<3>(Invoke(FakeDBusData("fake_cert"))));
418 // We're not expecting any server calls in this case; StrictMock will verify.
419 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
421 StrictMock
<MockObserver
> observer
;
422 EXPECT_CALL(observer
, MockCertificateCallback(true, "fake_cert")).Times(1);
423 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
424 &MockObserver::MockCertificateCallback
,
425 base::Unretained(&observer
));
427 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
428 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
429 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", false,
434 } // namespace attestation
435 } // namespace chromeos