Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chromeos / attestation / attestation_flow_unittest.cc
blob578393bf924097b9e66652723d982da1281511c7
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.
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"
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;
24 namespace chromeos {
25 namespace attestation {
27 namespace {
29 void DBusCallbackFalse(const BoolDBusMethodCallback& callback) {
30 base::MessageLoop::current()->PostTask(
31 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
34 void DBusCallbackTrue(const BoolDBusMethodCallback& callback) {
35 base::MessageLoop::current()->PostTask(
36 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
39 void DBusCallbackFail(const BoolDBusMethodCallback& callback) {
40 base::MessageLoop::current()->PostTask(
41 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_FAILURE, false));
44 void AsyncCallbackFalse(cryptohome::AsyncMethodCaller::Callback callback) {
45 callback.Run(false, cryptohome::MOUNT_ERROR_NONE);
48 class FakeDBusData {
49 public:
50 explicit FakeDBusData(const std::string& data) : data_(data) {}
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_));
58 private:
59 std::string data_;
62 } // namespace
64 class AttestationFlowTest : public testing::Test {
65 protected:
66 void Run() {
67 base::RunLoop run_loop;
68 run_loop.RunUntilIdle();
70 base::MessageLoop message_loop_;
73 TEST_F(AttestationFlowTest, GetCertificate) {
74 // Verify the order of calls in a sequence.
75 Sequence flow_order;
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));
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);
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);
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);
106 EXPECT_CALL(
107 async_caller,
108 AsyncTpmAttestationCreateCertRequest(_,
109 PROFILE_ENTERPRISE_USER_CERTIFICATE,
110 "fake@test.com", "fake_origin", _))
111 .Times(1)
112 .InSequence(flow_order);
114 EXPECT_CALL(*proxy, SendCertificateRequest(
115 cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest,
116 _)).Times(1)
117 .InSequence(flow_order);
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@test.com",
126 kEnterpriseUserKey,
128 .Times(1)
129 .InSequence(flow_order);
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));
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@test.com",
144 "fake_origin", true, mock_callback);
145 Run();
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);
154 chromeos::MockCryptohomeClient client;
155 EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
156 .WillRepeatedly(Invoke(DBusCallbackFalse));
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());
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));
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();
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);
182 chromeos::MockCryptohomeClient client;
183 EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
184 .WillRepeatedly(Invoke(DBusCallbackFalse));
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);
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));
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();
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)));
219 chromeos::MockCryptohomeClient client;
220 EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
221 .WillRepeatedly(Invoke(DBusCallbackFalse));
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);
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));
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();
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,
257 kEnterpriseMachineKey,
259 .Times(1);
261 chromeos::MockCryptohomeClient client;
262 EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
263 .WillRepeatedly(Invoke(DBusCallbackTrue));
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);
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));
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();
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);
295 chromeos::MockCryptohomeClient client;
296 EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
297 .WillRepeatedly(Invoke(DBusCallbackTrue));
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());
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));
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();
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);
324 chromeos::MockCryptohomeClient client;
325 EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
326 .WillRepeatedly(Invoke(DBusCallbackTrue));
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);
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));
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();
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;
352 chromeos::MockCryptohomeClient client;
353 EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
354 .WillRepeatedly(Invoke(DBusCallbackFail));
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());
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));
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();
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,
387 kEnterpriseUserKey,
389 .Times(1);
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)));
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);
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));
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();
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;
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"))));
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());
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));
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();
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));
458 chromeos::MockCryptohomeClient client;
459 EXPECT_CALL(client, TpmAttestationIsEnrolled(_))
460 .WillRepeatedly(Invoke(DBusCallbackFalse));
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));
474 NiceMock<MockObserver> observer;
475 AttestationFlow::CertificateCallback mock_callback = base::Bind(
476 &MockObserver::MockCertificateCallback,
477 base::Unretained(&observer));
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();
486 } // namespace attestation
487 } // namespace chromeos