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

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

Issue 13532005: Added a PolicyCertVerifier that uses the trust anchors from the ONC policies. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: skip tests when NSS version is too old 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_proc.h"
23 #include "net/cert/cert_verify_result.h"
24 #include "net/cert/nss_cert_database.h"
25 #include "net/cert/x509_certificate.h"
26 #include "net/test/cert_test_util.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29
30 using testing::Mock;
31 using testing::ReturnRef;
32
33 namespace policy {
34
35 namespace {
36
37 class MockCertTrustAnchorProvider : public net::CertTrustAnchorProvider {
38 public:
39 MockCertTrustAnchorProvider() {}
40 virtual ~MockCertTrustAnchorProvider() {}
41
42 MOCK_METHOD0(GetAdditionalTrustAnchors, const net::CertificateList&());
43 };
44
45 } // namespace
46
47 // This is actually a unit test, but is linked with browser_tests because
48 // importing a certificate into the NSS test database persists for the duration
49 // of a process; since each browser_test runs in a separate process then this
50 // won't affect subsequent tests.
51 // This can be moved to the unittests target once the TODO in ~ScopedTestNSSDB
52 // is fixed.
53 class PolicyCertVerifierTest : public testing::Test {
54 public:
55 PolicyCertVerifierTest()
56 : cert_db_(NULL),
57 ui_thread_(content::BrowserThread::UI, &loop_),
58 io_thread_(content::BrowserThread::IO, &loop_),
59 profile_manager_(TestingBrowserProcess::GetGlobal()),
60 profile_(NULL) {}
61
62 virtual ~PolicyCertVerifierTest() {}
63
64 virtual void SetUp() OVERRIDE {
65 ASSERT_TRUE(test_nssdb_.is_open());
66 cert_db_ = net::NSSCertDatabase::GetInstance();
67
68 ASSERT_TRUE(profile_manager_.SetUp());
69 profile_ = profile_manager_.CreateTestingProfile("profile");
70
71 cert_verifier_.reset(new PolicyCertVerifier(profile_, &trust_provider_));
72 }
73
74 bool SupportsAdditionalTrustAnchors() {
75 scoped_refptr<net::CertVerifyProc> proc =
pneubeck (no reviews) 2013/04/04 11:22:22 nit: you might drop the local variable.
Joao da Silva 2013/04/04 11:25:35 RefCounted objects have 0 refcounts when they are
76 net::CertVerifyProc::CreateDefault();
77 return proc->SupportsAdditionalTrustAnchors();
78 }
79
80 scoped_refptr<net::X509Certificate> LoadCertificate(const std::string& name,
81 net::CertType type) {
82 scoped_refptr<net::X509Certificate> cert =
83 net::ImportCertFromFile(net::GetTestCertsDirectory(), name);
84
85 // No certificate is trusted right after it's loaded.
86 net::NSSCertDatabase::TrustBits trust =
87 cert_db_->GetCertTrust(cert.get(), type);
88 EXPECT_EQ(net::NSSCertDatabase::TRUST_DEFAULT, trust);
89
90 return cert;
91 }
92
93 protected:
94 crypto::ScopedTestNSSDB test_nssdb_;
95 net::NSSCertDatabase* cert_db_;
96 MessageLoop loop_;
97 content::TestBrowserThread ui_thread_;
98 content::TestBrowserThread io_thread_;
99 TestingProfileManager profile_manager_;
100 TestingProfile* profile_;
101 MockCertTrustAnchorProvider trust_provider_;
102 scoped_ptr<PolicyCertVerifier> cert_verifier_;
103 const net::CertificateList empty_cert_list_;
104 };
105
106 TEST_F(PolicyCertVerifierTest, VerifyUntrustedCert) {
107 scoped_refptr<net::X509Certificate> cert =
108 LoadCertificate("ok_cert.pem", net::SERVER_CERT);
109 ASSERT_TRUE(cert);
110
111 // |cert| is untrusted, so Verify() fails.
112 net::CertVerifyResult verify_result;
113 net::TestCompletionCallback callback;
114 net::CertVerifier::RequestHandle request_handle;
115 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
116 .WillOnce(ReturnRef(empty_cert_list_));
117 int error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
118 &verify_result, callback.callback(),
119 &request_handle, net::BoundNetLog());
120 Mock::VerifyAndClearExpectations(&trust_provider_);
121 ASSERT_EQ(net::ERR_IO_PENDING, error);
122 ASSERT_TRUE(request_handle);
123 error = callback.WaitForResult();
124 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error);
125
126 // Issuing the same request again hits the cache. This tests the synchronous
127 // path.
128 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
129 .WillOnce(ReturnRef(empty_cert_list_));
130 error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
131 &verify_result, callback.callback(),
132 &request_handle, net::BoundNetLog());
133 Mock::VerifyAndClearExpectations(&trust_provider_);
134 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error);
135
136 // The profile is not tainted.
137 base::RunLoop().RunUntilIdle();
138 EXPECT_FALSE(
139 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
140 }
141
142 TEST_F(PolicyCertVerifierTest, VerifyTrustedCert) {
143 // |ca_cert| is the issuer of |cert|.
144 scoped_refptr<net::X509Certificate> ca_cert =
145 LoadCertificate("root_ca_cert.crt", net::CA_CERT);
146 ASSERT_TRUE(ca_cert);
147 scoped_refptr<net::X509Certificate> cert =
148 LoadCertificate("ok_cert.pem", net::SERVER_CERT);
149 ASSERT_TRUE(cert);
150
151 // Make the database trust |ca_cert|.
152 net::CertificateList import_list;
153 import_list.push_back(ca_cert);
154 net::NSSCertDatabase::ImportCertFailureList failure_list;
155 ASSERT_TRUE(cert_db_->ImportCACerts(
156 import_list, net::NSSCertDatabase::TRUSTED_SSL, &failure_list));
157 ASSERT_TRUE(failure_list.empty());
158
159 // Verify that it is now trusted.
160 net::NSSCertDatabase::TrustBits trust =
161 cert_db_->GetCertTrust(ca_cert.get(), net::CA_CERT);
162 EXPECT_EQ(net::NSSCertDatabase::TRUSTED_SSL, trust);
163
164 // Verify() successfully verifies |cert| after it was imported.
165 net::CertVerifyResult verify_result;
166 net::TestCompletionCallback callback;
167 net::CertVerifier::RequestHandle request_handle;
168 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
169 .WillOnce(ReturnRef(empty_cert_list_));
170 int error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
171 &verify_result, callback.callback(),
172 &request_handle, net::BoundNetLog());
173 Mock::VerifyAndClearExpectations(&trust_provider_);
174 ASSERT_EQ(net::ERR_IO_PENDING, error);
175 ASSERT_TRUE(request_handle);
176 error = callback.WaitForResult();
177 EXPECT_EQ(net::OK, error);
178
179 // The profile is not tainted, since the certificate is trusted from the
180 // database.
181 base::RunLoop().RunUntilIdle();
182 EXPECT_FALSE(
183 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
184 }
185
186 TEST_F(PolicyCertVerifierTest, VerifyUsingAdditionalTrustAnchor) {
187 if (!SupportsAdditionalTrustAnchors()) {
188 LOG(INFO) << "Test skipped on this platform. NSS >= 3.14.2 required.";
189 return;
190 }
191
192 // |ca_cert| is the issuer of |cert|.
193 scoped_refptr<net::X509Certificate> ca_cert =
194 LoadCertificate("root_ca_cert.crt", net::CA_CERT);
195 ASSERT_TRUE(ca_cert);
196 scoped_refptr<net::X509Certificate> cert =
197 LoadCertificate("ok_cert.pem", net::SERVER_CERT);
198 ASSERT_TRUE(cert);
199
200 net::CertificateList additional_trust_anchors;
201 additional_trust_anchors.push_back(ca_cert);
202
203 // Verify() successfully verifies |cert|, using |ca_cert| from the list of
204 // |additional_trust_anchors|.
205 net::CertVerifyResult verify_result;
206 net::TestCompletionCallback callback;
207 net::CertVerifier::RequestHandle request_handle;
208 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
209 .WillOnce(ReturnRef(additional_trust_anchors));
210 int error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
211 &verify_result, callback.callback(),
212 &request_handle, net::BoundNetLog());
213 Mock::VerifyAndClearExpectations(&trust_provider_);
214 ASSERT_EQ(net::ERR_IO_PENDING, error);
215 ASSERT_TRUE(request_handle);
216 error = callback.WaitForResult();
217 EXPECT_EQ(net::OK, error);
218
219 // The profile becomes tainted after using the trust anchors that came from
220 // the policy configuration.
221 base::RunLoop().RunUntilIdle();
222 EXPECT_TRUE(
223 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
224 }
225
226 TEST_F(PolicyCertVerifierTest, ProfileRemainsTainted) {
227 if (!SupportsAdditionalTrustAnchors()) {
228 LOG(INFO) << "Test skipped on this platform. NSS >= 3.14.2 required.";
229 return;
230 }
231
232 // |ca_cert| is the issuer of |cert|.
233 scoped_refptr<net::X509Certificate> ca_cert =
234 LoadCertificate("root_ca_cert.crt", net::CA_CERT);
235 ASSERT_TRUE(ca_cert);
236 scoped_refptr<net::X509Certificate> cert =
237 LoadCertificate("ok_cert.pem", net::SERVER_CERT);
238 ASSERT_TRUE(cert);
239
240 net::CertificateList additional_trust_anchors;
241 additional_trust_anchors.push_back(ca_cert);
242
243 // |cert| is untrusted, so Verify() fails.
244 net::CertVerifyResult verify_result;
245 net::TestCompletionCallback callback;
246 net::CertVerifier::RequestHandle request_handle;
247 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
248 .WillOnce(ReturnRef(empty_cert_list_));
249 int 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::ERR_CERT_AUTHORITY_INVALID, error);
257
258 // The profile is not tainted.
259 base::RunLoop().RunUntilIdle();
260 EXPECT_FALSE(
261 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
262
263 // Verify() again with the additional trust anchors.
264 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
265 .WillOnce(ReturnRef(additional_trust_anchors));
266 error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
267 &verify_result, callback.callback(),
268 &request_handle, net::BoundNetLog());
269 Mock::VerifyAndClearExpectations(&trust_provider_);
270 ASSERT_EQ(net::ERR_IO_PENDING, error);
271 ASSERT_TRUE(request_handle);
272 error = callback.WaitForResult();
273 EXPECT_EQ(net::OK, error);
274
275 // The profile becomes tainted after using the trust anchors that came from
276 // the policy configuration.
277 base::RunLoop().RunUntilIdle();
278 EXPECT_TRUE(
279 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
280
281 // Verifying after removing the trust anchors should now fail.
282 EXPECT_CALL(trust_provider_, GetAdditionalTrustAnchors())
283 .WillOnce(ReturnRef(empty_cert_list_));
284 error = cert_verifier_->Verify(cert, "127.0.0.1", 0, NULL,
285 &verify_result, callback.callback(),
286 &request_handle, net::BoundNetLog());
287 Mock::VerifyAndClearExpectations(&trust_provider_);
288 // Note: this hits the cached result from the first Verify() in this test.
289 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, error);
290
291 // The profile is still tainted.
292 base::RunLoop().RunUntilIdle();
293 EXPECT_TRUE(
294 profile_->GetPrefs()->GetBoolean(prefs::kUsedPolicyCertificatesOnce));
295 }
296
297 } // 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