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

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: rebaes 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
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
39 ReadVerifyCertChainTestFromFile("key-rollover-oldchain.pem", &chain,
40 &oldroot_, &unused_time,
41 &unused_verify_result);
42 ASSERT_EQ(2U, chain.size());
43 target_ = chain[0];
44 oldintermediate_ = chain[1];
45 ASSERT_TRUE(target_);
46 ASSERT_TRUE(oldintermediate_);
47 ASSERT_TRUE(oldroot_);
48
49 scoped_refptr<TrustAnchor> unused_root;
50 ReadVerifyCertChainTestFromFile("key-rollover-longrolloverchain.pem",
51 &chain, &unused_root, &unused_time,
52 &unused_verify_result);
53 ASSERT_EQ(4U, chain.size());
54 newintermediate_ = chain[1];
55 newroot_ = TrustAnchor::CreateFromCertificateNoConstraints(chain[2]);
56 newrootrollover_ = chain[3];
57 ASSERT_TRUE(newintermediate_);
58 ASSERT_TRUE(newroot_);
59 ASSERT_TRUE(newrootrollover_);
60
61 trust_store_nss_.reset(
62 new TrustStoreNSS(base::ThreadTaskRunnerHandle::Get()));
63 }
64
65 std::string GetUniqueNickname() {
66 return "trust_store_nss_unittest" + base::UintToString(nickname_counter_++);
67 }
68
69 void AddCertToNSS(const ParsedCertificate* cert) {
70 std::string nickname = GetUniqueNickname();
71 ScopedCERTCertificate nss_cert(
72 X509Certificate::CreateOSCertHandleFromBytesWithNickname(
73 cert->der_cert().AsStringPiece().data(), cert->der_cert().Length(),
74 nickname.c_str()));
75 ASSERT_TRUE(nss_cert);
76 SECStatus srv =
77 PK11_ImportCert(test_nssdb_.slot(), nss_cert.get(), CK_INVALID_HANDLE,
78 nickname.c_str(), PR_FALSE /* includeTrust (unused) */);
79 ASSERT_EQ(SECSuccess, srv);
80 }
81
82 void AddCertsToNSS() {
83 AddCertToNSS(target_.get());
84 AddCertToNSS(oldintermediate_.get());
85 AddCertToNSS(newintermediate_.get());
86 AddCertToNSS(oldroot_->cert().get());
87 AddCertToNSS(newroot_->cert().get());
88 AddCertToNSS(newrootrollover_.get());
89 }
90
91 // Trusts |cert|. Assumes the cert was already imported into NSS.
92 void TrustCert(const TrustAnchor* anchor) { TrustCert(anchor->cert().get()); }
93 void TrustCert(const ParsedCertificate* cert) {
94 SECItem der_cert;
95 der_cert.data = const_cast<uint8_t*>(cert->der_cert().UnsafeData());
96 der_cert.len = base::checked_cast<unsigned>(cert->der_cert().Length());
97 der_cert.type = siDERCertBuffer;
98
99 ScopedCERTCertificate nss_cert(
100 CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &der_cert));
101 ASSERT_TRUE(nss_cert);
102
103 CERTCertTrust trust = {0};
104 trust.sslFlags =
105 CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA | CERTDB_VALID_CA;
106 SECStatus srv =
107 CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nss_cert.get(), &trust);
108 ASSERT_EQ(SECSuccess, srv);
109 }
110
111 protected:
112 void ExpectTrustStoreContains(tracked_objects::Location loc,
113 scoped_refptr<ParsedCertificate> cert,
114 TrustAnchors expected_async_matches) {
115 SCOPED_TRACE(loc.ToString());
116
117 TrustAnchors sync_matches;
118 TrustAnchorResultRecorder anchor_results;
119 std::unique_ptr<TrustStore::Request> req;
120 trust_store_nss_->FindTrustAnchorsForCert(cert, anchor_results.Callback(),
121 &sync_matches, &req);
122 ASSERT_TRUE(req);
123 EXPECT_TRUE(sync_matches.empty());
124
125 anchor_results.Run();
126 std::vector<der::Input> der_result_matches;
127 for (const auto& it : anchor_results.matches())
128 der_result_matches.push_back(it->cert()->der_cert());
129 std::sort(der_result_matches.begin(), der_result_matches.end());
130
131 std::vector<der::Input> der_expected_matches;
132 for (const auto& it : expected_async_matches)
133 der_expected_matches.push_back(it->cert()->der_cert());
134 std::sort(der_expected_matches.begin(), der_expected_matches.end());
135
136 EXPECT_EQ(der_expected_matches, der_result_matches);
137 }
138
139 scoped_refptr<TrustAnchor> oldroot_;
140 scoped_refptr<TrustAnchor> newroot_;
141
142 scoped_refptr<ParsedCertificate> target_;
143 scoped_refptr<ParsedCertificate> oldintermediate_;
144 scoped_refptr<ParsedCertificate> newintermediate_;
145 scoped_refptr<ParsedCertificate> newrootrollover_;
146 crypto::ScopedTestNSSDB test_nssdb_;
147 std::unique_ptr<TrustStoreNSS> trust_store_nss_;
148 unsigned nickname_counter_ = 0;
149 };
150
151 // Without adding any certs to the NSS DB, should get no anchor results for any
152 // of the test certs.
153 TEST_F(TrustStoreNSSTest, CertsNotPresent) {
154 ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
155 ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
156 ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), TrustAnchors());
157 }
158
159 // If certs are present in NSS DB but aren't marked as trusted, should get no
160 // anchor results for any of the test certs.
161 TEST_F(TrustStoreNSSTest, CertsPresentButNotTrusted) {
162 AddCertsToNSS();
163 ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
164 ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
165 ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
166 ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), TrustAnchors());
167 }
168
169 // A self-signed CA certificate is trusted. FindTrustAnchorsForCert should
170 // return the cert on any intermediates with a matching issuer, and on any
171 // matching self-signed/self-issued CA certs.
172 TEST_F(TrustStoreNSSTest, TrustedCA) {
173 AddCertsToNSS();
174 TrustCert(newroot_.get());
175 ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
176 ExpectTrustStoreContains(FROM_HERE, newintermediate_, {newroot_});
177 ExpectTrustStoreContains(FROM_HERE, oldintermediate_, {newroot_});
178 ExpectTrustStoreContains(FROM_HERE, newrootrollover_, {newroot_});
179 ExpectTrustStoreContains(FROM_HERE, oldroot_->cert(), {newroot_});
180 ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), {newroot_});
181 }
182
183 // When an intermediate certificate is trusted, FindTrustAnchorsForCert should
184 // return that cert on any certs issued by the intermediate, but not for the
185 // intermediate itself (or the CAs).
186 TEST_F(TrustStoreNSSTest, TrustedIntermediate) {
187 AddCertsToNSS();
188 TrustCert(newintermediate_.get());
189 ExpectTrustStoreContains(
190 FROM_HERE, target_,
191 {TrustAnchor::CreateFromCertificateNoConstraints(newintermediate_)});
192 ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
193 ExpectTrustStoreContains(FROM_HERE, oldintermediate_, TrustAnchors());
194 ExpectTrustStoreContains(FROM_HERE, newrootrollover_, TrustAnchors());
195 ExpectTrustStoreContains(FROM_HERE, oldroot_->cert(), TrustAnchors());
196 ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), TrustAnchors());
197 }
198
199 // Multiple self-signed CA certificates with the same name are trusted.
200 // FindTrustAnchorsForCert should return all these certs on any intermediates
201 // with a matching issuer, and on any matching self-signed/self-issued CA certs.
202 TEST_F(TrustStoreNSSTest, MultipleTrustedCAWithSameSubject) {
203 AddCertsToNSS();
204 TrustCert(oldroot_.get());
205 TrustCert(newroot_.get());
206 ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
207 ExpectTrustStoreContains(FROM_HERE, newintermediate_, {newroot_, oldroot_});
208 ExpectTrustStoreContains(FROM_HERE, oldintermediate_, {newroot_, oldroot_});
209 ExpectTrustStoreContains(FROM_HERE, oldroot_->cert(), {newroot_, oldroot_});
210 }
211
212 // Cancel a FindTrustAnchorsForCert request before it has returned any results.
213 // Callback should not be called.
214 TEST_F(TrustStoreNSSTest, CancelRequest) {
215 std::unique_ptr<TrustStore::Request> req;
216 TrustAnchors sync_matches;
217 trust_store_nss_->FindTrustAnchorsForCert(target_, base::Bind(&NotCalled),
218 &sync_matches, &req);
219 ASSERT_TRUE(req);
220 req.reset();
221 base::RunLoop().RunUntilIdle();
222 }
223
224 // Cancel a FindTrustAnchorsForCert request during the callback. Should not
225 // crash.
226 TEST_F(TrustStoreNSSTest, CancelRequestDuringCallback) {
227 AddCertsToNSS();
228 TrustCert(newroot_.get());
229
230 base::RunLoop run_loop;
231 std::unique_ptr<TrustStore::Request> req;
232 TrustAnchors sync_matches;
233 trust_store_nss_->FindTrustAnchorsForCert(
234 newintermediate_,
235 base::Bind(&TrustStoreRequestDeleter, &req, run_loop.QuitClosure()),
236 &sync_matches, &req);
237 ASSERT_TRUE(req);
238 run_loop.Run();
239 ASSERT_FALSE(req);
240 base::RunLoop().RunUntilIdle();
241 }
242
243 } // namespace
244
245 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698