1// Copyright 2013 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/ref_counted.h" 7#include "base/run_loop.h" 8#include "base/threading/platform_thread.h" 9#include "base/time/time.h" 10#include "chrome/browser/chromeos/attestation/platform_verification_flow.h" 11#include "chrome/browser/chromeos/policy/device_policy_builder.h" 12#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" 13#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" 14#include "chrome/browser/chromeos/settings/device_settings_service.h" 15#include "chrome/browser/ui/browser.h" 16#include "chrome/browser/ui/tabs/tab_strip_model.h" 17#include "chromeos/dbus/fake_cryptohome_client.h" 18#include "testing/gtest/include/gtest/gtest.h" 19 20using chromeos::attestation::PlatformVerificationFlow; 21 22namespace policy { 23 24class CustomFakeCryptohomeClient : public chromeos::FakeCryptohomeClient { 25 public: 26 virtual void TpmAttestationIsEnrolled( 27 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE { 28 base::MessageLoop::current()->PostTask( 29 FROM_HERE, 30 base::Bind(callback, chromeos::DBUS_METHOD_CALL_FAILURE, false)); 31 } 32}; 33 34class AttestationDevicePolicyTest 35 : public DevicePolicyCrosBrowserTest, 36 public chromeos::DeviceSettingsService::Observer { 37 public: 38 // DeviceSettingsService::Observer 39 virtual void OwnershipStatusChanged() OVERRIDE {} 40 virtual void DeviceSettingsUpdated() OVERRIDE { 41 operation_complete_ = true; 42 } 43 44 protected: 45 AttestationDevicePolicyTest() : operation_complete_(false) {} 46 47 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 48 DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture(); 49 InstallOwnerKey(); 50 RefreshDevicePolicy(); 51 } 52 53 // Refreshes device policy and waits for it to be applied. 54 virtual void SyncRefreshDevicePolicy() { 55 chromeos::DeviceSettingsService::Get()->AddObserver(this); 56 RefreshDevicePolicy(); 57 WaitForAsyncOperation(); 58 chromeos::DeviceSettingsService::Get()->RemoveObserver(this); 59 } 60 61 enterprise_management::AttestationSettingsProto* GetDevicePolicyProto() { 62 return device_policy()->payload().mutable_attestation_settings(); 63 } 64 65 // A callback for PlatformVerificationFlow::ChallengePlatformKey. 66 void Callback(PlatformVerificationFlow::Result result, 67 const std::string& signed_data, 68 const std::string& signature, 69 const std::string& platform_key_certificate) { 70 result_ = result; 71 operation_complete_ = true; 72 } 73 74 // Synchronously do what the content protection code path does when it wants 75 // to verify a Chrome OS platform. 76 PlatformVerificationFlow::Result SyncContentProtectionAttestation() { 77 scoped_refptr<PlatformVerificationFlow> verifier( 78 new PlatformVerificationFlow(NULL, NULL, &fake_cryptohome_client_, 79 NULL)); 80 verifier->ChallengePlatformKey( 81 browser()->tab_strip_model()->GetActiveWebContents(), 82 "fake_service_id", 83 "fake_challenge", 84 base::Bind(&AttestationDevicePolicyTest::Callback, this)); 85 WaitForAsyncOperation(); 86 return result_; 87 } 88 89 private: 90 bool operation_complete_; 91 PlatformVerificationFlow::Result result_; 92 CustomFakeCryptohomeClient fake_cryptohome_client_; 93 94 void WaitForAsyncOperation() { 95 while (!operation_complete_) { 96 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); 97 base::RunLoop pump; 98 pump.RunUntilIdle(); 99 } 100 // Reset for the next call. 101 operation_complete_ = false; 102 } 103 104 DISALLOW_COPY_AND_ASSIGN(AttestationDevicePolicyTest); 105}; 106 107IN_PROC_BROWSER_TEST_F(AttestationDevicePolicyTest, ContentProtectionTest) { 108 EXPECT_NE(PlatformVerificationFlow::POLICY_REJECTED, 109 SyncContentProtectionAttestation()); 110 111 GetDevicePolicyProto()->set_content_protection_enabled(false); 112 SyncRefreshDevicePolicy(); 113 114 EXPECT_EQ(PlatformVerificationFlow::POLICY_REJECTED, 115 SyncContentProtectionAttestation()); 116 117 GetDevicePolicyProto()->set_content_protection_enabled(true); 118 SyncRefreshDevicePolicy(); 119 120 EXPECT_NE(PlatformVerificationFlow::POLICY_REJECTED, 121 SyncContentProtectionAttestation()); 122} 123 124} // namespace policy 125