Index: chromeos/attestation/attestation_flow_unittest.cc |
diff --git a/chromeos/attestation/attestation_flow_unittest.cc b/chromeos/attestation/attestation_flow_unittest.cc |
index 0b40dd66783890f4d1b27ffe8ec3261655b88999..8218e9c781c85ae8ea52cc8f2bcf25b9b6439382 100644 |
--- a/chromeos/attestation/attestation_flow_unittest.cc |
+++ b/chromeos/attestation/attestation_flow_unittest.cc |
@@ -7,9 +7,13 @@ |
#include "base/bind.h" |
#include "base/location.h" |
+#include "base/memory/ptr_util.h" |
#include "base/run_loop.h" |
#include "base/single_thread_task_runner.h" |
+#include "base/test/test_mock_time_task_runner.h" |
#include "base/threading/thread_task_runner_handle.h" |
+#include "base/time/tick_clock.h" |
+#include "base/timer/timer.h" |
#include "chromeos/attestation/mock_attestation_flow.h" |
#include "chromeos/cryptohome/cryptohome_parameters.h" |
#include "chromeos/cryptohome/mock_async_method_caller.h" |
@@ -33,6 +37,9 @@ namespace attestation { |
namespace { |
+constexpr base::TimeDelta kPreparednessTimeout = |
+ base::TimeDelta::FromSeconds(7); |
+ |
void DBusCallbackFalse(const BoolDBusMethodCallback& callback) { |
base::ThreadTaskRunnerHandle::Get()->PostTask( |
FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false)); |
@@ -86,6 +93,94 @@ TEST_F(AttestationFlowTest, GetCertificate) { |
.InSequence(flow_order) |
.WillRepeatedly(Invoke(DBusCallbackFalse)); |
+ EXPECT_CALL(client, TpmAttestationIsPrepared(_)) |
+ .InSequence(flow_order) |
+ .WillOnce(Invoke(DBusCallbackTrue)); |
+ |
+ // Use StrictMock when we want to verify invocation frequency. |
+ StrictMock<cryptohome::MockAsyncMethodCaller> async_caller; |
+ async_caller.SetUp(true, cryptohome::MOUNT_ERROR_NONE); |
+ EXPECT_CALL(async_caller, AsyncTpmAttestationCreateEnrollRequest(_, _)) |
+ .Times(1) |
+ .InSequence(flow_order); |
+ |
+ std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>()); |
+ proxy->DeferToFake(true); |
+ EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault()); |
+ EXPECT_CALL( |
+ *proxy, |
+ SendEnrollRequest( |
+ cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest, _)) |
+ .Times(1) |
+ .InSequence(flow_order); |
+ |
+ std::string fake_enroll_response = |
+ cryptohome::MockAsyncMethodCaller::kFakeAttestationEnrollRequest; |
+ fake_enroll_response += "_response"; |
+ EXPECT_CALL(async_caller, |
+ AsyncTpmAttestationEnroll(_, fake_enroll_response, _)) |
+ .Times(1) |
+ .InSequence(flow_order); |
+ |
+ const AccountId account_id = AccountId::FromUserEmail("fake@test.com"); |
+ EXPECT_CALL(async_caller, |
+ AsyncTpmAttestationCreateCertRequest( |
+ _, PROFILE_ENTERPRISE_USER_CERTIFICATE, |
+ cryptohome::Identification(account_id), "fake_origin", _)) |
+ .Times(1) |
+ .InSequence(flow_order); |
+ |
+ EXPECT_CALL( |
+ *proxy, |
+ SendCertificateRequest( |
+ cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest, _)) |
+ .Times(1) |
+ .InSequence(flow_order); |
+ |
+ std::string fake_cert_response = |
+ cryptohome::MockAsyncMethodCaller::kFakeAttestationCertRequest; |
+ fake_cert_response += "_response"; |
+ EXPECT_CALL(async_caller, AsyncTpmAttestationFinishCertRequest( |
+ fake_cert_response, KEY_USER, |
+ cryptohome::Identification(account_id), |
+ kEnterpriseUserKey, _)) |
+ .Times(1) |
+ .InSequence(flow_order); |
+ |
+ StrictMock<MockObserver> observer; |
+ EXPECT_CALL( |
+ observer, |
+ MockCertificateCallback( |
+ true, cryptohome::MockAsyncMethodCaller::kFakeAttestationCert)) |
+ .Times(1) |
+ .InSequence(flow_order); |
+ AttestationFlow::CertificateCallback mock_callback = base::Bind( |
+ &MockObserver::MockCertificateCallback, base::Unretained(&observer)); |
+ |
+ std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
+ flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, account_id, |
+ "fake_origin", true, mock_callback); |
+ Run(); |
+} |
+ |
+TEST_F(AttestationFlowTest, GetCertificate_Attestation_Not_Prepared) { |
+ // Verify the order of calls in a sequence. |
+ Sequence flow_order; |
+ |
+ // Use DBusCallbackFalse so the full enrollment flow is triggered. |
+ chromeos::MockCryptohomeClient client; |
+ EXPECT_CALL(client, TpmAttestationIsEnrolled(_)) |
+ .InSequence(flow_order) |
+ .WillRepeatedly(Invoke(DBusCallbackFalse)); |
+ |
+ // It will take a bit for attestation to be prepared. |
+ EXPECT_CALL(client, TpmAttestationIsPrepared(_)) |
+ .InSequence(flow_order) |
+ .WillOnce(Invoke(DBusCallbackFalse)) |
+ .WillOnce(Invoke(DBusCallbackTrue)); |
+ |
// Use StrictMock when we want to verify invocation frequency. |
StrictMock<cryptohome::MockAsyncMethodCaller> async_caller; |
async_caller.SetUp(true, cryptohome::MOUNT_ERROR_NONE); |
@@ -142,10 +237,59 @@ TEST_F(AttestationFlowTest, GetCertificate) { |
&MockObserver::MockCertificateCallback, |
base::Unretained(&observer)); |
+ scoped_refptr<base::TestMockTimeTaskRunner> task_runner( |
+ new base::TestMockTimeTaskRunner(base::Time::Now(), |
+ base::TimeTicks::Now())); |
+ std::unique_ptr<base::TickClock> tick_clock(task_runner->GetMockTickClock()); |
+ message_loop_.SetTaskRunner(task_runner); |
+ |
std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
- AttestationFlow flow(&async_caller, &client, std::move(proxy_interface)); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
+ flow.SetRetryTimerForTest( |
+ base::MakeUnique<base::OneShotTimer>(tick_clock.get())); |
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, account_id, |
"fake_origin", true, mock_callback); |
+ |
+ task_runner->FastForwardBy(kPreparednessTimeout); |
+ Run(); |
+} |
+ |
+TEST_F(AttestationFlowTest, GetCertificate_Attestation_Never_Prepared) { |
+ StrictMock<cryptohome::MockAsyncMethodCaller> async_caller; |
+ async_caller.SetUp(false, cryptohome::MOUNT_ERROR_NONE); |
+ |
+ chromeos::MockCryptohomeClient client; |
+ EXPECT_CALL(client, TpmAttestationIsEnrolled(_)) |
+ .WillRepeatedly(Invoke(DBusCallbackFalse)); |
+ |
+ EXPECT_CALL(client, TpmAttestationIsPrepared(_)) |
+ .WillRepeatedly(Invoke(DBusCallbackFalse)); |
+ |
+ // We're not expecting any server calls in this case; StrictMock will verify. |
+ std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>()); |
+ EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault()); |
+ |
+ StrictMock<MockObserver> observer; |
+ EXPECT_CALL(observer, MockCertificateCallback(false, "")).Times(1); |
+ AttestationFlow::CertificateCallback mock_callback = base::Bind( |
+ &MockObserver::MockCertificateCallback, base::Unretained(&observer)); |
+ |
+ scoped_refptr<base::TestMockTimeTaskRunner> task_runner( |
+ new base::TestMockTimeTaskRunner(base::Time::Now(), |
+ base::TimeTicks::Now())); |
+ std::unique_ptr<base::TickClock> tick_clock(task_runner->GetMockTickClock()); |
+ message_loop_.SetTaskRunner(task_runner); |
+ |
+ std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
+ flow.SetRetryTimerForTest( |
+ base::MakeUnique<base::OneShotTimer>(tick_clock.get())); |
+ flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), |
+ "fake_origin", true, mock_callback); |
+ |
+ task_runner->FastForwardBy(kPreparednessTimeout); |
Run(); |
} |
@@ -159,6 +303,9 @@ TEST_F(AttestationFlowTest, GetCertificate_NoEK) { |
EXPECT_CALL(client, TpmAttestationIsEnrolled(_)) |
.WillRepeatedly(Invoke(DBusCallbackFalse)); |
+ EXPECT_CALL(client, TpmAttestationIsPrepared(_)) |
+ .WillOnce(Invoke(DBusCallbackTrue)); |
+ |
// We're not expecting any server calls in this case; StrictMock will verify. |
std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>()); |
EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault()); |
@@ -171,7 +318,8 @@ TEST_F(AttestationFlowTest, GetCertificate_NoEK) { |
base::Unretained(&observer)); |
std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
- AttestationFlow flow(&async_caller, &client, std::move(proxy_interface)); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "", |
true, mock_callback); |
Run(); |
@@ -187,6 +335,9 @@ TEST_F(AttestationFlowTest, GetCertificate_EKRejected) { |
EXPECT_CALL(client, TpmAttestationIsEnrolled(_)) |
.WillRepeatedly(Invoke(DBusCallbackFalse)); |
+ EXPECT_CALL(client, TpmAttestationIsPrepared(_)) |
+ .WillOnce(Invoke(DBusCallbackTrue)); |
+ |
std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>()); |
proxy->DeferToFake(false); |
EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault()); |
@@ -202,7 +353,8 @@ TEST_F(AttestationFlowTest, GetCertificate_EKRejected) { |
base::Unretained(&observer)); |
std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
- AttestationFlow flow(&async_caller, &client, std::move(proxy_interface)); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "", |
true, mock_callback); |
Run(); |
@@ -224,6 +376,9 @@ TEST_F(AttestationFlowTest, GetCertificate_FailEnroll) { |
EXPECT_CALL(client, TpmAttestationIsEnrolled(_)) |
.WillRepeatedly(Invoke(DBusCallbackFalse)); |
+ EXPECT_CALL(client, TpmAttestationIsPrepared(_)) |
+ .WillOnce(Invoke(DBusCallbackTrue)); |
+ |
std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>()); |
proxy->DeferToFake(true); |
EXPECT_CALL(*proxy, GetType()).WillRepeatedly(DoDefault()); |
@@ -238,7 +393,8 @@ TEST_F(AttestationFlowTest, GetCertificate_FailEnroll) { |
base::Unretained(&observer)); |
std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
- AttestationFlow flow(&async_caller, &client, std::move(proxy_interface)); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "", |
true, mock_callback); |
Run(); |
@@ -280,7 +436,8 @@ TEST_F(AttestationFlowTest, GetMachineCertificateAlreadyEnrolled) { |
base::Unretained(&observer)); |
std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
- AttestationFlow flow(&async_caller, &client, std::move(proxy_interface)); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
flow.GetCertificate(PROFILE_ENTERPRISE_MACHINE_CERTIFICATE, EmptyAccountId(), |
"", true, mock_callback); |
Run(); |
@@ -309,7 +466,8 @@ TEST_F(AttestationFlowTest, GetCertificate_FailCreateCertRequest) { |
base::Unretained(&observer)); |
std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
- AttestationFlow flow(&async_caller, &client, std::move(proxy_interface)); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "", |
true, mock_callback); |
Run(); |
@@ -341,7 +499,8 @@ TEST_F(AttestationFlowTest, GetCertificate_CertRequestRejected) { |
base::Unretained(&observer)); |
std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
- AttestationFlow flow(&async_caller, &client, std::move(proxy_interface)); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "", |
true, mock_callback); |
Run(); |
@@ -366,7 +525,8 @@ TEST_F(AttestationFlowTest, GetCertificate_FailIsEnrolled) { |
base::Unretained(&observer)); |
std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
- AttestationFlow flow(&async_caller, &client, std::move(proxy_interface)); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "", |
true, mock_callback); |
Run(); |
@@ -412,7 +572,8 @@ TEST_F(AttestationFlowTest, GetCertificate_CheckExisting) { |
base::Unretained(&observer)); |
std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
- AttestationFlow flow(&async_caller, &client, std::move(proxy_interface)); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "", |
false, mock_callback); |
Run(); |
@@ -445,7 +606,8 @@ TEST_F(AttestationFlowTest, GetCertificate_AlreadyExists) { |
base::Unretained(&observer)); |
std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
- AttestationFlow flow(&async_caller, &client, std::move(proxy_interface)); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "", |
false, mock_callback); |
Run(); |
@@ -462,6 +624,9 @@ TEST_F(AttestationFlowTest, AlternatePCA) { |
EXPECT_CALL(client, TpmAttestationIsEnrolled(_)) |
.WillRepeatedly(Invoke(DBusCallbackFalse)); |
+ EXPECT_CALL(client, TpmAttestationIsPrepared(_)) |
+ .WillRepeatedly(Invoke(DBusCallbackTrue)); |
+ |
NiceMock<cryptohome::MockAsyncMethodCaller> async_caller; |
async_caller.SetUp(true, cryptohome::MOUNT_ERROR_NONE); |
EXPECT_CALL(async_caller, |
@@ -480,7 +645,8 @@ TEST_F(AttestationFlowTest, AlternatePCA) { |
base::Unretained(&observer)); |
std::unique_ptr<ServerProxy> proxy_interface(proxy.release()); |
- AttestationFlow flow(&async_caller, &client, std::move(proxy_interface)); |
+ AttestationFlow flow(&async_caller, &client, std::move(proxy_interface), |
+ kPreparednessTimeout); |
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "", |
true, mock_callback); |
Run(); |