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

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

Issue 2036033002: Add CertIssuerSourceAia: authorityInfoAccess fetching for CertPathBuilder. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert-parsing-path-building
Patch Set: . Created 4 years, 6 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/cert_issuer_source_aia.h"
6
7 #include "base/bind.h"
8 #include "net/cert/internal/parsed_certificate.h"
9 #include "url/gurl.h"
10
11 namespace net {
12
13 namespace {
14
15 // TODO(mattm): These are arbitrary choices. Re-evaluate.
16 const int kTimeoutMilliseconds = 10000;
17 const int kMaxResponseBytes = 65536;
18
19 } // namespace
20
21 CertIssuerSourceAia::CertIssuerSourceAia(CertNetFetcher* cert_fetcher)
22 : cert_fetcher_(cert_fetcher) {}
23
24 CertIssuerSourceAia::~CertIssuerSourceAia() = default;
25
26 void CertIssuerSourceAia::SyncGetIssuersOf(
27 const ParsedCertificate* cert,
28 std::vector<scoped_refptr<ParsedCertificate>>* issuers) {
29 // CertIssuerSourceAia never returns synchronous results.
30 }
31
32 void CertIssuerSourceAia::AsyncGetIssuersOf(
33 const ParsedCertificate* cert,
34 const IssuerCallback& issuers_callback,
35 std::unique_ptr<Request>* out_req) {
36 if (!cert->has_authority_info_access())
37 return;
38
39 // RFC 5280 section 4.2.2.1:
40 //
41 // An authorityInfoAccess extension may include multiple instances of
42 // the id-ad-caIssuers accessMethod. The different instances may
43 // specify different methods for accessing the same information or may
44 // point to different information.
45
46 std::vector<GURL> urls;
47 for (const auto& uri : cert->ca_issuers_uris()) {
48 GURL url(uri);
49 // XXX should HTTPS be disallowed?
eroman 2016/06/03 16:28:52 XXX --> TODO(...)
mattm 2016/06/03 21:27:26 Acknowledged.
50 // XXX should FTP be allowed?
51 if (url.is_valid() && url.SchemeIsHTTPOrHTTPS())
eroman 2016/06/03 16:28:52 We only support http:// for the fetching of AIA [1
mattm 2016/06/03 21:27:26 Agreed. I've done #1 for this CL.
52 urls.push_back(url);
53 }
54 if (urls.empty())
eroman 2016/06/03 16:28:52 I think we also should have a failsafe that bounds
mattm 2016/06/03 21:27:26 Done.
55 return;
56
57 std::unique_ptr<AiaRequest> aia_request(new AiaRequest(issuers_callback));
58
59 for (const auto& url : urls) {
60 aia_request->AddCertFetcherRequest(cert_fetcher_->FetchCaIssuers(
61 url, kTimeoutMilliseconds, kMaxResponseBytes,
62 base::Bind(&AiaRequest::FetchCallback,
63 base::Unretained(aia_request.get()))));
64 }
65
66 *out_req = std::move(aia_request);
67 }
68
69 CertIssuerSourceAia::AiaRequest::AiaRequest(
70 const IssuerCallback& issuers_callback)
71 : issuers_callback_(issuers_callback) {}
72
73 CertIssuerSourceAia::AiaRequest::~AiaRequest() = default;
74
75 CompletionStatus CertIssuerSourceAia::AiaRequest::GetNext(
76 scoped_refptr<ParsedCertificate>* out_cert) {
77 if (current_result_ < results_.size()) {
78 *out_cert = std::move(results_[current_result_++]);
79 return CompletionStatus::SYNC;
80 }
81 *out_cert = nullptr;
82 if (pending_requests_)
83 return CompletionStatus::ASYNC;
84 return CompletionStatus::SYNC;
85 }
86
87 void CertIssuerSourceAia::AiaRequest::AddCertFetcherRequest(
88 std::unique_ptr<CertNetFetcher::Request> cert_fetcher_request) {
89 cert_fetcher_requests_.push_back(std::move(cert_fetcher_request));
90 pending_requests_++;
91 }
92
93 void CertIssuerSourceAia::AiaRequest::FetchCallback(
94 Error error,
95 const std::vector<uint8_t>& fetched_bytes) {
96 DCHECK(pending_requests_ > 0);
97 pending_requests_--;
98 bool client_waiting_for_callback = current_result_ >= results_.size();
99 if (error != OK) {
100 LOG(ERROR) << "AiaRequest::FetchCallback got error " << error;
eroman 2016/06/03 16:28:52 Please add a TODO here. Rather than swallowing the
mattm 2016/06/03 21:27:26 Done.
101 } else {
102 // RFC 5280 section 4.2.2.1:
103 //
104 // Conforming applications that support HTTP or FTP for accessing
105 // certificates MUST be able to accept individual DER encoded
106 // certificates and SHOULD be able to accept "certs-only" CMS messages.
107 //
108 // TODO(mattm): Is supporting CMS message format important?
109 if (!ParsedCertificate::CreateAndAddToVector(
110 fetched_bytes.data(), fetched_bytes.size(),
111 ParsedCertificate::DataSource::INTERNAL_COPY, &results_)) {
eroman 2016/06/03 16:28:52 Can you add a TODO to avoid copying the bytes? (W
mattm 2016/06/03 21:27:26 Done.
112 LOG(ERROR) << "Error parsing AIA data";
eroman 2016/06/03 16:28:52 Also add a TODO here about the error propagation.
mattm 2016/06/03 21:27:26 Done.
113 }
114 }
115 // If the client is waiting for results, need to run callback if:
116 // * Some are available now.
117 // * The last fetch finished, even with no results. (Client needs to know to
118 // stop waiting.)
119 if (client_waiting_for_callback &&
120 (current_result_ < results_.size() || pending_requests_ == 0)) {
121 issuers_callback_.Run(this);
122 }
123 }
124
125 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698