policy_cert_verifier_browsertest.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/policy/policy_cert_verifier.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/ref_counted.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/run_loop.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/test/base/testing_browser_process.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/test/base/testing_profile.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/test/base/testing_profile_manager.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/browser_thread.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/test/test_browser_thread.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "crypto/nss_util.h" 1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/base/net_log.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/test_completion_callback.h" 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/test_data_directory.h" 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/cert/cert_trust_anchor_provider.h" 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/cert/cert_verify_proc.h" 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/cert/cert_verify_result.h" 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/cert/nss_cert_database.h" 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/cert/x509_certificate.h" 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/test/cert_test_util.h" 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "testing/gmock/include/gmock/gmock.h" 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "testing/gtest/include/gtest/gtest.h" 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing testing::Mock; 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing testing::ReturnRef; 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace policy { 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace { 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass MockCertTrustAnchorProvider : public net::CertTrustAnchorProvider { 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockCertTrustAnchorProvider() {} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MockCertTrustAnchorProvider() {} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD0(GetAdditionalTrustAnchors, const net::CertificateList&()); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is actually a unit test, but is linked with browser_tests because 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// importing a certificate into the NSS test database persists for the duration 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of a process; since each browser_test runs in a separate process then this 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// won't affect subsequent tests. 5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// This can be moved to the unittests target once the TODO in ~ScopedTestNSSDB 5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// is fixed. 5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class PolicyCertVerifierTest : public testing::Test { 5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) public: 5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PolicyCertVerifierTest() 5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : cert_db_(NULL), 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui_thread_(content::BrowserThread::UI, &loop_), 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) io_thread_(content::BrowserThread::IO, &loop_), 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_manager_(TestingBrowserProcess::GetGlobal()), 6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) profile_(NULL) {} 6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual ~PolicyCertVerifierTest() {} 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void SetUp() OVERRIDE { 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_TRUE(test_nssdb_.is_open()); 6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) cert_db_ = net::NSSCertDatabase::GetInstance(); 6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(profile_manager_.SetUp()); 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_ = profile_manager_.CreateTestingProfile("profile"); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) cert_verifier_.reset(new PolicyCertVerifier(profile_, &trust_provider_)); 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SupportsAdditionalTrustAnchors() { 7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_refptr<net::CertVerifyProc> proc = 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CertVerifyProc::CreateDefault(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proc->SupportsAdditionalTrustAnchors(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::X509Certificate> LoadCertificate(const std::string& name, 8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::CertType type) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::X509Certificate> cert = 83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) net::ImportCertFromFile(net::GetTestCertsDirectory(), name); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No certificate is trusted right after it's loaded. 8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::NSSCertDatabase::TrustBits trust = 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_db_->GetCertTrust(cert.get(), type); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(net::NSSCertDatabase::TRUST_DEFAULT, trust); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return cert; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crypto::ScopedTestNSSDB test_nssdb_; 9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::NSSCertDatabase* cert_db_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessageLoop loop_; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread ui_thread_; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread io_thread_; 9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TestingProfileManager profile_manager_; 10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TestingProfile* profile_; 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MockCertTrustAnchorProvider trust_provider_; 10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_ptr<PolicyCertVerifier> cert_verifier_; 10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const net::CertificateList empty_cert_list_; 10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_F(PolicyCertVerifierTest, VerifyUntrustedCert) { 10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_refptr<net::X509Certificate> cert = 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadCertificate("ok_cert.pem", net::SERVER_CERT); 109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_TRUE(cert.get()); 11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // |cert| is untrusted, so Verify() fails. 11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::CertVerifyResult verify_result; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::TestCompletionCallback callback; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CertVerifier::RequestHandle request_handle; 11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors()) 11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) .WillOnce(ReturnRef(empty_cert_list_)); 11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int error = cert_verifier_->Verify(cert.get(), 11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "127.0.0.1", 11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 0, 12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) NULL, 12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &verify_result, 12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) callback.callback(), 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &request_handle, 12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::BoundNetLog()); 12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Mock::VerifyAndClearExpectations(&trust_provider_); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(net::ERR_IO_PENDING, error); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(request_handle); 12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) error = callback.WaitForResult(); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error); 130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issuing the same request again hits the cache. This tests the synchronous 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // path. 13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors()) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(ReturnRef(empty_cert_list_)); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error = cert_verifier_->Verify(cert.get(), 13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "127.0.0.1", 13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 0, 13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) NULL, 13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &verify_result, 14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) callback.callback(), 14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &request_handle, 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::BoundNetLog()); 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Mock::VerifyAndClearExpectations(&trust_provider_); 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error); 14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // The profile is not tainted. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE( 14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce)); 15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_F(PolicyCertVerifierTest, VerifyTrustedCert) { 15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // |ca_cert| is the issuer of |cert|. 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_refptr<net::X509Certificate> ca_cert = 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadCertificate("root_ca_cert.pem", net::CA_CERT); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ca_cert.get()); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::X509Certificate> cert = 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadCertificate("ok_cert.pem", net::SERVER_CERT); 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(cert.get()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make the database trust |ca_cert|. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CertificateList import_list; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_list.push_back(ca_cert); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NSSCertDatabase::ImportCertFailureList failure_list; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(cert_db_->ImportCACerts( 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_list, net::NSSCertDatabase::TRUSTED_SSL, &failure_list)); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(failure_list.empty()); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that it is now trusted. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NSSCertDatabase::TrustBits trust = 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_db_->GetCertTrust(ca_cert.get(), net::CA_CERT); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(net::NSSCertDatabase::TRUSTED_SSL, trust); 173 174 // Verify() successfully verifies |cert| after it was imported. 175 net::CertVerifyResult verify_result; 176 net::TestCompletionCallback callback; 177 net::CertVerifier::RequestHandle request_handle; 178 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors()) 179 .WillOnce(ReturnRef(empty_cert_list_)); 180 int error = cert_verifier_->Verify(cert.get(), 181 "127.0.0.1", 182 0, 183 NULL, 184 &verify_result, 185 callback.callback(), 186 &request_handle, 187 net::BoundNetLog()); 188 Mock::VerifyAndClearExpectations(&trust_provider_); 189 ASSERT_EQ(net::ERR_IO_PENDING, error); 190 ASSERT_TRUE(request_handle); 191 error = callback.WaitForResult(); 192 EXPECT_EQ(net::OK, error); 193 194 // The profile is not tainted, since the certificate is trusted from the 195 // database. 196 base::RunLoop().RunUntilIdle(); 197 EXPECT_FALSE( 198 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce)); 199} 200 201TEST_F(PolicyCertVerifierTest, VerifyUsingAdditionalTrustAnchor) { 202 if (!SupportsAdditionalTrustAnchors()) { 203 LOG(INFO) << "Test skipped on this platform. NSS >= 3.14.2 required."; 204 return; 205 } 206 207 // |ca_cert| is the issuer of |cert|. 208 scoped_refptr<net::X509Certificate> ca_cert = 209 LoadCertificate("root_ca_cert.pem", net::CA_CERT); 210 ASSERT_TRUE(ca_cert.get()); 211 scoped_refptr<net::X509Certificate> cert = 212 LoadCertificate("ok_cert.pem", net::SERVER_CERT); 213 ASSERT_TRUE(cert.get()); 214 215 net::CertificateList additional_trust_anchors; 216 additional_trust_anchors.push_back(ca_cert); 217 218 // Verify() successfully verifies |cert|, using |ca_cert| from the list of 219 // |additional_trust_anchors|. 220 net::CertVerifyResult verify_result; 221 net::TestCompletionCallback callback; 222 net::CertVerifier::RequestHandle request_handle; 223 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors()) 224 .WillOnce(ReturnRef(additional_trust_anchors)); 225 int error = cert_verifier_->Verify(cert.get(), 226 "127.0.0.1", 227 0, 228 NULL, 229 &verify_result, 230 callback.callback(), 231 &request_handle, 232 net::BoundNetLog()); 233 Mock::VerifyAndClearExpectations(&trust_provider_); 234 ASSERT_EQ(net::ERR_IO_PENDING, error); 235 ASSERT_TRUE(request_handle); 236 error = callback.WaitForResult(); 237 EXPECT_EQ(net::OK, error); 238 239 // The profile becomes tainted after using the trust anchors that came from 240 // the policy configuration. 241 base::RunLoop().RunUntilIdle(); 242 EXPECT_TRUE( 243 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce)); 244} 245 246TEST_F(PolicyCertVerifierTest, ProfileRemainsTainted) { 247 if (!SupportsAdditionalTrustAnchors()) { 248 LOG(INFO) << "Test skipped on this platform. NSS >= 3.14.2 required."; 249 return; 250 } 251 252 // |ca_cert| is the issuer of |cert|. 253 scoped_refptr<net::X509Certificate> ca_cert = 254 LoadCertificate("root_ca_cert.pem", net::CA_CERT); 255 ASSERT_TRUE(ca_cert.get()); 256 scoped_refptr<net::X509Certificate> cert = 257 LoadCertificate("ok_cert.pem", net::SERVER_CERT); 258 ASSERT_TRUE(cert.get()); 259 260 net::CertificateList additional_trust_anchors; 261 additional_trust_anchors.push_back(ca_cert); 262 263 // |cert| is untrusted, so Verify() fails. 264 net::CertVerifyResult verify_result; 265 net::TestCompletionCallback callback; 266 net::CertVerifier::RequestHandle request_handle; 267 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors()) 268 .WillOnce(ReturnRef(empty_cert_list_)); 269 int error = cert_verifier_->Verify(cert.get(), 270 "127.0.0.1", 271 0, 272 NULL, 273 &verify_result, 274 callback.callback(), 275 &request_handle, 276 net::BoundNetLog()); 277 Mock::VerifyAndClearExpectations(&trust_provider_); 278 ASSERT_EQ(net::ERR_IO_PENDING, error); 279 ASSERT_TRUE(request_handle); 280 error = callback.WaitForResult(); 281 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error); 282 283 // The profile is not tainted. 284 base::RunLoop().RunUntilIdle(); 285 EXPECT_FALSE( 286 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce)); 287 288 // Verify() again with the additional trust anchors. 289 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors()) 290 .WillOnce(ReturnRef(additional_trust_anchors)); 291 error = cert_verifier_->Verify(cert.get(), 292 "127.0.0.1", 293 0, 294 NULL, 295 &verify_result, 296 callback.callback(), 297 &request_handle, 298 net::BoundNetLog()); 299 Mock::VerifyAndClearExpectations(&trust_provider_); 300 ASSERT_EQ(net::ERR_IO_PENDING, error); 301 ASSERT_TRUE(request_handle); 302 error = callback.WaitForResult(); 303 EXPECT_EQ(net::OK, error); 304 305 // The profile becomes tainted after using the trust anchors that came from 306 // the policy configuration. 307 base::RunLoop().RunUntilIdle(); 308 EXPECT_TRUE( 309 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce)); 310 311 // Verifying after removing the trust anchors should now fail. 312 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors()) 313 .WillOnce(ReturnRef(empty_cert_list_)); 314 error = cert_verifier_->Verify(cert.get(), 315 "127.0.0.1", 316 0, 317 NULL, 318 &verify_result, 319 callback.callback(), 320 &request_handle, 321 net::BoundNetLog()); 322 Mock::VerifyAndClearExpectations(&trust_provider_); 323 // Note: this hits the cached result from the first Verify() in this test. 324 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error); 325 326 // The profile is still tainted. 327 base::RunLoop().RunUntilIdle(); 328 EXPECT_TRUE( 329 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce)); 330} 331 332} // namespace policy 333