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

Side by Side Diff: net/cert/internal/trust_store_nss_unittest.cc

Issue 2272493002: Add TrustStoreNSS and TrustStoreCollection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert-trust-store-interface3-nss
Patch Set: rebase Created 4 years, 3 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
« no previous file with comments | « net/cert/internal/trust_store_nss.cc ('k') | net/cert/internal/trust_store_test_helpers.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 "net/cert/internal/trust_store_nss.h"
6
7 #include <cert.h>
8 #include <certdb.h>
9
10 #include "base/bind.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/run_loop.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "crypto/scoped_test_nss_db.h"
16 #include "net/cert/internal/test_helpers.h"
17 #include "net/cert/internal/trust_store_test_helpers.h"
18 #include "net/cert/scoped_nss_types.h"
19 #include "net/cert/x509_certificate.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace net {
23
24 namespace {
25
26 void NotCalled(TrustAnchors anchors) {
27 ADD_FAILURE() << "NotCalled was called";
28 }
29
30 class TrustStoreNSSTest : public testing::Test {
31 public:
32 void SetUp() override {
33 ASSERT_TRUE(test_nssdb_.is_open());
34
35 ParsedCertificateList chain;
36 bool unused_verify_result;
37 der::GeneralizedTime unused_time;
38 std::string unused_errors;
39
40 ReadVerifyCertChainTestFromFile("key-rollover-oldchain.pem", &chain,
41 &oldroot_, &unused_time,
42 &unused_verify_result, &unused_errors);
43 ASSERT_EQ(2U, chain.size());
44 target_ = chain[0];
45 oldintermediate_ = chain[1];
46 ASSERT_TRUE(target_);
47 ASSERT_TRUE(oldintermediate_);
48 ASSERT_TRUE(oldroot_);
49
50 scoped_refptr<TrustAnchor> unused_root;
51 ReadVerifyCertChainTestFromFile("key-rollover-longrolloverchain.pem",
52 &chain, &unused_root, &unused_time,
53 &unused_verify_result, &unused_errors);
54 ASSERT_EQ(4U, chain.size());
55 newintermediate_ = chain[1];
56 newroot_ = TrustAnchor::CreateFromCertificateNoConstraints(chain[2]);
57 newrootrollover_ = chain[3];
58 ASSERT_TRUE(newintermediate_);
59 ASSERT_TRUE(newroot_);
60 ASSERT_TRUE(newrootrollover_);
61
62 trust_store_nss_.reset(
63 new TrustStoreNSS(trustSSL, base::ThreadTaskRunnerHandle::Get()));
64 }
65
66 std::string GetUniqueNickname() {
67 return "trust_store_nss_unittest" + base::UintToString(nickname_counter_++);
68 }
69
70 void AddCertToNSS(const ParsedCertificate* cert) {
71 std::string nickname = GetUniqueNickname();
72 ScopedCERTCertificate nss_cert(
73 X509Certificate::CreateOSCertHandleFromBytesWithNickname(
74 cert->der_cert().AsStringPiece().data(), cert->der_cert().Length(),
75 nickname.c_str()));
76 ASSERT_TRUE(nss_cert);
77 SECStatus srv =
78 PK11_ImportCert(test_nssdb_.slot(), nss_cert.get(), CK_INVALID_HANDLE,
79 nickname.c_str(), PR_FALSE /* includeTrust (unused) */);
80 ASSERT_EQ(SECSuccess, srv);
81 }
82
83 void AddCertsToNSS() {
84 AddCertToNSS(target_.get());
85 AddCertToNSS(oldintermediate_.get());
86 AddCertToNSS(newintermediate_.get());
87 AddCertToNSS(oldroot_->cert().get());
88 AddCertToNSS(newroot_->cert().get());
89 AddCertToNSS(newrootrollover_.get());
90 }
91
92 // Trusts |cert|. Assumes the cert was already imported into NSS.
93 void TrustCert(const TrustAnchor* anchor) { TrustCert(anchor->cert().get()); }
94 void TrustCert(const ParsedCertificate* cert) {
95 SECItem der_cert;
96 der_cert.data = const_cast<uint8_t*>(cert->der_cert().UnsafeData());
97 der_cert.len = base::checked_cast<unsigned>(cert->der_cert().Length());
98 der_cert.type = siDERCertBuffer;
99
100 ScopedCERTCertificate nss_cert(
101 CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &der_cert));
102 ASSERT_TRUE(nss_cert);
103
104 CERTCertTrust trust = {0};
105 trust.sslFlags =
106 CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA | CERTDB_VALID_CA;
107 SECStatus srv =
108 CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nss_cert.get(), &trust);
109 ASSERT_EQ(SECSuccess, srv);
110 }
111
112 protected:
113 void ExpectTrustStoreContains(tracked_objects::Location loc,
114 scoped_refptr<ParsedCertificate> cert,
115 TrustAnchors expected_async_matches) {
116 SCOPED_TRACE(loc.ToString());
117
118 TrustAnchors sync_matches;
119 TrustAnchorResultRecorder anchor_results;
120 std::unique_ptr<TrustStore::Request> req;
121 trust_store_nss_->FindTrustAnchorsForCert(cert, anchor_results.Callback(),
122 &sync_matches, &req);
123 ASSERT_TRUE(req);
124 EXPECT_TRUE(sync_matches.empty());
125
126 anchor_results.Run();
127 std::vector<der::Input> der_result_matches;
128 for (const auto& it : anchor_results.matches())
129 der_result_matches.push_back(it->cert()->der_cert());
130 std::sort(der_result_matches.begin(), der_result_matches.end());
131
132 std::vector<der::Input> der_expected_matches;
133 for (const auto& it : expected_async_matches)
134 der_expected_matches.push_back(it->cert()->der_cert());
135 std::sort(der_expected_matches.begin(), der_expected_matches.end());
136
137 EXPECT_EQ(der_expected_matches, der_result_matches);
138 }
139
140 scoped_refptr<TrustAnchor> oldroot_;
141 scoped_refptr<TrustAnchor> newroot_;
142
143 scoped_refptr<ParsedCertificate> target_;
144 scoped_refptr<ParsedCertificate> oldintermediate_;
145 scoped_refptr<ParsedCertificate> newintermediate_;
146 scoped_refptr<ParsedCertificate> newrootrollover_;
147 crypto::ScopedTestNSSDB test_nssdb_;
148 std::unique_ptr<TrustStoreNSS> trust_store_nss_;
149 unsigned nickname_counter_ = 0;
150 };
151
152 // Without adding any certs to the NSS DB, should get no anchor results for any
153 // of the test certs.
154 TEST_F(TrustStoreNSSTest, CertsNotPresent) {
155 ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
156 ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
157 ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), TrustAnchors());
158 }
159
160 // If certs are present in NSS DB but aren't marked as trusted, should get no
161 // anchor results for any of the test certs.
162 TEST_F(TrustStoreNSSTest, CertsPresentButNotTrusted) {
163 AddCertsToNSS();
164 ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
165 ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
166 ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
167 ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), TrustAnchors());
168 }
169
170 // A self-signed CA certificate is trusted. FindTrustAnchorsForCert should
171 // return the cert on any intermediates with a matching issuer, and on any
172 // matching self-signed/self-issued CA certs.
173 TEST_F(TrustStoreNSSTest, TrustedCA) {
174 AddCertsToNSS();
175 TrustCert(newroot_.get());
176 ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
177 ExpectTrustStoreContains(FROM_HERE, newintermediate_, {newroot_});
178 ExpectTrustStoreContains(FROM_HERE, oldintermediate_, {newroot_});
179 ExpectTrustStoreContains(FROM_HERE, newrootrollover_, {newroot_});
180 ExpectTrustStoreContains(FROM_HERE, oldroot_->cert(), {newroot_});
181 ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), {newroot_});
182 }
183
184 // When an intermediate certificate is trusted, FindTrustAnchorsForCert should
185 // return that cert on any certs issued by the intermediate, but not for the
186 // intermediate itself (or the CAs).
187 TEST_F(TrustStoreNSSTest, TrustedIntermediate) {
188 AddCertsToNSS();
189 TrustCert(newintermediate_.get());
190 ExpectTrustStoreContains(
191 FROM_HERE, target_,
192 {TrustAnchor::CreateFromCertificateNoConstraints(newintermediate_)});
193 ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
194 ExpectTrustStoreContains(FROM_HERE, oldintermediate_, TrustAnchors());
195 ExpectTrustStoreContains(FROM_HERE, newrootrollover_, TrustAnchors());
196 ExpectTrustStoreContains(FROM_HERE, oldroot_->cert(), TrustAnchors());
197 ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), TrustAnchors());
198 }
199
200 // Multiple self-signed CA certificates with the same name are trusted.
201 // FindTrustAnchorsForCert should return all these certs on any intermediates
202 // with a matching issuer, and on any matching self-signed/self-issued CA certs.
203 TEST_F(TrustStoreNSSTest, MultipleTrustedCAWithSameSubject) {
204 AddCertsToNSS();
205 TrustCert(oldroot_.get());
206 TrustCert(newroot_.get());
207 ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
208 ExpectTrustStoreContains(FROM_HERE, newintermediate_, {newroot_, oldroot_});
209 ExpectTrustStoreContains(FROM_HERE, oldintermediate_, {newroot_, oldroot_});
210 ExpectTrustStoreContains(FROM_HERE, oldroot_->cert(), {newroot_, oldroot_});
211 }
212
213 // Cancel a FindTrustAnchorsForCert request before it has returned any results.
214 // Callback should not be called.
215 TEST_F(TrustStoreNSSTest, CancelRequest) {
216 std::unique_ptr<TrustStore::Request> req;
217 TrustAnchors sync_matches;
218 trust_store_nss_->FindTrustAnchorsForCert(target_, base::Bind(&NotCalled),
219 &sync_matches, &req);
220 ASSERT_TRUE(req);
221 req.reset();
222 base::RunLoop().RunUntilIdle();
223 }
224
225 // Cancel a FindTrustAnchorsForCert request during the callback. Should not
226 // crash.
227 TEST_F(TrustStoreNSSTest, CancelRequestDuringCallback) {
228 AddCertsToNSS();
229 TrustCert(newroot_.get());
230
231 base::RunLoop run_loop;
232 std::unique_ptr<TrustStore::Request> req;
233 TrustAnchors sync_matches;
234 trust_store_nss_->FindTrustAnchorsForCert(
235 newintermediate_,
236 base::Bind(&TrustStoreRequestDeleter, &req, run_loop.QuitClosure()),
237 &sync_matches, &req);
238 ASSERT_TRUE(req);
239 run_loop.Run();
240 ASSERT_FALSE(req);
241 base::RunLoop().RunUntilIdle();
242 }
243
244 } // namespace
245
246 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/internal/trust_store_nss.cc ('k') | net/cert/internal/trust_store_test_helpers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698