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_email", "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
,
121 .InSequence(flow_order
);
123 StrictMock
<MockObserver
> observer
;
124 EXPECT_CALL(observer
, MockCertificateCallback(
126 cryptohome::MockAsyncMethodCaller::kFakeAttestationCert
))
128 .InSequence(flow_order
);
129 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
130 &MockObserver::MockCertificateCallback
,
131 base::Unretained(&observer
));
133 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
134 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
135 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "fake_email",
136 "fake_origin", true, mock_callback
);
140 TEST_F(AttestationFlowTest
, GetCertificate_NoEK
) {
141 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
142 async_caller
.SetUp(false, cryptohome::MOUNT_ERROR_NONE
);
143 EXPECT_CALL(async_caller
, AsyncTpmAttestationCreateEnrollRequest(_
))
146 chromeos::MockCryptohomeClient client
;
147 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
148 .WillRepeatedly(Invoke(DBusCallbackFalse
));
150 // We're not expecting any server calls in this case; StrictMock will verify.
151 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
153 StrictMock
<MockObserver
> observer
;
154 EXPECT_CALL(observer
, MockCertificateCallback(false, ""))
156 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
157 &MockObserver::MockCertificateCallback
,
158 base::Unretained(&observer
));
160 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
161 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
162 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
167 TEST_F(AttestationFlowTest
, GetCertificate_EKRejected
) {
168 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
169 async_caller
.SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
170 EXPECT_CALL(async_caller
, AsyncTpmAttestationCreateEnrollRequest(_
))
173 chromeos::MockCryptohomeClient client
;
174 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
175 .WillRepeatedly(Invoke(DBusCallbackFalse
));
177 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
178 proxy
->DeferToFake(false);
179 EXPECT_CALL(*proxy
, SendEnrollRequest(
180 cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest
,
183 StrictMock
<MockObserver
> observer
;
184 EXPECT_CALL(observer
, MockCertificateCallback(false, ""))
186 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
187 &MockObserver::MockCertificateCallback
,
188 base::Unretained(&observer
));
190 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
191 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
192 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
197 TEST_F(AttestationFlowTest
, GetCertificate_FailEnroll
) {
198 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
199 async_caller
.SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
200 EXPECT_CALL(async_caller
, AsyncTpmAttestationCreateEnrollRequest(_
))
202 std::string fake_enroll_response
=
203 cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest
;
204 fake_enroll_response
+= "_response";
205 EXPECT_CALL(async_caller
, AsyncTpmAttestationEnroll(fake_enroll_response
, _
))
206 .WillOnce(WithArgs
<1>(Invoke(AsyncCallbackFalse
)));
208 chromeos::MockCryptohomeClient client
;
209 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
210 .WillRepeatedly(Invoke(DBusCallbackFalse
));
212 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
213 proxy
->DeferToFake(true);
214 EXPECT_CALL(*proxy
, SendEnrollRequest(
215 cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest
,
218 StrictMock
<MockObserver
> observer
;
219 EXPECT_CALL(observer
, MockCertificateCallback(false, "")).Times(1);
220 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
221 &MockObserver::MockCertificateCallback
,
222 base::Unretained(&observer
));
224 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
225 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
226 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
231 TEST_F(AttestationFlowTest
, GetMachineCertificateAlreadyEnrolled
) {
232 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
233 async_caller
.SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
234 EXPECT_CALL(async_caller
,
235 AsyncTpmAttestationCreateCertRequest(
236 PROFILE_ENTERPRISE_MACHINE_CERTIFICATE
, "", "", _
))
238 std::string fake_cert_response
=
239 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
;
240 fake_cert_response
+= "_response";
241 EXPECT_CALL(async_caller
,
242 AsyncTpmAttestationFinishCertRequest(fake_cert_response
,
244 kEnterpriseMachineKey
,
248 chromeos::MockCryptohomeClient client
;
249 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
250 .WillRepeatedly(Invoke(DBusCallbackTrue
));
252 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
253 proxy
->DeferToFake(true);
254 EXPECT_CALL(*proxy
, SendCertificateRequest(
255 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
,
258 StrictMock
<MockObserver
> observer
;
259 EXPECT_CALL(observer
, MockCertificateCallback(
261 cryptohome::MockAsyncMethodCaller::kFakeAttestationCert
)).Times(1);
262 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
263 &MockObserver::MockCertificateCallback
,
264 base::Unretained(&observer
));
266 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
267 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
268 flow
.GetCertificate(PROFILE_ENTERPRISE_MACHINE_CERTIFICATE
, "", "", true,
273 TEST_F(AttestationFlowTest
, GetCertificate_FailCreateCertRequest
) {
274 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
275 async_caller
.SetUp(false, cryptohome::MOUNT_ERROR_NONE
);
276 EXPECT_CALL(async_caller
,
277 AsyncTpmAttestationCreateCertRequest(
278 PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", _
))
281 chromeos::MockCryptohomeClient client
;
282 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
283 .WillRepeatedly(Invoke(DBusCallbackTrue
));
285 // We're not expecting any server calls in this case; StrictMock will verify.
286 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
288 StrictMock
<MockObserver
> observer
;
289 EXPECT_CALL(observer
, MockCertificateCallback(false, "")).Times(1);
290 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
291 &MockObserver::MockCertificateCallback
,
292 base::Unretained(&observer
));
294 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
295 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
296 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
301 TEST_F(AttestationFlowTest
, GetCertificate_CertRequestRejected
) {
302 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
303 async_caller
.SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
304 EXPECT_CALL(async_caller
,
305 AsyncTpmAttestationCreateCertRequest(
306 PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", _
))
309 chromeos::MockCryptohomeClient client
;
310 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
311 .WillRepeatedly(Invoke(DBusCallbackTrue
));
313 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
314 proxy
->DeferToFake(false);
315 EXPECT_CALL(*proxy
, SendCertificateRequest(
316 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
,
319 StrictMock
<MockObserver
> observer
;
320 EXPECT_CALL(observer
, MockCertificateCallback(false, "")).Times(1);
321 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
322 &MockObserver::MockCertificateCallback
,
323 base::Unretained(&observer
));
325 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
326 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
327 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
332 TEST_F(AttestationFlowTest
, GetCertificate_FailIsEnrolled
) {
333 // We're not expecting any async calls in this case; StrictMock will verify.
334 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
336 chromeos::MockCryptohomeClient client
;
337 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
338 .WillRepeatedly(Invoke(DBusCallbackFail
));
340 // We're not expecting any server calls in this case; StrictMock will verify.
341 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
343 StrictMock
<MockObserver
> observer
;
344 EXPECT_CALL(observer
, MockCertificateCallback(false, "")).Times(1);
345 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
346 &MockObserver::MockCertificateCallback
,
347 base::Unretained(&observer
));
349 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
350 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
351 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", true,
356 TEST_F(AttestationFlowTest
, GetCertificate_CheckExisting
) {
357 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
358 async_caller
.SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
359 EXPECT_CALL(async_caller
,
360 AsyncTpmAttestationCreateCertRequest(
361 PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", _
))
363 std::string fake_cert_response
=
364 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
;
365 fake_cert_response
+= "_response";
366 EXPECT_CALL(async_caller
,
367 AsyncTpmAttestationFinishCertRequest(fake_cert_response
,
373 chromeos::MockCryptohomeClient client
;
374 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
375 .WillRepeatedly(Invoke(DBusCallbackTrue
));
377 TpmAttestationDoesKeyExist(KEY_USER
, kEnterpriseUserKey
, _
))
378 .WillRepeatedly(WithArgs
<2>(Invoke(DBusCallbackFalse
)));
380 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
381 proxy
->DeferToFake(true);
382 EXPECT_CALL(*proxy
, SendCertificateRequest(
383 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest
,
386 StrictMock
<MockObserver
> observer
;
387 EXPECT_CALL(observer
, MockCertificateCallback(
389 cryptohome::MockAsyncMethodCaller::kFakeAttestationCert
)).Times(1);
390 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
391 &MockObserver::MockCertificateCallback
,
392 base::Unretained(&observer
));
394 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
395 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
396 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", false,
401 TEST_F(AttestationFlowTest
, GetCertificate_AlreadyExists
) {
402 // We're not expecting any async calls in this case; StrictMock will verify.
403 StrictMock
<cryptohome::MockAsyncMethodCaller
> async_caller
;
405 chromeos::MockCryptohomeClient client
;
406 EXPECT_CALL(client
, TpmAttestationIsEnrolled(_
))
407 .WillRepeatedly(Invoke(DBusCallbackTrue
));
409 TpmAttestationDoesKeyExist(KEY_USER
, kEnterpriseUserKey
, _
))
410 .WillRepeatedly(WithArgs
<2>(Invoke(DBusCallbackTrue
)));
412 TpmAttestationGetCertificate(KEY_USER
, kEnterpriseUserKey
, _
))
413 .WillRepeatedly(WithArgs
<2>(Invoke(FakeDBusData("fake_cert"))));
415 // We're not expecting any server calls in this case; StrictMock will verify.
416 scoped_ptr
<MockServerProxy
> proxy(new StrictMock
<MockServerProxy
>());
418 StrictMock
<MockObserver
> observer
;
419 EXPECT_CALL(observer
, MockCertificateCallback(true, "fake_cert")).Times(1);
420 AttestationFlow::CertificateCallback mock_callback
= base::Bind(
421 &MockObserver::MockCertificateCallback
,
422 base::Unretained(&observer
));
424 scoped_ptr
<ServerProxy
> proxy_interface(proxy
.release());
425 AttestationFlow
flow(&async_caller
, &client
, proxy_interface
.Pass());
426 flow
.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE
, "", "", false,
431 } // namespace attestation
432 } // namespace chromeos