Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: chrome/browser/chromeos/policy/policy_cert_verifier_browsertest.cc

Issue 13035003: Added a PolicyCertVerifier that uses the trust anchors from the ONC policies. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed comments Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 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 "chrome/browser/chromeos/policy/policy_cert_verifier.h"
6
7 #include "base/memory/ref_counted.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop.h"
10 #include "base/run_loop.h"
11 #include "chrome/common/pref_names.h"
12 #include "chrome/test/base/testing_browser_process.h"
13 #include "chrome/test/base/testing_profile.h"
14 #include "chrome/test/base/testing_profile_manager.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/test/test_browser_thread.h"
17 #include "crypto/nss_util.h"
18 #include "net/base/net_log.h"
19 #include "net/base/test_completion_callback.h"
20 #include "net/base/test_data_directory.h"
21 #include "net/cert/cert_trust_anchor_provider.h"
22 #include "net/cert/cert_verify_result.h"
23 #include "net/cert/nss_cert_database.h"
24 #include "net/cert/x509_certificate.h"
25 #include "net/test/cert_test_util.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28
29 using testing::Mock;
30 using testing::ReturnRef;
31
32 namespace policy {
33
34 namespace {
35
36 class MockCertTrustAnchorProvider : public net::CertTrustAnchorProvider {
37 public:
38 MockCertTrustAnchorProvider() {}
39 virtual ~MockCertTrustAnchorProvider() {}
40
41 MOCK_METHOD0(GetAdditionalTrustAnchors, const net::CertificateList&());
42 };
43
44 } // namespace
45
46 // This is actually a unit test, but is linked with browser_tests because
47 // importing a certificate into the NSS test database persists for the duration
48 // of a process; since each browser_test runs in a separate process then this
49 // won't affect subsequent tests.
50 // This can be moved to the unittests target once the TODO in ~ScopedTestNSSDB
51 // is fixed.
52 class PolicyCertVerifierTest : public testing::Test {
53 public:
54 PolicyCertVerifierTest()
55 : cert_db_(NULL),
56 ui_thread_(content::BrowserThread::UI, &loop_),
57 io_thread_(content::BrowserThread::IO, &loop_),
58 profile_manager_(TestingBrowserProcess::GetGlobal()),
59 profile_(NULL) {}
60
61 virtual ~PolicyCertVerifierTest() {}
62
63 virtual void SetUp() OVERRIDE {
64 ASSERT_TRUE(test_nssdb_.is_open());
65 cert_db_ = net::NSSCertDatabase::GetInstance();
66
67 ASSERT_TRUE(profile_manager_.SetUp());
68 profile_ = profile_manager_.CreateTestingProfile("profile");
69
70 cert_verifier_.reset(new PolicyCertVerifier(profile_, &trust_provider_));
71 }
72
73 scoped_refptr<net::X509Certificate> LoadCertificate(const std::string& name,
74 net::CertType type) {
75 scoped_refptr<net::X509Certificate> cert =
76 net::ImportCertFromFile(net::GetTestCertsDirectory(), name);
77
78 // No certificate is trusted right after it's loaded.
79 net::NSSCertDatabase::TrustBits trust =
80 cert_db_->GetCertTrust(cert.get(), type);
81 EXPECT_EQ(net::NSSCertDatabase::TRUST_DEFAULT, trust);
82
83 return cert;
84 }
85
86 protected:
87 crypto::ScopedTestNSSDB test_nssdb_;
88 net::NSSCertDatabase* cert_db_;
89 MessageLoop loop_;
90 content::TestBrowserThread ui_thread_;
91 content::TestBrowserThread io_thread_;
92 TestingProfileManager profile_manager_;
93 TestingProfile* profile_;
94 MockCertTrustAnchorProvider trust_provider_;
95 scoped_ptr<PolicyCertVerifier> cert_verifier_;
96 const net::CertificateList empty_cert_list_;
97 };
98
99 TEST_F(PolicyCertVerifierTest, VerifyUntrustedCert) {
100 scoped_refptr<net::X509Certificate> cert =
101 LoadCertificate("ok_cert.pem", net::SERVER_CERT);
102 ASSERT_TRUE(cert);
103
104 // |cert| is untrusted, so Verify() fails.
105 net::CertVerifyResult verify_result;
106 net::TestCompletionCallback callback;
107 net::CertVerifier::RequestHandle request_handle;
108 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
109 .WillOnce(ReturnRef(empty_cert_list_));
110 int error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
111 &verify_result, callback.callback(),
112 &request_handle, net::BoundNetLog());
113 Mock::VerifyAndClearExpectations(&trust_provider_);
114 ASSERT_EQ(net::ERR_IO_PENDING, error);
115 ASSERT_TRUE(request_handle);
116 error = callback.WaitForResult();
117 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error);
118
119 // Issuing the same request again hits the cache. This tests the synchronous
120 // path.
121 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
122 .WillOnce(ReturnRef(empty_cert_list_));
123 error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
124 &verify_result, callback.callback(),
125 &request_handle, net::BoundNetLog());
126 Mock::VerifyAndClearExpectations(&trust_provider_);
127 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error);
128
129 // The profile is not tainted.
130 base::RunLoop().RunUntilIdle();
131 EXPECT_FALSE(
132 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
133 }
134
135 TEST_F(PolicyCertVerifierTest, VerifyTrustedCert) {
136 // |ca_cert| is the issuer of |cert|.
137 scoped_refptr<net::X509Certificate> ca_cert =
138 LoadCertificate("root_ca_cert.crt", net::CA_CERT);
139 ASSERT_TRUE(ca_cert);
140 scoped_refptr<net::X509Certificate> cert =
141 LoadCertificate("ok_cert.pem", net::SERVER_CERT);
142 ASSERT_TRUE(cert);
143
144 // Make the database trust |ca_cert|.
145 net::CertificateList import_list;
146 import_list.push_back(ca_cert);
147 net::NSSCertDatabase::ImportCertFailureList failure_list;
148 ASSERT_TRUE(cert_db_->ImportCACerts(
149 import_list, net::NSSCertDatabase::TRUSTED_SSL, &failure_list));
150 ASSERT_TRUE(failure_list.empty());
151
152 // Verify that it is now trusted.
153 net::NSSCertDatabase::TrustBits trust =
154 cert_db_->GetCertTrust(ca_cert.get(), net::CA_CERT);
155 EXPECT_EQ(net::NSSCertDatabase::TRUSTED_SSL, trust);
156
157 // Verify() successfully verifies |cert| after it was imported.
158 net::CertVerifyResult verify_result;
159 net::TestCompletionCallback callback;
160 net::CertVerifier::RequestHandle request_handle;
161 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
162 .WillOnce(ReturnRef(empty_cert_list_));
163 int error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
164 &verify_result, callback.callback(),
165 &request_handle, net::BoundNetLog());
166 Mock::VerifyAndClearExpectations(&trust_provider_);
167 ASSERT_EQ(net::ERR_IO_PENDING, error);
168 ASSERT_TRUE(request_handle);
169 error = callback.WaitForResult();
170 EXPECT_EQ(net::OK, error);
171
172 // The profile is not tainted, since the certificate is trusted from the
173 // database.
174 base::RunLoop().RunUntilIdle();
175 EXPECT_FALSE(
176 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
177 }
178
179 TEST_F(PolicyCertVerifierTest, VerifyUsingAdditionalTrustAnchor) {
180 // |ca_cert| is the issuer of |cert|.
181 scoped_refptr<net::X509Certificate> ca_cert =
182 LoadCertificate("root_ca_cert.crt", net::CA_CERT);
183 ASSERT_TRUE(ca_cert);
184 scoped_refptr<net::X509Certificate> cert =
185 LoadCertificate("ok_cert.pem", net::SERVER_CERT);
186 ASSERT_TRUE(cert);
187
188 net::CertificateList additional_trust_anchors;
189 additional_trust_anchors.push_back(ca_cert);
190
191 // Verify() successfully verifies |cert|, using |ca_cert| from the list of
192 // |additional_trust_anchors|.
193 net::CertVerifyResult verify_result;
194 net::TestCompletionCallback callback;
195 net::CertVerifier::RequestHandle request_handle;
196 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
197 .WillOnce(ReturnRef(additional_trust_anchors));
198 int error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
199 &verify_result, callback.callback(),
200 &request_handle, net::BoundNetLog());
201 Mock::VerifyAndClearExpectations(&trust_provider_);
202 ASSERT_EQ(net::ERR_IO_PENDING, error);
203 ASSERT_TRUE(request_handle);
204 error = callback.WaitForResult();
205 EXPECT_EQ(net::OK, error);
206
207 // The profile becomes tainted after using the trust anchors that came from
208 // the policy configuration.
209 base::RunLoop().RunUntilIdle();
210 EXPECT_TRUE(
211 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
212 }
213
214 TEST_F(PolicyCertVerifierTest, ProfileRemainsTainted) {
215 // |ca_cert| is the issuer of |cert|.
216 scoped_refptr<net::X509Certificate> ca_cert =
217 LoadCertificate("root_ca_cert.crt", net::CA_CERT);
218 ASSERT_TRUE(ca_cert);
219 scoped_refptr<net::X509Certificate> cert =
220 LoadCertificate("ok_cert.pem", net::SERVER_CERT);
221 ASSERT_TRUE(cert);
222
223 net::CertificateList additional_trust_anchors;
224 additional_trust_anchors.push_back(ca_cert);
225
226 // |cert| is untrusted, so Verify() fails.
227 net::CertVerifyResult verify_result;
228 net::TestCompletionCallback callback;
229 net::CertVerifier::RequestHandle request_handle;
230 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
231 .WillOnce(ReturnRef(empty_cert_list_));
232 int error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
233 &verify_result, callback.callback(),
234 &request_handle, net::BoundNetLog());
235 Mock::VerifyAndClearExpectations(&trust_provider_);
236 ASSERT_EQ(net::ERR_IO_PENDING, error);
237 ASSERT_TRUE(request_handle);
238 error = callback.WaitForResult();
239 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error);
240
241 // The profile is not tainted.
242 base::RunLoop().RunUntilIdle();
243 EXPECT_FALSE(
244 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
245
246 // Verify() again with the additional trust anchors.
247 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
248 .WillOnce(ReturnRef(additional_trust_anchors));
249 error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
250 &verify_result, callback.callback(),
251 &request_handle, net::BoundNetLog());
252 Mock::VerifyAndClearExpectations(&trust_provider_);
253 ASSERT_EQ(net::ERR_IO_PENDING, error);
254 ASSERT_TRUE(request_handle);
255 error = callback.WaitForResult();
256 EXPECT_EQ(net::OK, error);
257
258 // The profile becomes tainted after using the trust anchors that came from
259 // the policy configuration.
260 base::RunLoop().RunUntilIdle();
261 EXPECT_TRUE(
262 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
263
264 // Verifying after removing the trust anchors should now fail.
265 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
266 .WillOnce(ReturnRef(empty_cert_list_));
267 error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
268 &verify_result, callback.callback(),
269 &request_handle, net::BoundNetLog());
270 Mock::VerifyAndClearExpectations(&trust_provider_);
271 // Note: this hits the cached result from the first Verify() in this test.
272 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error);
273
274 // The profile is still tainted.
275 base::RunLoop().RunUntilIdle();
276 EXPECT_TRUE(
277 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
278 }
279
280 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/policy/policy_cert_verifier.cc ('k') | chrome/browser/policy/browser_policy_connector.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698