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

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

Issue 2266333002: Allow TrustStore queries to be asynchronous. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: typo 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 | « no previous file | net/cert/internal/path_builder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/cert/internal/path_builder.h" 5 #include "net/cert/internal/path_builder.h"
6 6
7 #include <set> 7 #include <set>
8 #include <unordered_set> 8 #include <unordered_set>
9 9
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 bool IsEmpty() const { return !IsTrustAnchor() && !IsCertificate(); } 58 bool IsEmpty() const { return !IsTrustAnchor() && !IsCertificate(); }
59 59
60 scoped_refptr<ParsedCertificate> cert; 60 scoped_refptr<ParsedCertificate> cert;
61 scoped_refptr<TrustAnchor> anchor; 61 scoped_refptr<TrustAnchor> anchor;
62 }; 62 };
63 63
64 // CertIssuersIter iterates through the intermediates from |cert_issuer_sources| 64 // CertIssuersIter iterates through the intermediates from |cert_issuer_sources|
65 // which may be issuers of |cert|. 65 // which may be issuers of |cert|.
66 class CertIssuersIter { 66 class CertIssuersIter {
67 public: 67 public:
68 // Constructs the CertIssuersIter. |*cert_issuer_sources| must be valid for 68 // Constructs the CertIssuersIter. |*cert_issuer_sources| and |*trust_store|
69 // the lifetime of the CertIssuersIter. 69 // must be valid for the lifetime of the CertIssuersIter.
70 CertIssuersIter(scoped_refptr<ParsedCertificate> cert, 70 CertIssuersIter(scoped_refptr<ParsedCertificate> cert,
71 CertIssuerSources* cert_issuer_sources, 71 CertIssuerSources* cert_issuer_sources,
72 const TrustStore& trust_store); 72 const TrustStore* trust_store);
73 73
74 // Gets the next candidate issuer. If an issuer is ready synchronously, SYNC 74 // Gets the next candidate issuer. If an issuer is ready synchronously, SYNC
75 // is returned and the cert is stored in |*cert|. If an issuer is not 75 // is returned and the cert is stored in |*cert|. If an issuer is not
76 // ready, ASYNC is returned and |callback| will be called once |*out_cert| has 76 // ready, ASYNC is returned and |callback| will be called once |*out_cert| has
77 // been set. If |callback| is null, always completes synchronously. 77 // been set. If |callback| is null, always completes synchronously.
78 // 78 //
79 // In either case, if all issuers have been exhausted, |*out| is cleared. 79 // In either case, if all issuers have been exhausted, |*out| is cleared.
80 CompletionStatus GetNextIssuer(CertificateOrTrustAnchor* out, 80 CompletionStatus GetNextIssuer(CertificateOrTrustAnchor* out,
81 const base::Closure& callback); 81 const base::Closure& callback);
82 82
83 // Returns the |cert| for which issuers are being retrieved. 83 // Returns the |cert| for which issuers are being retrieved.
84 const ParsedCertificate* cert() const { return cert_.get(); } 84 const ParsedCertificate* cert() const { return cert_.get(); }
85 scoped_refptr<ParsedCertificate> reference_cert() const { return cert_; } 85 scoped_refptr<ParsedCertificate> reference_cert() const { return cert_; }
86 86
87 private: 87 private:
88 void DoAsyncIssuerQuery();
89 void GotAsyncAnchors(TrustAnchors anchors);
88 void GotAsyncCerts(CertIssuerSource::Request* request); 90 void GotAsyncCerts(CertIssuerSource::Request* request);
91 void NotifyIfNecessary();
89 92
90 scoped_refptr<ParsedCertificate> cert_; 93 scoped_refptr<ParsedCertificate> cert_;
91 CertIssuerSources* cert_issuer_sources_; 94 CertIssuerSources* cert_issuer_sources_;
95 const TrustStore* trust_store_;
92 96
93 // The list of trust anchors that match the issuer name for |cert_|. 97 // The list of trust anchors that match the issuer name for |cert_|.
94 TrustAnchors anchors_; 98 TrustAnchors anchors_;
95 // The index of the next trust anchor in |anchors_| to return. 99 // The index of the next trust anchor in |anchors_| to return.
96 size_t cur_anchor_ = 0; 100 size_t cur_anchor_ = 0;
97 101
98 // The list of issuers for |cert_|. This is added to incrementally (first 102 // The list of issuers for |cert_|. This is added to incrementally (first
99 // synchronous results, then possibly multiple times as asynchronous results 103 // synchronous results, then possibly multiple times as asynchronous results
100 // arrive.) The issuers may be re-sorted each time new issuers are added, but 104 // arrive.) The issuers may be re-sorted each time new issuers are added, but
101 // only the results from |cur_| onwards should be sorted, since the earlier 105 // only the results from |cur_| onwards should be sorted, since the earlier
102 // results were already returned. 106 // results were already returned.
103 // Elements should not be removed from |issuers_| once added, since 107 // Elements should not be removed from |issuers_| once added, since
104 // |present_issuers_| will point to data owned by the certs. 108 // |present_issuers_| will point to data owned by the certs.
105 ParsedCertificateList issuers_; 109 ParsedCertificateList issuers_;
106 // The index of the next cert in |issuers_| to return. 110 // The index of the next cert in |issuers_| to return.
107 size_t cur_issuer_ = 0; 111 size_t cur_issuer_ = 0;
108 112
109 // Set of DER-encoded values for the certs in |issuers_|. Used to prevent 113 // Set of DER-encoded values for the certs in |issuers_|. Used to prevent
110 // duplicates. This is based on the full DER of the cert to allow different 114 // duplicates. This is based on the full DER of the cert to allow different
111 // versions of the same certificate to be tried in different candidate paths. 115 // versions of the same certificate to be tried in different candidate paths.
112 // This points to data owned by |issuers_|. 116 // This points to data owned by |issuers_|.
113 std::unordered_set<base::StringPiece, base::StringPieceHash> present_issuers_; 117 std::unordered_set<base::StringPiece, base::StringPieceHash> present_issuers_;
114 118
115 // Tracks whether asynchronous requests have been made yet. 119 // Tracks which requests have been made yet.
116 bool did_async_query_ = false; 120 bool did_initial_query_ = false;
121 bool did_async_issuer_query_ = false;
117 // If asynchronous requests were made, how many of them are still outstanding? 122 // If asynchronous requests were made, how many of them are still outstanding?
118 size_t pending_async_results_; 123 size_t pending_async_results_;
119 // Owns the Request objects for any asynchronous requests so that they will be 124 // Owns the Request objects for any asynchronous requests so that they will be
120 // cancelled if CertIssuersIter is destroyed. 125 // cancelled if CertIssuersIter is destroyed.
121 std::vector<std::unique_ptr<CertIssuerSource::Request>> 126 std::vector<std::unique_ptr<CertIssuerSource::Request>>
122 pending_async_requests_; 127 pending_async_requests_;
128 std::unique_ptr<TrustStore::Request> pending_anchor_request_;
123 129
124 // When GetNextIssuer was called and returned asynchronously, |*out_| is 130 // When GetNextIssuer was called and returned asynchronously, |*out_| is
125 // where the result will be stored, and |callback_| will be run when the 131 // where the result will be stored, and |callback_| will be run when the
126 // result is ready. 132 // result is ready.
127 CertificateOrTrustAnchor* out_; 133 CertificateOrTrustAnchor* out_;
128 base::Closure callback_; 134 base::Closure callback_;
129 135
130 DISALLOW_COPY_AND_ASSIGN(CertIssuersIter); 136 DISALLOW_COPY_AND_ASSIGN(CertIssuersIter);
131 }; 137 };
132 138
133 CertIssuersIter::CertIssuersIter(scoped_refptr<ParsedCertificate> in_cert, 139 CertIssuersIter::CertIssuersIter(scoped_refptr<ParsedCertificate> in_cert,
134 CertIssuerSources* cert_issuer_sources, 140 CertIssuerSources* cert_issuer_sources,
135 const TrustStore& trust_store) 141 const TrustStore* trust_store)
136 : cert_(in_cert), cert_issuer_sources_(cert_issuer_sources) { 142 : cert_(in_cert),
143 cert_issuer_sources_(cert_issuer_sources),
144 trust_store_(trust_store) {
137 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) << ") created"; 145 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) << ") created";
138 trust_store.FindTrustAnchorsByNormalizedName(in_cert->normalized_issuer(),
139 &anchors_);
140
141 for (auto* cert_issuer_source : *cert_issuer_sources_) {
142 ParsedCertificateList new_issuers;
143 cert_issuer_source->SyncGetIssuersOf(cert(), &new_issuers);
144 for (scoped_refptr<ParsedCertificate>& issuer : new_issuers) {
145 if (present_issuers_.find(issuer->der_cert().AsStringPiece()) !=
146 present_issuers_.end())
147 continue;
148 present_issuers_.insert(issuer->der_cert().AsStringPiece());
149 issuers_.push_back(std::move(issuer));
150 }
151 }
152 // TODO(mattm): sort by notbefore, etc (eg if cert issuer matches a trust
153 // anchor subject (or is a trust anchor), that should be sorted higher too.
154 // See big list of possible sorting hints in RFC 4158.)
155 // (Update PathBuilderKeyRolloverTest.TestRolloverBothRootsTrusted once that
156 // is done)
157 } 146 }
158 147
159 CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out, 148 CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out,
160 const base::Closure& callback) { 149 const base::Closure& callback) {
161 // Should not be called again while already waiting for an async result. 150 // Should not be called again while already waiting for an async result.
162 DCHECK(callback_.is_null()); 151 DCHECK(callback_.is_null());
163 152
153 if (!did_initial_query_) {
154 did_initial_query_ = true;
155 trust_store_->FindTrustAnchorsForCert(
156 cert_.get(),
157 callback.is_null() ? TrustStore::TrustAnchorsCallback()
158 : base::Bind(&CertIssuersIter::GotAsyncAnchors,
159 base::Unretained(this)),
160 &anchors_, &pending_anchor_request_);
161
162 for (auto* cert_issuer_source : *cert_issuer_sources_) {
163 ParsedCertificateList new_issuers;
164 cert_issuer_source->SyncGetIssuersOf(cert(), &new_issuers);
165 for (scoped_refptr<ParsedCertificate>& issuer : new_issuers) {
166 if (present_issuers_.find(issuer->der_cert().AsStringPiece()) !=
167 present_issuers_.end())
168 continue;
169 present_issuers_.insert(issuer->der_cert().AsStringPiece());
170 issuers_.push_back(std::move(issuer));
171 }
172 }
173 DVLOG(1) << anchors_.size() << " sync anchors, " << issuers_.size()
174 << " sync issuers";
175 // TODO(mattm): sort by notbefore, etc (eg if cert issuer matches a trust
176 // anchor subject (or is a trust anchor), that should be sorted higher too.
177 // See big list of possible sorting hints in RFC 4158.)
178 // (Update PathBuilderKeyRolloverTest.TestRolloverBothRootsTrusted once that
179 // is done)
180 }
181
164 // Return possible trust anchors first. 182 // Return possible trust anchors first.
165 if (cur_anchor_ < anchors_.size()) { 183 if (cur_anchor_ < anchors_.size()) {
166 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) 184 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
167 << "): returning anchor " << cur_anchor_ << " of " 185 << "): returning anchor " << cur_anchor_ << " of "
168 << anchors_.size(); 186 << anchors_.size();
169 // Still have anchors that haven't been returned yet, return one of them. 187 // Still have anchors that haven't been returned yet, return one of them.
170 *out = CertificateOrTrustAnchor(anchors_[cur_anchor_++]); 188 *out = CertificateOrTrustAnchor(anchors_[cur_anchor_++]);
171 return CompletionStatus::SYNC; 189 return CompletionStatus::SYNC;
172 } 190 }
173 191
192 if (pending_anchor_request_) {
193 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
194 << ") Still waiting for async trust anchor results.";
195 out_ = out;
196 callback_ = callback;
197 return CompletionStatus::ASYNC;
198 }
199
174 if (cur_issuer_ < issuers_.size()) { 200 if (cur_issuer_ < issuers_.size()) {
175 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) 201 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
176 << "): returning issuer " << cur_issuer_ << " of " 202 << "): returning issuer " << cur_issuer_ << " of "
177 << issuers_.size(); 203 << issuers_.size();
178 // Still have issuers that haven't been returned yet, return one of them. 204 // Still have issuers that haven't been returned yet, return one of them.
179 // A reference to the returned issuer is retained, since |present_issuers_| 205 // A reference to the returned issuer is retained, since |present_issuers_|
180 // points to data owned by it. 206 // points to data owned by it.
181 *out = CertificateOrTrustAnchor(issuers_[cur_issuer_++]); 207 *out = CertificateOrTrustAnchor(issuers_[cur_issuer_++]);
182 return CompletionStatus::SYNC; 208 return CompletionStatus::SYNC;
183 } 209 }
184 if (did_async_query_) { 210
211 if (did_async_issuer_query_) {
185 if (pending_async_results_ == 0) { 212 if (pending_async_results_ == 0) {
186 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) 213 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
187 << ") Reached the end of all available issuers."; 214 << ") Reached the end of all available issuers.";
188 // Reached the end of all available issuers. 215 // Reached the end of all available issuers.
189 *out = CertificateOrTrustAnchor(); 216 *out = CertificateOrTrustAnchor();
190 return CompletionStatus::SYNC; 217 return CompletionStatus::SYNC;
191 } 218 }
192 219
193 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) 220 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
194 << ") Still waiting for async results from other " 221 << ") Still waiting for async results from other "
195 "CertIssuerSources."; 222 "CertIssuerSources.";
196 // Still waiting for async results from other CertIssuerSources. 223 // Still waiting for async results from other CertIssuerSources.
197 out_ = out; 224 out_ = out;
198 callback_ = callback; 225 callback_ = callback;
199 return CompletionStatus::ASYNC; 226 return CompletionStatus::ASYNC;
200 } 227 }
201 // Reached the end of synchronously gathered issuers. 228 // Reached the end of synchronously gathered issuers.
202 229
203 if (callback.is_null()) { 230 if (callback.is_null()) {
204 // Synchronous-only mode, don't try to query async sources. 231 // Synchronous-only mode, don't try to query async sources.
205 *out = CertificateOrTrustAnchor(); 232 *out = CertificateOrTrustAnchor();
206 return CompletionStatus::SYNC; 233 return CompletionStatus::SYNC;
207 } 234 }
208 235
209 // Now issue request(s) for async ones (AIA, etc). 236 // Now issue request(s) for async ones (AIA, etc).
210 did_async_query_ = true; 237 DoAsyncIssuerQuery();
238
239 if (pending_async_results_ == 0) {
240 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
241 << ") No cert sources have async results.";
242 // No cert sources have async results.
243 *out = CertificateOrTrustAnchor();
244 return CompletionStatus::SYNC;
245 }
246
247 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
248 << ") issued AsyncGetIssuersOf call(s) (n=" << pending_async_results_
249 << ")";
250 out_ = out;
251 callback_ = callback;
252 return CompletionStatus::ASYNC;
253 }
254
255 void CertIssuersIter::DoAsyncIssuerQuery() {
256 DCHECK(!did_async_issuer_query_);
257 did_async_issuer_query_ = true;
211 pending_async_results_ = 0; 258 pending_async_results_ = 0;
212 for (auto* cert_issuer_source : *cert_issuer_sources_) { 259 for (auto* cert_issuer_source : *cert_issuer_sources_) {
213 std::unique_ptr<CertIssuerSource::Request> request; 260 std::unique_ptr<CertIssuerSource::Request> request;
214 cert_issuer_source->AsyncGetIssuersOf( 261 cert_issuer_source->AsyncGetIssuersOf(
215 cert(), 262 cert(),
216 base::Bind(&CertIssuersIter::GotAsyncCerts, base::Unretained(this)), 263 base::Bind(&CertIssuersIter::GotAsyncCerts, base::Unretained(this)),
217 &request); 264 &request);
218 if (request) { 265 if (request) {
219 DVLOG(1) << "AsyncGetIssuersOf(" << CertDebugString(cert()) 266 DVLOG(1) << "AsyncGetIssuersOf(" << CertDebugString(cert())
220 << ") pending..."; 267 << ") pending...";
221 pending_async_results_++; 268 pending_async_results_++;
222 pending_async_requests_.push_back(std::move(request)); 269 pending_async_requests_.push_back(std::move(request));
223 } 270 }
224 } 271 }
272 }
225 273
226 if (pending_async_results_ == 0) { 274 void CertIssuersIter::GotAsyncAnchors(TrustAnchors anchors) {
227 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) 275 DVLOG(1) << "CertIssuersIter::GotAsyncAnchors(" << CertDebugString(cert())
228 << ") No cert sources have async results."; 276 << "): " << anchors.size() << " anchors";
229 // No cert sources have async results. 277 for (scoped_refptr<TrustAnchor>& anchor : anchors)
230 *out = CertificateOrTrustAnchor(); 278 anchors_.push_back(std::move(anchor));
231 return CompletionStatus::SYNC; 279 pending_anchor_request_.reset();
232 }
233 280
234 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) 281 NotifyIfNecessary();
235 << ") issued AsyncGetIssuersOf call(s) (n=" << pending_async_results_
236 << ")";
237 out_ = out;
238 callback_ = callback;
239 return CompletionStatus::ASYNC;
240 } 282 }
241 283
242 void CertIssuersIter::GotAsyncCerts(CertIssuerSource::Request* request) { 284 void CertIssuersIter::GotAsyncCerts(CertIssuerSource::Request* request) {
243 DVLOG(1) << "CertIssuersIter::GotAsyncCerts(" << CertDebugString(cert()) 285 DVLOG(1) << "CertIssuersIter::GotAsyncCerts(" << CertDebugString(cert())
244 << ")"; 286 << ")";
245 while (true) { 287 while (true) {
246 scoped_refptr<ParsedCertificate> cert; 288 scoped_refptr<ParsedCertificate> cert;
247 CompletionStatus status = request->GetNext(&cert); 289 CompletionStatus status = request->GetNext(&cert);
248 if (!cert) { 290 if (!cert) {
249 if (status == CompletionStatus::SYNC) { 291 if (status == CompletionStatus::SYNC) {
250 // Request is exhausted, no more results pending from that 292 // Request is exhausted, no more results pending from that
251 // CertIssuerSource. 293 // CertIssuerSource.
252 DCHECK_GT(pending_async_results_, 0U); 294 DCHECK_GT(pending_async_results_, 0U);
253 pending_async_results_--; 295 pending_async_results_--;
254 } 296 }
255 break; 297 break;
256 } 298 }
257 DCHECK_EQ(status, CompletionStatus::SYNC); 299 DCHECK_EQ(status, CompletionStatus::SYNC);
258 if (present_issuers_.find(cert->der_cert().AsStringPiece()) != 300 if (present_issuers_.find(cert->der_cert().AsStringPiece()) !=
259 present_issuers_.end()) 301 present_issuers_.end())
260 continue; 302 continue;
261 present_issuers_.insert(cert->der_cert().AsStringPiece()); 303 present_issuers_.insert(cert->der_cert().AsStringPiece());
262 issuers_.push_back(std::move(cert)); 304 issuers_.push_back(std::move(cert));
263 } 305 }
264 306
265 // TODO(mattm): re-sort remaining elements of issuers_ (remaining elements may 307 // TODO(mattm): re-sort remaining elements of issuers_ (remaining elements may
266 // be more than the ones just inserted, depending on |cur_| value). 308 // be more than the ones just inserted, depending on |cur_| value).
267 309
310 NotifyIfNecessary();
311 }
312
313 void CertIssuersIter::NotifyIfNecessary() {
268 // Notify that more results are available, if necessary. 314 // Notify that more results are available, if necessary.
269 if (!callback_.is_null()) { 315 if (!callback_.is_null()) {
270 DCHECK_GE(cur_anchor_, anchors_.size()); 316 if (cur_anchor_ < anchors_.size()) {
317 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
318 << "): async returning anchor " << cur_anchor_ << " of "
319 << anchors_.size();
320 *out_ = CertificateOrTrustAnchor(std::move(anchors_[cur_anchor_++]));
321 base::ResetAndReturn(&callback_).Run();
322 return;
323 }
271 if (cur_issuer_ < issuers_.size()) { 324 if (cur_issuer_ < issuers_.size()) {
325 DCHECK(!pending_anchor_request_);
272 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) 326 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
273 << "): async returning item " << cur_issuer_ << " of " 327 << "): async returning issuer " << cur_issuer_ << " of "
274 << issuers_.size(); 328 << issuers_.size();
275 *out_ = CertificateOrTrustAnchor(std::move(issuers_[cur_issuer_++])); 329 *out_ = CertificateOrTrustAnchor(std::move(issuers_[cur_issuer_++]));
276 base::ResetAndReturn(&callback_).Run(); 330 base::ResetAndReturn(&callback_).Run();
277 } else if (pending_async_results_ == 0) { 331 return;
332 }
333
334 if (!did_async_issuer_query_)
335 DoAsyncIssuerQuery();
336
337 if (pending_async_results_ == 0) {
278 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) 338 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
279 << "): async returning empty result"; 339 << "): async returning empty result";
280 *out_ = CertificateOrTrustAnchor(); 340 *out_ = CertificateOrTrustAnchor();
281 base::ResetAndReturn(&callback_).Run(); 341 base::ResetAndReturn(&callback_).Run();
282 } else { 342 return;
283 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
284 << "): empty result, but other async results "
285 "pending, waiting..";
286 } 343 }
344 DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
345 << "): empty result, but other async results "
346 "pending, waiting..";
287 } 347 }
288 } 348 }
289 349
290 // CertIssuerIterPath tracks which certs are present in the path and prevents 350 // CertIssuerIterPath tracks which certs are present in the path and prevents
291 // paths from being built which repeat any certs (including different versions 351 // paths from being built which repeat any certs (including different versions
292 // of the same cert, based on Subject+SubjectAltName+SPKI). 352 // of the same cert, based on Subject+SubjectAltName+SPKI).
293 class CertIssuerIterPath { 353 class CertIssuerIterPath {
294 public: 354 public:
295 // Returns true if |cert| is already present in the path. 355 // Returns true if |cert| is already present in the path.
296 bool IsPresent(const ParsedCertificate* cert) const { 356 bool IsPresent(const ParsedCertificate* cert) const {
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 } 570 }
511 571
512 if (next_issuer_.IsCertificate()) { 572 if (next_issuer_.IsCertificate()) {
513 // Skip this cert if it is already in the chain. 573 // Skip this cert if it is already in the chain.
514 if (cur_path_.IsPresent(next_issuer_.cert.get())) { 574 if (cur_path_.IsPresent(next_issuer_.cert.get())) {
515 next_state_ = STATE_GET_NEXT_ISSUER; 575 next_state_ = STATE_GET_NEXT_ISSUER;
516 return CompletionStatus::SYNC; 576 return CompletionStatus::SYNC;
517 } 577 }
518 578
519 cur_path_.Append(base::WrapUnique(new CertIssuersIter( 579 cur_path_.Append(base::WrapUnique(new CertIssuersIter(
520 std::move(next_issuer_.cert), &cert_issuer_sources_, *trust_store_))); 580 std::move(next_issuer_.cert), &cert_issuer_sources_, trust_store_)));
521 next_issuer_ = CertificateOrTrustAnchor(); 581 next_issuer_ = CertificateOrTrustAnchor();
522 DVLOG(1) << "CertPathIter cur_path_ = " << cur_path_.PathDebugString(); 582 DVLOG(1) << "CertPathIter cur_path_ = " << cur_path_.PathDebugString();
523 // Continue descending the tree. 583 // Continue descending the tree.
524 next_state_ = STATE_GET_NEXT_ISSUER; 584 next_state_ = STATE_GET_NEXT_ISSUER;
525 } else { 585 } else {
526 // TODO(mattm): should also include such paths in CertPathBuilder::Result, 586 // TODO(mattm): should also include such paths in CertPathBuilder::Result,
527 // maybe with a flag to enable it. Or use a visitor pattern so the caller 587 // maybe with a flag to enable it. Or use a visitor pattern so the caller
528 // can decide what to do with any failed paths. 588 // can decide what to do with any failed paths.
529 // No more issuers for current chain, go back up and see if there are any 589 // No more issuers for current chain, go back up and see if there are any
530 // more for the previous cert. 590 // more for the previous cert.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 result_path->error = is_success ? OK : ERR_CERT_AUTHORITY_INVALID; 723 result_path->error = is_success ? OK : ERR_CERT_AUTHORITY_INVALID;
664 // TODO(mattm): set best_result_index based on number or severity of errors. 724 // TODO(mattm): set best_result_index based on number or severity of errors.
665 if (result_path->error == OK) 725 if (result_path->error == OK)
666 out_result_->best_result_index = out_result_->paths.size(); 726 out_result_->best_result_index = out_result_->paths.size();
667 // TODO(mattm): add flag to only return a single path or all attempted paths? 727 // TODO(mattm): add flag to only return a single path or all attempted paths?
668 result_path->path = path; 728 result_path->path = path;
669 out_result_->paths.push_back(std::move(result_path)); 729 out_result_->paths.push_back(std::move(result_path));
670 } 730 }
671 731
672 } // namespace net 732 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/cert/internal/path_builder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698