summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsorin <sorin@chromium.org>2016-02-17 10:45:17 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-17 18:46:51 +0000
commit1bc5eff904e6e20191a0abc2ab7a4c75c31dcc1f (patch)
tree3982cbb00d3e68792199112696315313f3b3560f
parent4ae838b9c5d4ad2b0751c63a5ccd6bda1065989e (diff)
downloadchromium_src-1bc5eff904e6e20191a0abc2ab7a4c75c31dcc1f.zip
chromium_src-1bc5eff904e6e20191a0abc2ab7a4c75c31dcc1f.tar.gz
chromium_src-1bc5eff904e6e20191a0abc2ab7a4c75c31dcc1f.tar.bz2
Implement CUP signing in UpdateClient.
BUG=583027 Review URL: https://codereview.chromium.org/1685323002 Cr-Commit-Position: refs/heads/master@{#375930}
-rw-r--r--chrome/browser/component_updater/chrome_component_updater_configurator.cc5
-rw-r--r--chrome/browser/extensions/updater/chrome_update_client_config.cc4
-rw-r--r--chrome/browser/extensions/updater/chrome_update_client_config.h1
-rw-r--r--components/component_updater/configurator_impl.cc4
-rw-r--r--components/component_updater/configurator_impl.h3
-rw-r--r--components/update_client/action_update_check.cc9
-rw-r--r--components/update_client/action_update_check.h7
-rw-r--r--components/update_client/client_update_protocol_ecdsa.cc21
-rw-r--r--components/update_client/client_update_protocol_ecdsa.h4
-rw-r--r--components/update_client/client_update_protocol_ecdsa_unittest.cc4
-rw-r--r--components/update_client/configurator.h3
-rw-r--r--components/update_client/ping_manager.cc7
-rw-r--r--components/update_client/request_sender.cc140
-rw-r--r--components/update_client/request_sender.h50
-rw-r--r--components/update_client/request_sender_unittest.cc84
-rw-r--r--components/update_client/test_configurator.cc12
-rw-r--r--components/update_client/test_configurator.h3
-rw-r--r--components/update_client/update_checker.cc49
-rw-r--r--components/update_client/update_checker.h9
-rw-r--r--components/update_client/update_checker_unittest.cc56
-rw-r--r--components/update_client/update_client_unittest.cc26
-rw-r--r--components/update_client/utils.cc2
-rw-r--r--ios/chrome/browser/component_updater/ios_component_updater_configurator.cc6
23 files changed, 371 insertions, 138 deletions
diff --git a/chrome/browser/component_updater/chrome_component_updater_configurator.cc b/chrome/browser/component_updater/chrome_component_updater_configurator.cc
index 5f60ccf..fcc40d5 100644
--- a/chrome/browser/component_updater/chrome_component_updater_configurator.cc
+++ b/chrome/browser/component_updater/chrome_component_updater_configurator.cc
@@ -50,6 +50,7 @@ class ChromeConfigurator : public update_client::Configurator {
const override;
bool DeltasEnabled() const override;
bool UseBackgroundDownloader() const override;
+ bool UseCupSigning() const override;
scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner()
const override;
@@ -144,6 +145,10 @@ bool ChromeConfigurator::UseBackgroundDownloader() const {
return configurator_impl_.UseBackgroundDownloader();
}
+bool ChromeConfigurator::UseCupSigning() const {
+ return configurator_impl_.UseCupSigning();
+}
+
// Returns a task runner to run blocking tasks. The task runner continues to run
// after the browser shuts down, until the OS terminates the process. This
// imposes certain requirements for the code using the task runner, such as
diff --git a/chrome/browser/extensions/updater/chrome_update_client_config.cc b/chrome/browser/extensions/updater/chrome_update_client_config.cc
index 3ae3dca..7b81c2d 100644
--- a/chrome/browser/extensions/updater/chrome_update_client_config.cc
+++ b/chrome/browser/extensions/updater/chrome_update_client_config.cc
@@ -87,6 +87,10 @@ bool ChromeUpdateClientConfig::UseBackgroundDownloader() const {
return impl_.UseBackgroundDownloader();
}
+bool ChromeUpdateClientConfig::UseCupSigning() const {
+ return false;
+}
+
ChromeUpdateClientConfig::~ChromeUpdateClientConfig() {}
} // namespace extensions
diff --git a/chrome/browser/extensions/updater/chrome_update_client_config.h b/chrome/browser/extensions/updater/chrome_update_client_config.h
index 7e6b020..3596335 100644
--- a/chrome/browser/extensions/updater/chrome_update_client_config.h
+++ b/chrome/browser/extensions/updater/chrome_update_client_config.h
@@ -41,6 +41,7 @@ class ChromeUpdateClientConfig : public UpdateClientConfig {
const override;
bool DeltasEnabled() const override;
bool UseBackgroundDownloader() const override;
+ bool UseCupSigning() const override;
protected:
friend class base::RefCountedThreadSafe<ChromeUpdateClientConfig>;
diff --git a/components/component_updater/configurator_impl.cc b/components/component_updater/configurator_impl.cc
index 35c1793..6372118 100644
--- a/components/component_updater/configurator_impl.cc
+++ b/components/component_updater/configurator_impl.cc
@@ -178,4 +178,8 @@ bool ConfiguratorImpl::UseBackgroundDownloader() const {
return background_downloads_enabled_;
}
+bool ConfiguratorImpl::UseCupSigning() const {
+ return true;
+}
+
} // namespace component_updater
diff --git a/components/component_updater/configurator_impl.h b/components/component_updater/configurator_impl.h
index 09170d4..d5f99cf 100644
--- a/components/component_updater/configurator_impl.h
+++ b/components/component_updater/configurator_impl.h
@@ -81,6 +81,9 @@ class ConfiguratorImpl {
// non on-demand components.
bool UseBackgroundDownloader() const;
+ // True if signing of update checks is enabled.
+ bool UseCupSigning() const;
+
private:
net::URLRequestContextGetter* url_request_getter_;
std::string extra_info_;
diff --git a/components/update_client/action_update_check.cc b/components/update_client/action_update_check.cc
index 5c411c4..9e31eb6 100644
--- a/components/update_client/action_update_check.cc
+++ b/components/update_client/action_update_check.cc
@@ -96,18 +96,14 @@ void ActionUpdateCheck::Run(UpdateContext* update_context, Callback callback) {
}
void ActionUpdateCheck::UpdateCheckComplete(
- const GURL& original_url,
int error,
- const std::string& error_message,
const UpdateResponse::Results& results) {
DCHECK(thread_checker_.CalledOnValidThread());
- VLOG(1) << "Update check completed from: " << original_url.spec();
-
if (!error)
OnUpdateCheckSucceeded(results);
else
- OnUpdateCheckFailed(error, error_message);
+ OnUpdateCheckFailed(error);
}
void ActionUpdateCheck::OnUpdateCheckSucceeded(
@@ -198,8 +194,7 @@ void ActionUpdateCheck::OnUpdateCheckSucceeded(
UpdateCrx();
}
-void ActionUpdateCheck::OnUpdateCheckFailed(int error,
- const std::string& error_message) {
+void ActionUpdateCheck::OnUpdateCheckFailed(int error) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(error);
diff --git a/components/update_client/action_update_check.h b/components/update_client/action_update_check.h
index b5f1d24..7576d64 100644
--- a/components/update_client/action_update_check.h
+++ b/components/update_client/action_update_check.h
@@ -36,13 +36,10 @@ class ActionUpdateCheck : public Action, private ActionImpl {
void Run(UpdateContext* update_context, Callback callback) override;
private:
- void UpdateCheckComplete(const GURL& original_url,
- int error,
- const std::string& error_message,
- const UpdateResponse::Results& results);
+ void UpdateCheckComplete(int error, const UpdateResponse::Results& results);
void OnUpdateCheckSucceeded(const UpdateResponse::Results& results);
- void OnUpdateCheckFailed(int error, const std::string& error_message);
+ void OnUpdateCheckFailed(int error);
scoped_ptr<UpdateChecker> update_checker_;
const base::Version browser_version_;
diff --git a/components/update_client/client_update_protocol_ecdsa.cc b/components/update_client/client_update_protocol_ecdsa.cc
index 499ece7..8479ceb 100644
--- a/components/update_client/client_update_protocol_ecdsa.cc
+++ b/components/update_client/client_update_protocol_ecdsa.cc
@@ -5,6 +5,7 @@
#include "components/update_client/client_update_protocol_ecdsa.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
@@ -14,6 +15,8 @@
#include "crypto/sha2.h"
#include "crypto/signature_verifier.h"
+namespace update_client {
+
namespace {
// This is the algorithm ID for ECDSA with SHA-256. Parameters are ABSENT.
@@ -46,7 +49,7 @@ std::vector<uint8_t> SHA256HashVec(const std::vector<uint8_t>& vec) {
reinterpret_cast<const char*>(&vec.front()), vec.size()));
}
-bool ParseETagHeader(const base::StringPiece& etag_header_value,
+bool ParseETagHeader(const base::StringPiece& etag_header_value_in,
std::vector<uint8_t>* ecdsa_signature_out,
std::vector<uint8_t>* request_hash_out) {
DCHECK(ecdsa_signature_out);
@@ -55,6 +58,20 @@ bool ParseETagHeader(const base::StringPiece& etag_header_value,
// The ETag value is a UTF-8 string, formatted as "S:H", where:
// * S is the ECDSA signature in DER-encoded ASN.1 form, converted to hex.
// * H is the SHA-256 hash of the observed request body, standard hex format.
+ // A Weak ETag is formatted as W/"S:H". This function treats it the same as a
+ // strong ETag.
+ base::StringPiece etag_header_value(etag_header_value_in);
+
+ // Remove the weak prefix, then remove the begin and the end quotes.
+ const char kWeakETagPrefix[] = "W/";
+ if (etag_header_value.starts_with(kWeakETagPrefix))
+ etag_header_value.remove_prefix(arraysize(kWeakETagPrefix) - 1);
+ if (etag_header_value.size() >= 2 && etag_header_value.starts_with("\"") &&
+ etag_header_value.ends_with("\"")) {
+ etag_header_value.remove_prefix(1);
+ etag_header_value.remove_suffix(1);
+ }
+
const base::StringPiece::size_type delim_pos = etag_header_value.find(':');
if (delim_pos == base::StringPiece::npos || delim_pos == 0 ||
delim_pos == etag_header_value.size() - 1)
@@ -188,3 +205,5 @@ bool ClientUpdateProtocolEcdsa::ValidateResponse(
static_cast<int>(signed_message_hash.size()));
return verifier.VerifyFinal();
}
+
+} // namespace update_client
diff --git a/components/update_client/client_update_protocol_ecdsa.h b/components/update_client/client_update_protocol_ecdsa.h
index 6796626..2459c8c 100644
--- a/components/update_client/client_update_protocol_ecdsa.h
+++ b/components/update_client/client_update_protocol_ecdsa.h
@@ -13,6 +13,8 @@
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
+namespace update_client {
+
// Client Update Protocol v2, or CUP-ECDSA, is used by Google Update (Omaha)
// servers to ensure freshness and authenticity of update checks over HTTP,
// without the overhead of HTTPS -- namely, no PKI, no guarantee of privacy,
@@ -81,4 +83,6 @@ class ClientUpdateProtocolEcdsa {
DISALLOW_IMPLICIT_CONSTRUCTORS(ClientUpdateProtocolEcdsa);
};
+} // namespace update_client
+
#endif // COMPONENTS_UPDATE_CLIENT_CLIENT_UPDATE_PROTOCOL_ECDSA_H_
diff --git a/components/update_client/client_update_protocol_ecdsa_unittest.cc b/components/update_client/client_update_protocol_ecdsa_unittest.cc
index 506aad2..eab1f35 100644
--- a/components/update_client/client_update_protocol_ecdsa_unittest.cc
+++ b/components/update_client/client_update_protocol_ecdsa_unittest.cc
@@ -16,6 +16,8 @@
#include "crypto/secure_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+namespace update_client {
+
namespace {
std::string GetPublicKeyForTesting() {
@@ -292,3 +294,5 @@ TEST_F(CupEcdsaTest, ValidateResponse_TestSigning) {
"bf022100dd7d41d467be2af98d9116b0c7ba09740d54578c02a02f74da5f089834be3403"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5"));
}
+
+} // namespace update_client
diff --git a/components/update_client/configurator.h b/components/update_client/configurator.h
index 5d6a16a..c8101dd 100644
--- a/components/update_client/configurator.h
+++ b/components/update_client/configurator.h
@@ -98,6 +98,9 @@ class Configurator : public base::RefCountedThreadSafe<Configurator> {
// non on-demand components.
virtual bool UseBackgroundDownloader() const = 0;
+ // True if signing of update checks is enabled.
+ virtual bool UseCupSigning() const = 0;
+
// Gets a task runner to a blocking pool of threads suitable for worker jobs.
virtual scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner()
const = 0;
diff --git a/components/update_client/ping_manager.cc b/components/update_client/ping_manager.cc
index 17bcdd6..1918814 100644
--- a/components/update_client/ping_manager.cc
+++ b/components/update_client/ping_manager.cc
@@ -179,7 +179,7 @@ class PingSender {
bool SendPing(const CrxUpdateItem* item);
private:
- void OnRequestSenderComplete(const net::URLFetcher* source);
+ void OnRequestSenderComplete(int error, const std::string& response);
const scoped_refptr<Configurator> config_;
scoped_ptr<RequestSender> request_sender_;
@@ -195,7 +195,8 @@ PingSender::~PingSender() {
DCHECK(thread_checker_.CalledOnValidThread());
}
-void PingSender::OnRequestSenderComplete(const net::URLFetcher* source) {
+void PingSender::OnRequestSenderComplete(int error,
+ const std::string& response) {
DCHECK(thread_checker_.CalledOnValidThread());
delete this;
}
@@ -211,7 +212,7 @@ bool PingSender::SendPing(const CrxUpdateItem* item) {
request_sender_.reset(new RequestSender(config_));
request_sender_->Send(
- BuildPing(*config_, item), urls,
+ false, BuildPing(*config_, item), urls,
base::Bind(&PingSender::OnRequestSenderComplete, base::Unretained(this)));
return true;
}
diff --git a/components/update_client/request_sender.cc b/components/update_client/request_sender.cc
index 1a1ebc3..b2296a2 100644
--- a/components/update_client/request_sender.cc
+++ b/components/update_client/request_sender.cc
@@ -4,41 +4,68 @@
#include "components/update_client/request_sender.h"
+#include "base/base64.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
+#include "components/update_client/client_update_protocol_ecdsa.h"
#include "components/update_client/configurator.h"
#include "components/update_client/utils.h"
+#include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher.h"
namespace update_client {
+namespace {
+
+// This is an ECDSA prime256v1 named-curve key.
+const int kKeyVersion = 5;
+const char kKeyPubBytesBase64[] =
+ "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEB+Yi+3SdJKCyFJmm+suW3CyXygvVsbDbPnJgoC"
+ "X4GeTtoL8Q/WjPx7CGtXOL1Xjbx0VPPN3DrvqZSL/oXy9hVw==";
+
+} // namespace
+
+// This value is chosen not to conflict with network errors defined by
+// net/base/net_error_list.h. The callers don't have to handle this error in
+// any meaningful way, but this value may be reported in UMA stats, therefore
+// avoiding collisions with known network errors is desirable.
+int RequestSender::kErrorResponseNotTrusted = -10000;
+
RequestSender::RequestSender(const scoped_refptr<Configurator>& config)
- : config_(config) {}
+ : config_(config), use_signing_(false) {}
RequestSender::~RequestSender() {
DCHECK(thread_checker_.CalledOnValidThread());
}
-void RequestSender::Send(const std::string& request_string,
+void RequestSender::Send(bool use_signing,
+ const std::string& request_body,
const std::vector<GURL>& urls,
const RequestSenderCallback& request_sender_callback) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (urls.empty()) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(request_sender_callback, nullptr));
- return;
- }
- request_string_ = request_string;
+ use_signing_ = use_signing;
+ request_body_ = request_body;
urls_ = urls;
request_sender_callback_ = request_sender_callback;
+ if (urls_.empty()) {
+ return HandleSendError(-1);
+ }
+
cur_url_ = urls_.begin();
+ if (use_signing_) {
+ public_key_ = GetKey(kKeyPubBytesBase64);
+ if (public_key_.empty())
+ return HandleSendError(-1);
+ }
+
SendInternal();
}
@@ -47,17 +74,48 @@ void RequestSender::SendInternal() {
DCHECK(cur_url_->is_valid());
DCHECK(thread_checker_.CalledOnValidThread());
- url_fetcher_ = SendProtocolRequest(*cur_url_, request_string_, this,
- config_->RequestContext());
+ GURL url(*cur_url_);
+
+ if (use_signing_) {
+ DCHECK(!public_key_.empty());
+ signer_ = ClientUpdateProtocolEcdsa::Create(kKeyVersion, public_key_);
+ std::string request_query_string;
+ signer_->SignRequest(request_body_, &request_query_string);
+
+ url = BuildUpdateUrl(url, request_query_string);
+ }
+
+ url_fetcher_ =
+ SendProtocolRequest(url, request_body_, this, config_->RequestContext());
+ if (!url_fetcher_.get())
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&RequestSender::SendInternalComplete, base::Unretained(this),
+ -1, std::string(), std::string()));
}
-void RequestSender::OnURLFetchComplete(const net::URLFetcher* source) {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (GetFetchError(*source) == 0) {
- request_sender_callback_.Run(source);
- return;
+void RequestSender::SendInternalComplete(int error,
+ const std::string& response_body,
+ const std::string& response_etag) {
+ if (!error) {
+ if (!use_signing_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(request_sender_callback_, 0, response_body));
+ return;
+ }
+
+ DCHECK(use_signing_);
+ DCHECK(signer_.get());
+ if (signer_->ValidateResponse(response_body, response_etag)) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(request_sender_callback_, 0, response_body));
+ return;
+ }
+
+ error = kErrorResponseNotTrusted;
}
+ DCHECK(error);
if (++cur_url_ != urls_.end() &&
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@@ -65,8 +123,58 @@ void RequestSender::OnURLFetchComplete(const net::URLFetcher* source) {
return;
}
+ HandleSendError(error);
+}
+
+void RequestSender::OnURLFetchComplete(const net::URLFetcher* source) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(source);
+
+ VLOG(1) << "request completed from url: " << source->GetOriginalURL().spec();
+
+ const int fetch_error(GetFetchError(*source));
+ std::string response_body;
+ CHECK(source->GetResponseAsString(&response_body));
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&RequestSender::SendInternalComplete, base::Unretained(this),
+ fetch_error, response_body, GetServerETag(source)));
+}
+
+void RequestSender::HandleSendError(int error) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(request_sender_callback_, source));
+ FROM_HERE, base::Bind(request_sender_callback_, error, std::string()));
+}
+
+std::string RequestSender::GetKey(const char* key_bytes_base64) {
+ std::string result;
+ return base::Base64Decode(std::string(key_bytes_base64), &result)
+ ? result
+ : std::string();
+}
+
+GURL RequestSender::BuildUpdateUrl(const GURL& url,
+ const std::string& query_params) {
+ const std::string query_string(
+ url.has_query() ? base::StringPrintf("%s&%s", url.query().c_str(),
+ query_params.c_str())
+ : query_params);
+ GURL::Replacements replacements;
+ replacements.SetQueryStr(query_string);
+
+ return url.ReplaceComponents(replacements);
+}
+
+std::string RequestSender::GetServerETag(const net::URLFetcher* source) {
+ const auto response_headers(source->GetResponseHeaders());
+ if (!response_headers)
+ return std::string();
+
+ std::string etag;
+ return response_headers->EnumerateHeader(nullptr, "ETag", &etag)
+ ? etag
+ : std::string();
}
} // namespace update_client
diff --git a/components/update_client/request_sender.h b/components/update_client/request_sender.h
index b6ec23b..71b41ee 100644
--- a/components/update_client/request_sender.h
+++ b/components/update_client/request_sender.h
@@ -22,39 +22,69 @@ class URLFetcher;
namespace update_client {
+class ClientUpdateProtocolEcdsa;
class Configurator;
// Sends a request to one of the urls provided. The class implements a chain
// of responsibility design pattern, where the urls are tried in the order they
// are specified, until the request to one of them succeeds or all have failed.
+// CUP signing is optional.
class RequestSender : public net::URLFetcherDelegate {
public:
- // The |source| refers to the fetcher object used to make the request. This
- // parameter can be NULL in some error cases.
- typedef base::Callback<void(const net::URLFetcher* source)>
- RequestSenderCallback;
+ // If |error| is 0, then the response is provided in the |response| parameter.
+ using RequestSenderCallback =
+ base::Callback<void(int error, const std::string& response)>;
+
+ static int kErrorResponseNotTrusted;
explicit RequestSender(const scoped_refptr<Configurator>& config);
~RequestSender() override;
- void Send(const std::string& request_string,
+ // |use_signing| enables CUP signing of protocol messages exchanged using
+ // this class.
+ void Send(bool use_signing,
+ const std::string& request_body,
const std::vector<GURL>& urls,
const RequestSenderCallback& request_sender_callback);
private:
- void SendInternal();
+ // Combines the |url| and |query_params| parameters.
+ static GURL BuildUpdateUrl(const GURL& url, const std::string& query_params);
+
+ // Decodes and returns the public key used by CUP.
+ static std::string GetKey(const char* key_bytes_base64);
+
+ // Returns the Etag of the server response or an empty string if the
+ // Etag is not available.
+ static std::string GetServerETag(const net::URLFetcher* source);
// Overrides for URLFetcherDelegate.
void OnURLFetchComplete(const net::URLFetcher* source) override;
+ // Implements the error handling and url fallback mechanism.
+ void SendInternal();
+
+ // Called when SendInternal complets. |response_body|and |response_etag|
+ // contain the body and the etag associated with the HTTP response.
+ void SendInternalComplete(int error,
+ const std::string& response_body,
+ const std::string& response_etag);
+
+ // Helper function to handle a non-continuable error in Send.
+ void HandleSendError(int error);
+
+ base::ThreadChecker thread_checker_;
+
const scoped_refptr<Configurator> config_;
+ bool use_signing_;
std::vector<GURL> urls_;
- std::vector<GURL>::const_iterator cur_url_;
- scoped_ptr<net::URLFetcher> url_fetcher_;
- std::string request_string_;
+ std::string request_body_;
RequestSenderCallback request_sender_callback_;
- base::ThreadChecker thread_checker_;
+ std::string public_key_;
+ std::vector<GURL>::const_iterator cur_url_;
+ scoped_ptr<net::URLFetcher> url_fetcher_;
+ scoped_ptr<ClientUpdateProtocolEcdsa> signer_;
DISALLOW_COPY_AND_ASSIGN(RequestSender);
};
diff --git a/components/update_client/request_sender_unittest.cc b/components/update_client/request_sender_unittest.cc
index 527eb26..5132fd9 100644
--- a/components/update_client/request_sender_unittest.cc
+++ b/components/update_client/request_sender_unittest.cc
@@ -6,6 +6,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
+#include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h"
#include "components/update_client/request_sender.h"
#include "components/update_client/test_configurator.h"
@@ -22,6 +23,17 @@ const char kUrl2[] = "https://localhost2/path2";
const char kUrlPath1[] = "path1";
const char kUrlPath2[] = "path2";
+// TODO(sorin): refactor as a utility function for unit tests.
+base::FilePath test_file(const char* file) {
+ base::FilePath path;
+ PathService::Get(base::DIR_SOURCE_ROOT, &path);
+ return path.AppendASCII("components")
+ .AppendASCII("test")
+ .AppendASCII("data")
+ .AppendASCII("update_client")
+ .AppendASCII(file);
+}
+
} // namespace
class RequestSenderTest : public testing::Test {
@@ -33,7 +45,7 @@ class RequestSenderTest : public testing::Test {
void SetUp() override;
void TearDown() override;
- void RequestSenderComplete(const net::URLFetcher* source);
+ void RequestSenderComplete(int error, const std::string& response);
protected:
void Quit();
@@ -47,7 +59,8 @@ class RequestSenderTest : public testing::Test {
URLRequestPostInterceptor* post_interceptor_1_; // Owned by the factory.
URLRequestPostInterceptor* post_interceptor_2_; // Owned by the factory.
- const net::URLFetcher* url_fetcher_source_;
+ int error_;
+ std::string response_;
private:
base::MessageLoopForIO loop_;
@@ -57,13 +70,9 @@ class RequestSenderTest : public testing::Test {
};
RequestSenderTest::RequestSenderTest()
- : post_interceptor_1_(nullptr),
- post_interceptor_2_(nullptr),
- url_fetcher_source_(nullptr) {
-}
+ : post_interceptor_1_(nullptr), post_interceptor_2_(nullptr), error_(0) {}
-RequestSenderTest::~RequestSenderTest() {
-}
+RequestSenderTest::~RequestSenderTest() {}
void RequestSenderTest::SetUp() {
config_ = new TestConfigurator(base::ThreadTaskRunnerHandle::Get(),
@@ -114,21 +123,25 @@ void RequestSenderTest::Quit() {
quit_closure_.Run();
}
-void RequestSenderTest::RequestSenderComplete(const net::URLFetcher* source) {
- url_fetcher_source_ = source;
+void RequestSenderTest::RequestSenderComplete(int error,
+ const std::string& response) {
+ error_ = error;
+ response_ = response;
+
Quit();
}
// Tests that when a request to the first url succeeds, the subsequent urls are
// not tried.
TEST_F(RequestSenderTest, RequestSendSuccess) {
- EXPECT_TRUE(post_interceptor_1_->ExpectRequest(new PartialMatch("test")));
+ EXPECT_TRUE(post_interceptor_1_->ExpectRequest(
+ new PartialMatch("test"), test_file("updatecheck_reply_1.xml")));
std::vector<GURL> urls;
urls.push_back(GURL(kUrl1));
urls.push_back(GURL(kUrl2));
request_sender_.reset(new RequestSender(config_));
- request_sender_->Send("test", urls,
+ request_sender_->Send(false, "test", urls,
base::Bind(&RequestSenderTest::RequestSenderComplete,
base::Unretained(this)));
RunThreads();
@@ -138,9 +151,15 @@ TEST_F(RequestSenderTest, RequestSendSuccess) {
EXPECT_EQ(1, post_interceptor_1_->GetCount())
<< post_interceptor_1_->GetRequestsAsString();
+ // Sanity check the request.
EXPECT_STREQ("test", post_interceptor_1_->GetRequests()[0].c_str());
- EXPECT_EQ(GURL(kUrl1), url_fetcher_source_->GetOriginalURL());
- EXPECT_EQ(200, url_fetcher_source_->GetResponseCode());
+
+ // Check the response post conditions.
+ EXPECT_EQ(0, error_);
+ EXPECT_TRUE(base::StartsWith(response_,
+ "<?xml version='1.0' encoding='UTF-8'?>",
+ base::CompareCase::SENSITIVE));
+ EXPECT_EQ(443ul, response_.size());
}
// Tests that the request succeeds using the second url after the first url
@@ -154,7 +173,7 @@ TEST_F(RequestSenderTest, RequestSendSuccessWithFallback) {
urls.push_back(GURL(kUrl1));
urls.push_back(GURL(kUrl2));
request_sender_.reset(new RequestSender(config_));
- request_sender_->Send("test", urls,
+ request_sender_->Send(false, "test", urls,
base::Bind(&RequestSenderTest::RequestSenderComplete,
base::Unretained(this)));
RunThreads();
@@ -170,8 +189,7 @@ TEST_F(RequestSenderTest, RequestSendSuccessWithFallback) {
EXPECT_STREQ("test", post_interceptor_1_->GetRequests()[0].c_str());
EXPECT_STREQ("test", post_interceptor_2_->GetRequests()[0].c_str());
- EXPECT_EQ(GURL(kUrl2), url_fetcher_source_->GetOriginalURL());
- EXPECT_EQ(200, url_fetcher_source_->GetResponseCode());
+ EXPECT_EQ(0, error_);
}
// Tests that the request fails when both urls have failed.
@@ -185,7 +203,7 @@ TEST_F(RequestSenderTest, RequestSendFailed) {
urls.push_back(GURL(kUrl1));
urls.push_back(GURL(kUrl2));
request_sender_.reset(new RequestSender(config_));
- request_sender_->Send("test", urls,
+ request_sender_->Send(false, "test", urls,
base::Bind(&RequestSenderTest::RequestSenderComplete,
base::Unretained(this)));
RunThreads();
@@ -201,20 +219,42 @@ TEST_F(RequestSenderTest, RequestSendFailed) {
EXPECT_STREQ("test", post_interceptor_1_->GetRequests()[0].c_str());
EXPECT_STREQ("test", post_interceptor_2_->GetRequests()[0].c_str());
- EXPECT_EQ(GURL(kUrl2), url_fetcher_source_->GetOriginalURL());
- EXPECT_EQ(403, url_fetcher_source_->GetResponseCode());
+ EXPECT_EQ(403, error_);
}
// Tests that the request fails when no urls are provided.
TEST_F(RequestSenderTest, RequestSendFailedNoUrls) {
std::vector<GURL> urls;
request_sender_.reset(new RequestSender(config_));
- request_sender_->Send("test", urls,
+ request_sender_->Send(false, "test", urls,
+ base::Bind(&RequestSenderTest::RequestSenderComplete,
+ base::Unretained(this)));
+ RunThreads();
+
+ EXPECT_EQ(-1, error_);
+}
+
+// Tests that a CUP request fails if the response is not signed.
+TEST_F(RequestSenderTest, RequestSendCupError) {
+ EXPECT_TRUE(post_interceptor_1_->ExpectRequest(
+ new PartialMatch("test"), test_file("updatecheck_reply_1.xml")));
+
+ std::vector<GURL> urls;
+ urls.push_back(GURL(kUrl1));
+ request_sender_.reset(new RequestSender(config_));
+ request_sender_->Send(true, "test", urls,
base::Bind(&RequestSenderTest::RequestSenderComplete,
base::Unretained(this)));
RunThreads();
- EXPECT_EQ(nullptr, url_fetcher_source_);
+ EXPECT_EQ(1, post_interceptor_1_->GetHitCount())
+ << post_interceptor_1_->GetRequestsAsString();
+ EXPECT_EQ(1, post_interceptor_1_->GetCount())
+ << post_interceptor_1_->GetRequestsAsString();
+
+ EXPECT_STREQ("test", post_interceptor_1_->GetRequests()[0].c_str());
+ EXPECT_EQ(RequestSender::kErrorResponseNotTrusted, error_);
+ EXPECT_TRUE(response_.empty());
}
} // namespace update_client
diff --git a/components/update_client/test_configurator.cc b/components/update_client/test_configurator.cc
index 1e4e76e..f082bb8 100644
--- a/components/update_client/test_configurator.cc
+++ b/components/update_client/test_configurator.cc
@@ -27,8 +27,8 @@ TestConfigurator::TestConfigurator(
: worker_task_runner_(worker_task_runner),
initial_time_(0),
ondemand_time_(0),
- context_(new net::TestURLRequestContextGetter(network_task_runner)) {
-}
+ use_cup_signing_(false),
+ context_(new net::TestURLRequestContextGetter(network_task_runner)) {}
TestConfigurator::~TestConfigurator() {
}
@@ -103,6 +103,10 @@ bool TestConfigurator::UseBackgroundDownloader() const {
return false;
}
+bool TestConfigurator::UseCupSigning() const {
+ return use_cup_signing_;
+}
+
void TestConfigurator::SetOnDemandTime(int seconds) {
ondemand_time_ = seconds;
}
@@ -111,6 +115,10 @@ void TestConfigurator::SetInitialDelay(int seconds) {
initial_time_ = seconds;
}
+void TestConfigurator::SetUseCupSigning(bool use_cup_signing) {
+ use_cup_signing_ = use_cup_signing;
+}
+
void TestConfigurator::SetDownloadPreference(
const std::string& download_preference) {
download_preference_ = download_preference;
diff --git a/components/update_client/test_configurator.h b/components/update_client/test_configurator.h
index 2aa5ff2..e4c72f2a 100644
--- a/components/update_client/test_configurator.h
+++ b/components/update_client/test_configurator.h
@@ -73,12 +73,14 @@ class TestConfigurator : public Configurator {
scoped_refptr<OutOfProcessPatcher> CreateOutOfProcessPatcher() const override;
bool DeltasEnabled() const override;
bool UseBackgroundDownloader() const override;
+ bool UseCupSigning() const override;
scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner()
const override;
void SetOnDemandTime(int seconds);
void SetInitialDelay(int seconds);
void SetDownloadPreference(const std::string& download_preference);
+ void SetUseCupSigning(bool use_cup_signing);
private:
friend class base::RefCountedThreadSafe<TestConfigurator>;
@@ -90,6 +92,7 @@ class TestConfigurator : public Configurator {
int initial_time_;
int ondemand_time_;
std::string download_preference_;
+ bool use_cup_signing_;
scoped_refptr<net::TestURLRequestContextGetter> context_;
diff --git a/components/update_client/update_checker.cc b/components/update_client/update_checker.cc
index 16a4a95..dd851d9 100644
--- a/components/update_client/update_checker.cc
+++ b/components/update_client/update_checker.cc
@@ -22,7 +22,6 @@
#include "components/update_client/crx_update_item.h"
#include "components/update_client/request_sender.h"
#include "components/update_client/utils.h"
-#include "net/url_request/url_fetcher.h"
#include "url/gurl.h"
namespace update_client {
@@ -86,14 +85,13 @@ class UpdateCheckerImpl : public UpdateChecker {
const UpdateCheckCallback& update_check_callback) override;
private:
- void OnRequestSenderComplete(const net::URLFetcher* source);
+ void OnRequestSenderComplete(int error, const std::string& response);
+ base::ThreadChecker thread_checker_;
const scoped_refptr<Configurator> config_;
UpdateCheckCallback update_check_callback_;
scoped_ptr<RequestSender> request_sender_;
- base::ThreadChecker thread_checker_;
-
DISALLOW_COPY_AND_ASSIGN(UpdateCheckerImpl);
};
@@ -119,6 +117,7 @@ bool UpdateCheckerImpl::CheckForUpdates(
request_sender_.reset(new RequestSender(config_));
request_sender_->Send(
+ config_->UseCupSigning(),
BuildUpdateCheckRequest(*config_, items_to_check, additional_attributes),
config_->UpdateUrl(),
base::Bind(&UpdateCheckerImpl::OnRequestSenderComplete,
@@ -126,42 +125,26 @@ bool UpdateCheckerImpl::CheckForUpdates(
return true;
}
-void UpdateCheckerImpl::OnRequestSenderComplete(const net::URLFetcher* source) {
+void UpdateCheckerImpl::OnRequestSenderComplete(int error,
+ const std::string& response) {
DCHECK(thread_checker_.CalledOnValidThread());
- GURL original_url;
- int error = 0;
- std::string error_message;
- UpdateResponse update_response;
-
- if (source) {
- original_url = source->GetOriginalURL();
- VLOG(1) << "Update check request went to: " << original_url.spec();
- if (FetchSuccess(*source)) {
- std::string xml;
- source->GetResponseAsString(&xml);
- if (!update_response.Parse(xml)) {
- error = -1;
- error_message = update_response.errors();
- }
- } else {
- error = GetFetchError(*source);
- error_message.assign("network error");
+ if (!error) {
+ UpdateResponse update_response;
+ if (update_response.Parse(response)) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(update_check_callback_, error, update_response.results()));
+ return;
}
- } else {
- error = -1;
- error_message = "no fetcher";
- }
- if (error) {
- VLOG(1) << "Update request failed: " << error_message;
+ error = -1;
+ VLOG(1) << "Parse failed " << update_response.errors();
}
- request_sender_.reset();
-
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback_, original_url, error,
- error_message, update_response.results()));
+ FROM_HERE,
+ base::Bind(update_check_callback_, error, UpdateResponse::Results()));
}
} // namespace
diff --git a/components/update_client/update_checker.h b/components/update_client/update_checker.h
index 076abe9..1de7f0c 100644
--- a/components/update_client/update_checker.h
+++ b/components/update_client/update_checker.h
@@ -17,10 +17,6 @@
class GURL;
-namespace net {
-class URLRequestContextGetter;
-}
-
namespace update_client {
class Configurator;
@@ -29,10 +25,7 @@ struct CrxUpdateItem;
class UpdateChecker {
public:
using UpdateCheckCallback =
- base::Callback<void(const GURL& original_url,
- int error,
- const std::string& error_message,
- const UpdateResponse::Results& results)>;
+ base::Callback<void(int error, const UpdateResponse::Results& results)>;
using Factory =
scoped_ptr<UpdateChecker> (*)(const scoped_refptr<Configurator>& config);
diff --git a/components/update_client/update_checker_unittest.cc b/components/update_client/update_checker_unittest.cc
index 0a799c8..85457b9 100644
--- a/components/update_client/update_checker_unittest.cc
+++ b/components/update_client/update_checker_unittest.cc
@@ -47,10 +47,7 @@ class UpdateCheckerTest : public testing::Test {
void SetUp() override;
void TearDown() override;
- void UpdateCheckComplete(const GURL& original_url,
- int error,
- const std::string& error_message,
- const UpdateResponse::Results& results);
+ void UpdateCheckComplete(int error, const UpdateResponse::Results& results);
protected:
void Quit();
@@ -66,9 +63,7 @@ class UpdateCheckerTest : public testing::Test {
scoped_ptr<InterceptorFactory> interceptor_factory_;
URLRequestPostInterceptor* post_interceptor_; // Owned by the factory.
- GURL original_url_;
int error_;
- std::string error_message_;
UpdateResponse::Results results_;
private:
@@ -95,7 +90,6 @@ void UpdateCheckerTest::SetUp() {
update_checker_.reset();
error_ = 0;
- error_message_.clear();
results_ = UpdateResponse::Results();
}
@@ -134,13 +128,9 @@ void UpdateCheckerTest::Quit() {
}
void UpdateCheckerTest::UpdateCheckComplete(
- const GURL& original_url,
int error,
- const std::string& error_message,
const UpdateResponse::Results& results) {
- original_url_ = original_url;
error_ = error;
- error_message_ = error_message;
results_ = results;
Quit();
}
@@ -199,10 +189,7 @@ TEST_F(UpdateCheckerTest, UpdateCheckSuccess) {
post_interceptor_->GetRequests()[0].find("<hw physmemory="));
// Sanity check the arguments of the callback after parsing.
- ASSERT_FALSE(config_->UpdateUrl().empty());
- EXPECT_EQ(config_->UpdateUrl().front(), original_url_);
EXPECT_EQ(0, error_);
- EXPECT_TRUE(error_message_.empty());
EXPECT_EQ(1ul, results_.list.size());
EXPECT_STREQ("jebgalgnebhfojomionfpkfelancnnkf",
results_.list[0].extension_id.c_str());
@@ -223,7 +210,6 @@ TEST_F(UpdateCheckerTest, UpdateCheckError) {
update_checker_->CheckForUpdates(
items_to_check, "", base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
-
RunThreads();
EXPECT_EQ(1, post_interceptor_->GetHitCount())
@@ -231,10 +217,7 @@ TEST_F(UpdateCheckerTest, UpdateCheckError) {
EXPECT_EQ(1, post_interceptor_->GetCount())
<< post_interceptor_->GetRequestsAsString();
- ASSERT_FALSE(config_->UpdateUrl().empty());
- EXPECT_EQ(config_->UpdateUrl().front(), original_url_);
EXPECT_EQ(403, error_);
- EXPECT_STREQ("network error", error_message_.c_str());
EXPECT_EQ(0ul, results_.list.size());
}
@@ -262,4 +245,41 @@ TEST_F(UpdateCheckerTest, UpdateCheckDownloadPreference) {
post_interceptor_->GetRequests()[0].find(" dlpref=\"cacheable\""));
}
+// This test is checking that an update check signed with CUP fails, since there
+// is currently no entity that can respond with a valid signed response.
+// A proper CUP test requires network mocks, which are not available now.
+TEST_F(UpdateCheckerTest, UpdateCheckCupError) {
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+
+ config_->SetUseCupSigning(true);
+ update_checker_ = UpdateChecker::Create(config_);
+
+ CrxUpdateItem item(BuildCrxUpdateItem());
+ std::vector<CrxUpdateItem*> items_to_check;
+ items_to_check.push_back(&item);
+
+ update_checker_->CheckForUpdates(
+ items_to_check, "", base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
+ base::Unretained(this)));
+
+ RunThreads();
+
+ EXPECT_EQ(1, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ ASSERT_EQ(1, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+
+ // Sanity check the request.
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+ "<updatecheck /><packages><package fp=\"fp1\"/></packages></app>"));
+
+ // Expect an error since the response is not trusted.
+ EXPECT_EQ(-10000, error_);
+ EXPECT_EQ(0ul, results_.list.size());
+}
+
} // namespace update_client
diff --git a/components/update_client/update_client_unittest.cc b/components/update_client/update_client_unittest.cc
index 8a245ad..a0bee0f 100644
--- a/components/update_client/update_client_unittest.cc
+++ b/components/update_client/update_client_unittest.cc
@@ -226,8 +226,8 @@ TEST_F(UpdateClientTest, OneCrxNoUpdate) {
const std::string& additional_attributes,
const UpdateCheckCallback& update_check_callback) override {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "",
- UpdateResponse::Results()));
+ FROM_HERE,
+ base::Bind(update_check_callback, 0, UpdateResponse::Results()));
return true;
}
};
@@ -368,7 +368,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
results.list.push_back(result);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
+ FROM_HERE, base::Bind(update_check_callback, 0, results));
return true;
}
};
@@ -580,7 +580,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdate) {
results.list.push_back(result2);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
+ FROM_HERE, base::Bind(update_check_callback, 0, results));
return true;
}
};
@@ -827,7 +827,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
results.list.push_back(result2);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
+ FROM_HERE, base::Bind(update_check_callback, 0, results));
return true;
}
};
@@ -1099,7 +1099,7 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
+ FROM_HERE, base::Bind(update_check_callback, 0, results));
return true;
}
};
@@ -1340,7 +1340,7 @@ TEST_F(UpdateClientTest, OneCrxInstallError) {
results.list.push_back(result);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
+ FROM_HERE, base::Bind(update_check_callback, 0, results));
return true;
}
};
@@ -1573,7 +1573,7 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
+ FROM_HERE, base::Bind(update_check_callback, 0, results));
return true;
}
};
@@ -1777,8 +1777,8 @@ TEST_F(UpdateClientTest, OneCrxNoUpdateQueuedCall) {
const std::string& additional_attributes,
const UpdateCheckCallback& update_check_callback) override {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "",
- UpdateResponse::Results()));
+ FROM_HERE,
+ base::Bind(update_check_callback, 0, UpdateResponse::Results()));
return true;
}
};
@@ -1911,7 +1911,7 @@ TEST_F(UpdateClientTest, OneCrxInstall) {
results.list.push_back(result);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
+ FROM_HERE, base::Bind(update_check_callback, 0, results));
return true;
}
};
@@ -2062,8 +2062,8 @@ TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
const std::string& additional_attributes,
const UpdateCheckCallback& update_check_callback) override {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "",
- UpdateResponse::Results()));
+ FROM_HERE,
+ base::Bind(update_check_callback, 0, UpdateResponse::Results()));
return true;
}
};
diff --git a/components/update_client/utils.cc b/components/update_client/utils.cc
index 75b0d00..a6ec277 100644
--- a/components/update_client/utils.cc
+++ b/components/update_client/utils.cc
@@ -133,6 +133,8 @@ scoped_ptr<net::URLFetcher> SendProtocolRequest(
net::URLRequestContextGetter* url_request_context_getter) {
scoped_ptr<net::URLFetcher> url_fetcher = net::URLFetcher::Create(
0, url, net::URLFetcher::POST, url_fetcher_delegate);
+ if (!url_fetcher.get())
+ return url_fetcher;
url_fetcher->SetUploadData("application/xml", protocol_request);
url_fetcher->SetRequestContext(url_request_context_getter);
diff --git a/ios/chrome/browser/component_updater/ios_component_updater_configurator.cc b/ios/chrome/browser/component_updater/ios_component_updater_configurator.cc
index 1c1025c..ea16f56 100644
--- a/ios/chrome/browser/component_updater/ios_component_updater_configurator.cc
+++ b/ios/chrome/browser/component_updater/ios_component_updater_configurator.cc
@@ -5,6 +5,7 @@
#include "ios/chrome/browser/component_updater/ios_component_updater_configurator.h"
#include <string>
+#include <vector>
#include "base/threading/sequenced_worker_pool.h"
#include "base/version.h"
@@ -42,6 +43,7 @@ class IOSConfigurator : public update_client::Configurator {
const override;
bool DeltasEnabled() const override;
bool UseBackgroundDownloader() const override;
+ bool UseCupSigning() const override;
scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner()
const override;
@@ -127,6 +129,10 @@ bool IOSConfigurator::UseBackgroundDownloader() const {
return configurator_impl_.UseBackgroundDownloader();
}
+bool IOSConfigurator::UseCupSigning() const {
+ return configurator_impl_.UseCupSigning();
+}
+
scoped_refptr<base::SequencedTaskRunner>
IOSConfigurator::GetSequencedTaskRunner() const {
return web::WebThread::GetBlockingPool()