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

Unified 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, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | net/cert/internal/path_builder_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/cert/internal/path_builder.cc
diff --git a/net/cert/internal/path_builder.cc b/net/cert/internal/path_builder.cc
index 10b507bc594c3849d63aa2af78c35ad8a1c5d08a..26e366410e87bfe4844dfa1715db05400bc9bbeb 100644
--- a/net/cert/internal/path_builder.cc
+++ b/net/cert/internal/path_builder.cc
@@ -65,11 +65,11 @@ struct CertificateOrTrustAnchor {
// which may be issuers of |cert|.
class CertIssuersIter {
public:
- // Constructs the CertIssuersIter. |*cert_issuer_sources| must be valid for
- // the lifetime of the CertIssuersIter.
+ // Constructs the CertIssuersIter. |*cert_issuer_sources| and |*trust_store|
+ // must be valid for the lifetime of the CertIssuersIter.
CertIssuersIter(scoped_refptr<ParsedCertificate> cert,
CertIssuerSources* cert_issuer_sources,
- const TrustStore& trust_store);
+ const TrustStore* trust_store);
// Gets the next candidate issuer. If an issuer is ready synchronously, SYNC
// is returned and the cert is stored in |*cert|. If an issuer is not
@@ -85,10 +85,14 @@ class CertIssuersIter {
scoped_refptr<ParsedCertificate> reference_cert() const { return cert_; }
private:
+ void DoAsyncIssuerQuery();
+ void GotAsyncAnchors(TrustAnchors anchors);
void GotAsyncCerts(CertIssuerSource::Request* request);
+ void NotifyIfNecessary();
scoped_refptr<ParsedCertificate> cert_;
CertIssuerSources* cert_issuer_sources_;
+ const TrustStore* trust_store_;
// The list of trust anchors that match the issuer name for |cert_|.
TrustAnchors anchors_;
@@ -112,14 +116,16 @@ class CertIssuersIter {
// This points to data owned by |issuers_|.
std::unordered_set<base::StringPiece, base::StringPieceHash> present_issuers_;
- // Tracks whether asynchronous requests have been made yet.
- bool did_async_query_ = false;
+ // Tracks which requests have been made yet.
+ bool did_initial_query_ = false;
+ bool did_async_issuer_query_ = false;
// If asynchronous requests were made, how many of them are still outstanding?
size_t pending_async_results_;
// Owns the Request objects for any asynchronous requests so that they will be
// cancelled if CertIssuersIter is destroyed.
std::vector<std::unique_ptr<CertIssuerSource::Request>>
pending_async_requests_;
+ std::unique_ptr<TrustStore::Request> pending_anchor_request_;
// When GetNextIssuer was called and returned asynchronously, |*out_| is
// where the result will be stored, and |callback_| will be run when the
@@ -132,28 +138,11 @@ class CertIssuersIter {
CertIssuersIter::CertIssuersIter(scoped_refptr<ParsedCertificate> in_cert,
CertIssuerSources* cert_issuer_sources,
- const TrustStore& trust_store)
- : cert_(in_cert), cert_issuer_sources_(cert_issuer_sources) {
+ const TrustStore* trust_store)
+ : cert_(in_cert),
+ cert_issuer_sources_(cert_issuer_sources),
+ trust_store_(trust_store) {
DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) << ") created";
- trust_store.FindTrustAnchorsByNormalizedName(in_cert->normalized_issuer(),
- &anchors_);
-
- for (auto* cert_issuer_source : *cert_issuer_sources_) {
- ParsedCertificateList new_issuers;
- cert_issuer_source->SyncGetIssuersOf(cert(), &new_issuers);
- for (scoped_refptr<ParsedCertificate>& issuer : new_issuers) {
- if (present_issuers_.find(issuer->der_cert().AsStringPiece()) !=
- present_issuers_.end())
- continue;
- present_issuers_.insert(issuer->der_cert().AsStringPiece());
- issuers_.push_back(std::move(issuer));
- }
- }
- // TODO(mattm): sort by notbefore, etc (eg if cert issuer matches a trust
- // anchor subject (or is a trust anchor), that should be sorted higher too.
- // See big list of possible sorting hints in RFC 4158.)
- // (Update PathBuilderKeyRolloverTest.TestRolloverBothRootsTrusted once that
- // is done)
}
CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out,
@@ -161,6 +150,35 @@ CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out,
// Should not be called again while already waiting for an async result.
DCHECK(callback_.is_null());
+ if (!did_initial_query_) {
+ did_initial_query_ = true;
+ trust_store_->FindTrustAnchorsForCert(
+ cert_.get(),
+ callback.is_null() ? TrustStore::TrustAnchorsCallback()
+ : base::Bind(&CertIssuersIter::GotAsyncAnchors,
+ base::Unretained(this)),
+ &anchors_, &pending_anchor_request_);
+
+ for (auto* cert_issuer_source : *cert_issuer_sources_) {
+ ParsedCertificateList new_issuers;
+ cert_issuer_source->SyncGetIssuersOf(cert(), &new_issuers);
+ for (scoped_refptr<ParsedCertificate>& issuer : new_issuers) {
+ if (present_issuers_.find(issuer->der_cert().AsStringPiece()) !=
+ present_issuers_.end())
+ continue;
+ present_issuers_.insert(issuer->der_cert().AsStringPiece());
+ issuers_.push_back(std::move(issuer));
+ }
+ }
+ DVLOG(1) << anchors_.size() << " sync anchors, " << issuers_.size()
+ << " sync issuers";
+ // TODO(mattm): sort by notbefore, etc (eg if cert issuer matches a trust
+ // anchor subject (or is a trust anchor), that should be sorted higher too.
+ // See big list of possible sorting hints in RFC 4158.)
+ // (Update PathBuilderKeyRolloverTest.TestRolloverBothRootsTrusted once that
+ // is done)
+ }
+
// Return possible trust anchors first.
if (cur_anchor_ < anchors_.size()) {
DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
@@ -171,6 +189,14 @@ CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out,
return CompletionStatus::SYNC;
}
+ if (pending_anchor_request_) {
+ DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
+ << ") Still waiting for async trust anchor results.";
+ out_ = out;
+ callback_ = callback;
+ return CompletionStatus::ASYNC;
+ }
+
if (cur_issuer_ < issuers_.size()) {
DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
<< "): returning issuer " << cur_issuer_ << " of "
@@ -181,7 +207,8 @@ CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out,
*out = CertificateOrTrustAnchor(issuers_[cur_issuer_++]);
return CompletionStatus::SYNC;
}
- if (did_async_query_) {
+
+ if (did_async_issuer_query_) {
if (pending_async_results_ == 0) {
DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
<< ") Reached the end of all available issuers.";
@@ -207,7 +234,27 @@ CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out,
}
// Now issue request(s) for async ones (AIA, etc).
- did_async_query_ = true;
+ DoAsyncIssuerQuery();
+
+ if (pending_async_results_ == 0) {
+ DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
+ << ") No cert sources have async results.";
+ // No cert sources have async results.
+ *out = CertificateOrTrustAnchor();
+ return CompletionStatus::SYNC;
+ }
+
+ DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
+ << ") issued AsyncGetIssuersOf call(s) (n=" << pending_async_results_
+ << ")";
+ out_ = out;
+ callback_ = callback;
+ return CompletionStatus::ASYNC;
+}
+
+void CertIssuersIter::DoAsyncIssuerQuery() {
+ DCHECK(!did_async_issuer_query_);
+ did_async_issuer_query_ = true;
pending_async_results_ = 0;
for (auto* cert_issuer_source : *cert_issuer_sources_) {
std::unique_ptr<CertIssuerSource::Request> request;
@@ -222,21 +269,16 @@ CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out,
pending_async_requests_.push_back(std::move(request));
}
}
+}
- if (pending_async_results_ == 0) {
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << ") No cert sources have async results.";
- // No cert sources have async results.
- *out = CertificateOrTrustAnchor();
- return CompletionStatus::SYNC;
- }
+void CertIssuersIter::GotAsyncAnchors(TrustAnchors anchors) {
+ DVLOG(1) << "CertIssuersIter::GotAsyncAnchors(" << CertDebugString(cert())
+ << "): " << anchors.size() << " anchors";
+ for (scoped_refptr<TrustAnchor>& anchor : anchors)
+ anchors_.push_back(std::move(anchor));
+ pending_anchor_request_.reset();
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << ") issued AsyncGetIssuersOf call(s) (n=" << pending_async_results_
- << ")";
- out_ = out;
- callback_ = callback;
- return CompletionStatus::ASYNC;
+ NotifyIfNecessary();
}
void CertIssuersIter::GotAsyncCerts(CertIssuerSource::Request* request) {
@@ -265,25 +307,43 @@ void CertIssuersIter::GotAsyncCerts(CertIssuerSource::Request* request) {
// TODO(mattm): re-sort remaining elements of issuers_ (remaining elements may
// be more than the ones just inserted, depending on |cur_| value).
+ NotifyIfNecessary();
+}
+
+void CertIssuersIter::NotifyIfNecessary() {
// Notify that more results are available, if necessary.
if (!callback_.is_null()) {
- DCHECK_GE(cur_anchor_, anchors_.size());
+ if (cur_anchor_ < anchors_.size()) {
+ DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
+ << "): async returning anchor " << cur_anchor_ << " of "
+ << anchors_.size();
+ *out_ = CertificateOrTrustAnchor(std::move(anchors_[cur_anchor_++]));
+ base::ResetAndReturn(&callback_).Run();
+ return;
+ }
if (cur_issuer_ < issuers_.size()) {
+ DCHECK(!pending_anchor_request_);
DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << "): async returning item " << cur_issuer_ << " of "
+ << "): async returning issuer " << cur_issuer_ << " of "
<< issuers_.size();
*out_ = CertificateOrTrustAnchor(std::move(issuers_[cur_issuer_++]));
base::ResetAndReturn(&callback_).Run();
- } else if (pending_async_results_ == 0) {
+ return;
+ }
+
+ if (!did_async_issuer_query_)
+ DoAsyncIssuerQuery();
+
+ if (pending_async_results_ == 0) {
DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
<< "): async returning empty result";
*out_ = CertificateOrTrustAnchor();
base::ResetAndReturn(&callback_).Run();
- } else {
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << "): empty result, but other async results "
- "pending, waiting..";
+ return;
}
+ DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
+ << "): empty result, but other async results "
+ "pending, waiting..";
}
}
@@ -517,7 +577,7 @@ CompletionStatus CertPathIter::DoGetNextIssuerComplete() {
}
cur_path_.Append(base::WrapUnique(new CertIssuersIter(
- std::move(next_issuer_.cert), &cert_issuer_sources_, *trust_store_)));
+ std::move(next_issuer_.cert), &cert_issuer_sources_, trust_store_)));
next_issuer_ = CertificateOrTrustAnchor();
DVLOG(1) << "CertPathIter cur_path_ = " << cur_path_.PathDebugString();
// Continue descending the tree.
« 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