Remove libcurl support from update_engine_sideload.

While sideloading an update from recovery we don't need nor want to
download payload from HTTP(S) URLs, only local file:// are supported.
This patch moves libcurl_http_fetcher and certificate_checker files out
of libpayload_consumer dropping the libcurl and libssl dependencies from
it and the update_engine_sideload.

Bug: 27178350
TEST=build UE for Brillo and Android. Unittests still pass and
update_engine_sideload doesn't link to libcurl.

Change-Id: Iffefdb094654f7277dc825c041fe55aac9ee8756
diff --git a/common/certificate_checker.cc b/common/certificate_checker.cc
deleted file mode 100644
index 86df950..0000000
--- a/common/certificate_checker.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-//
-// Copyright (C) 2012 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/common/certificate_checker.h"
-
-#include <string>
-
-#include <base/logging.h>
-#include <base/strings/string_number_conversions.h>
-#include <base/strings/string_util.h>
-#include <base/strings/stringprintf.h>
-#include <curl/curl.h>
-#include <openssl/evp.h>
-#include <openssl/ssl.h>
-
-#include "update_engine/common/constants.h"
-#include "update_engine/common/prefs_interface.h"
-#include "update_engine/common/utils.h"
-
-using std::string;
-
-namespace chromeos_update_engine {
-
-bool OpenSSLWrapper::GetCertificateDigest(X509_STORE_CTX* x509_ctx,
-                                          int* out_depth,
-                                          unsigned int* out_digest_length,
-                                          uint8_t* out_digest) const {
-  TEST_AND_RETURN_FALSE(out_digest);
-  X509* certificate = X509_STORE_CTX_get_current_cert(x509_ctx);
-  TEST_AND_RETURN_FALSE(certificate);
-  int depth = X509_STORE_CTX_get_error_depth(x509_ctx);
-  if (out_depth)
-    *out_depth = depth;
-
-  unsigned int len;
-  const EVP_MD* digest_function = EVP_sha256();
-  bool success = X509_digest(certificate, digest_function, out_digest, &len);
-
-  if (success && out_digest_length)
-    *out_digest_length = len;
-  return success;
-}
-
-// static
-CertificateChecker* CertificateChecker::cert_checker_singleton_ = nullptr;
-
-CertificateChecker::CertificateChecker(PrefsInterface* prefs,
-                                       OpenSSLWrapper* openssl_wrapper)
-    : prefs_(prefs), openssl_wrapper_(openssl_wrapper) {
-}
-
-CertificateChecker::~CertificateChecker() {
-  if (cert_checker_singleton_ == this)
-    cert_checker_singleton_ = nullptr;
-}
-
-void CertificateChecker::Init() {
-  CHECK(cert_checker_singleton_ == nullptr);
-  cert_checker_singleton_ = this;
-}
-
-// static
-CURLcode CertificateChecker::ProcessSSLContext(CURL* curl_handle,
-                                               SSL_CTX* ssl_ctx,
-                                               void* ptr) {
-  ServerToCheck* server_to_check = reinterpret_cast<ServerToCheck*>(ptr);
-
-  if (!cert_checker_singleton_) {
-    DLOG(WARNING) << "No CertificateChecker singleton initialized.";
-    return CURLE_FAILED_INIT;
-  }
-
-  // From here we set the SSL_CTX to another callback, from the openssl library,
-  // which will be called after each server certificate is validated. However,
-  // since openssl does not allow us to pass our own data pointer to the
-  // callback, the certificate check will have to be done statically. Since we
-  // need to know which update server we are using in order to check the
-  // certificate, we hardcode Chrome OS's two known update servers here, and
-  // define a different static callback for each. Since this code should only
-  // run in official builds, this should not be a problem. However, if an update
-  // server different from the ones listed here is used, the check will not
-  // take place.
-  int (*verify_callback)(int, X509_STORE_CTX*);
-  switch (*server_to_check) {
-    case ServerToCheck::kDownload:
-      verify_callback = &CertificateChecker::VerifySSLCallbackDownload;
-      break;
-    case ServerToCheck::kUpdate:
-      verify_callback = &CertificateChecker::VerifySSLCallbackUpdate;
-      break;
-    case ServerToCheck::kNone:
-      verify_callback = nullptr;
-      break;
-  }
-
-  SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, verify_callback);
-  return CURLE_OK;
-}
-
-// static
-int CertificateChecker::VerifySSLCallbackDownload(int preverify_ok,
-                                                  X509_STORE_CTX* x509_ctx) {
-  return VerifySSLCallback(preverify_ok, x509_ctx, ServerToCheck::kDownload);
-}
-
-// static
-int CertificateChecker::VerifySSLCallbackUpdate(int preverify_ok,
-                                                X509_STORE_CTX* x509_ctx) {
-  return VerifySSLCallback(preverify_ok, x509_ctx, ServerToCheck::kUpdate);
-}
-
-// static
-int CertificateChecker::VerifySSLCallback(int preverify_ok,
-                                          X509_STORE_CTX* x509_ctx,
-                                          ServerToCheck server_to_check) {
-  CHECK(cert_checker_singleton_ != nullptr);
-  return cert_checker_singleton_->CheckCertificateChange(
-      preverify_ok, x509_ctx, server_to_check) ? 1 : 0;
-}
-
-bool CertificateChecker::CheckCertificateChange(int preverify_ok,
-                                                X509_STORE_CTX* x509_ctx,
-                                                ServerToCheck server_to_check) {
-  TEST_AND_RETURN_FALSE(prefs_ != nullptr);
-
-  // If pre-verification failed, we are not interested in the current
-  // certificate. We store a report to UMA and just propagate the fail result.
-  if (!preverify_ok) {
-    NotifyCertificateChecked(server_to_check, CertificateCheckResult::kFailed);
-    return false;
-  }
-
-  int depth;
-  unsigned int digest_length;
-  uint8_t digest[EVP_MAX_MD_SIZE];
-
-  if (!openssl_wrapper_->GetCertificateDigest(x509_ctx,
-                                              &depth,
-                                              &digest_length,
-                                              digest)) {
-    LOG(WARNING) << "Failed to generate digest of X509 certificate "
-                 << "from update server.";
-    NotifyCertificateChecked(server_to_check, CertificateCheckResult::kValid);
-    return true;
-  }
-
-  // We convert the raw bytes of the digest to an hex string, for storage in
-  // prefs.
-  string digest_string = base::HexEncode(digest, digest_length);
-
-  string storage_key =
-      base::StringPrintf("%s-%d-%d", kPrefsUpdateServerCertificate,
-                         static_cast<int>(server_to_check), depth);
-  string stored_digest;
-  // If there's no stored certificate, we just store the current one and return.
-  if (!prefs_->GetString(storage_key, &stored_digest)) {
-    if (!prefs_->SetString(storage_key, digest_string)) {
-      LOG(WARNING) << "Failed to store server certificate on storage key "
-                   << storage_key;
-    }
-    NotifyCertificateChecked(server_to_check, CertificateCheckResult::kValid);
-    return true;
-  }
-
-  // Certificate changed, we store a report to UMA and store the most recent
-  // certificate.
-  if (stored_digest != digest_string) {
-    if (!prefs_->SetString(storage_key, digest_string)) {
-      LOG(WARNING) << "Failed to store server certificate on storage key "
-                   << storage_key;
-    }
-    LOG(INFO) << "Certificate changed from " << stored_digest << " to "
-              << digest_string << ".";
-    NotifyCertificateChecked(server_to_check,
-                             CertificateCheckResult::kValidChanged);
-    return true;
-  }
-
-  NotifyCertificateChecked(server_to_check, CertificateCheckResult::kValid);
-  // Since we don't perform actual SSL verification, we return success.
-  return true;
-}
-
-void CertificateChecker::NotifyCertificateChecked(
-    ServerToCheck server_to_check,
-    CertificateCheckResult result) {
-  if (observer_)
-    observer_->CertificateChecked(server_to_check, result);
-}
-
-}  // namespace chromeos_update_engine
diff --git a/common/certificate_checker.h b/common/certificate_checker.h
deleted file mode 100644
index c785192..0000000
--- a/common/certificate_checker.h
+++ /dev/null
@@ -1,175 +0,0 @@
-//
-// Copyright (C) 2011 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_COMMON_CERTIFICATE_CHECKER_H_
-#define UPDATE_ENGINE_COMMON_CERTIFICATE_CHECKER_H_
-
-#include <curl/curl.h>
-#include <openssl/ssl.h>
-
-#include <string>
-
-#include <base/macros.h>
-#include <gtest/gtest_prod.h>  // for FRIEND_TEST
-
-namespace chromeos_update_engine {
-
-class PrefsInterface;
-
-// Wrapper for openssl operations with the certificates.
-class OpenSSLWrapper {
- public:
-  OpenSSLWrapper() = default;
-  virtual ~OpenSSLWrapper() = default;
-
-  // Takes an openssl X509_STORE_CTX, extracts the corresponding certificate
-  // from it and calculates its fingerprint (SHA256 digest). Returns true on
-  // success and false otherwise.
-  //
-  // |x509_ctx| is the pointer to the openssl object that holds the certificate.
-  // |out_depth| is the depth of the current certificate, in the certificate
-  // chain.
-  // |out_digest_length| is the length of the generated digest.
-  // |out_digest| is the byte array where the digest itself will be written.
-  // It should be big enough to hold a SHA1 digest (e.g. EVP_MAX_MD_SIZE).
-  virtual bool GetCertificateDigest(X509_STORE_CTX* x509_ctx,
-                                    int* out_depth,
-                                    unsigned int* out_digest_length,
-                                    uint8_t* out_digest) const;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(OpenSSLWrapper);
-};
-
-// The values in this enum are replicated in the metrics server. See metrics.h
-// for instructions on how to update these values in the server side.
-enum class CertificateCheckResult {
-  // The certificate is valid and the same as seen before or the first time we
-  // see a certificate.
-  kValid,
-  // The certificate is valid, but is different than a previously seen
-  // certificate for the selected server.
-  kValidChanged,
-  // The certificate validation failed.
-  kFailed,
-
-  // This value must be the last entry.
-  kNumConstants
-};
-
-// These values are used to generate the keys of files persisted via prefs.
-// This means that changing these will cause loss of information on metrics
-// reporting, during the transition. These values are also mapped to a metric
-// name in metrics.cc, so adding values here requires to assign a new metric
-// name in that file.
-enum class ServerToCheck {
-  kUpdate = 0,
-  kDownload,
-
-  // Ignore this server.
-  kNone,
-};
-
-// Responsible for checking whether update server certificates change, and
-// reporting to UMA when this happens. Since all state information is persisted,
-// and openssl forces us to use a static callback with no data pointer, this
-// class is entirely static.
-class CertificateChecker {
- public:
-  class Observer {
-   public:
-    virtual ~Observer() = default;
-
-    // Called whenever a certificate is checked for the server |server_to_check|
-    // passing the result of said certificate check.
-    virtual void CertificateChecked(ServerToCheck server_to_check,
-                                    CertificateCheckResult result) = 0;
-  };
-
-  CertificateChecker(PrefsInterface* prefs, OpenSSLWrapper* openssl_wrapper);
-  ~CertificateChecker();
-
-  // This callback is called by libcurl just before the initialization of an
-  // SSL connection after having processed all other SSL related options. Used
-  // to check if server certificates change. |cert_checker| is expected to be a
-  // pointer to the CertificateChecker instance.
-  static CURLcode ProcessSSLContext(CURL* curl_handle,
-                                    SSL_CTX* ssl_ctx,
-                                    void* cert_checker);
-
-  // Initialize this class as the singleton instance. Only one instance can be
-  // initialized at a time and it should be initialized before other methods
-  // can be used.
-  void Init();
-
-  // Set the certificate observer to the passed instance. To remove the
-  // observer, pass a nullptr. The |observer| instance must be valid while this
-  // CertificateChecker verifies certificates.
-  void SetObserver(Observer* observer) { observer_ = observer; }
-
- private:
-  FRIEND_TEST(CertificateCheckerTest, NewCertificate);
-  FRIEND_TEST(CertificateCheckerTest, SameCertificate);
-  FRIEND_TEST(CertificateCheckerTest, ChangedCertificate);
-  FRIEND_TEST(CertificateCheckerTest, FailedCertificate);
-
-  // These callbacks are asynchronously called by openssl after initial SSL
-  // verification. They are used to perform any additional security verification
-  // on the connection, but we use them here to get hold of the server
-  // certificate, in order to determine if it has changed since the last
-  // connection. Since openssl forces us to do this statically, we define two
-  // different callbacks for the two different official update servers, and only
-  // assign the correspondent one. The assigned callback is then called once per
-  // each certificate on the server and returns 1 for success and 0 for failure.
-  static int VerifySSLCallbackDownload(int preverify_ok,
-                                       X509_STORE_CTX* x509_ctx);
-  static int VerifySSLCallbackUpdate(int preverify_ok,
-                                     X509_STORE_CTX* x509_ctx);
-  static int VerifySSLCallback(int preverify_ok,
-                               X509_STORE_CTX* x509_ctx,
-                               ServerToCheck server_to_check);
-
-  // Checks if server certificate stored in |x509_ctx| has changed since last
-  // connection to that same server, specified by |server_to_check|.
-  // This is called by the callbacks defined above. The result of the
-  // certificate check is passed to the observer, if any. Returns true on
-  // success and false otherwise.
-  bool CheckCertificateChange(int preverify_ok,
-                              X509_STORE_CTX* x509_ctx,
-                              ServerToCheck server_to_check);
-
-  // Notifies the observer, if any, of a certificate checking.
-  void NotifyCertificateChecked(ServerToCheck server_to_check,
-                                CertificateCheckResult result);
-
-  // The CertificateChecker singleton instance.
-  static CertificateChecker* cert_checker_singleton_;
-
-  // Prefs instance used to store the certificates seen in the past.
-  PrefsInterface* prefs_;
-
-  // The wrapper for openssl operations.
-  OpenSSLWrapper* openssl_wrapper_;
-
-  // The observer called whenever a certificate is checked, if not null.
-  Observer* observer_{nullptr};
-
-  DISALLOW_COPY_AND_ASSIGN(CertificateChecker);
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_COMMON_CERTIFICATE_CHECKER_H_
diff --git a/common/certificate_checker_unittest.cc b/common/certificate_checker_unittest.cc
deleted file mode 100644
index c30acc5..0000000
--- a/common/certificate_checker_unittest.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-//
-// Copyright (C) 2012 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/common/certificate_checker.h"
-
-#include <string>
-
-#include <base/strings/string_util.h>
-#include <base/strings/stringprintf.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "update_engine/common/constants.h"
-#include "update_engine/common/mock_certificate_checker.h"
-#include "update_engine/common/mock_prefs.h"
-
-using ::testing::DoAll;
-using ::testing::Return;
-using ::testing::SetArgumentPointee;
-using ::testing::SetArrayArgument;
-using ::testing::_;
-using std::string;
-
-namespace chromeos_update_engine {
-
-class MockCertificateCheckObserver : public CertificateChecker::Observer {
- public:
-  MOCK_METHOD2(CertificateChecked,
-               void(ServerToCheck server_to_check,
-                    CertificateCheckResult result));
-};
-
-class CertificateCheckerTest : public testing::Test {
- protected:
-  void SetUp() override {
-    cert_key_ = base::StringPrintf("%s-%d-%d",
-                                   cert_key_prefix_.c_str(),
-                                   static_cast<int>(server_to_check_),
-                                   depth_);
-    cert_checker.Init();
-    cert_checker.SetObserver(&observer_);
-  }
-
-  void TearDown() override {
-    cert_checker.SetObserver(nullptr);
-  }
-
-  MockPrefs prefs_;
-  MockOpenSSLWrapper openssl_wrapper_;
-  // Parameters of our mock certificate digest.
-  int depth_{0};
-  unsigned int length_{4};
-  uint8_t digest_[4]{0x17, 0x7D, 0x07, 0x5F};
-  string digest_hex_{"177D075F"};
-  string diff_digest_hex_{"1234ABCD"};
-  string cert_key_prefix_{kPrefsUpdateServerCertificate};
-  ServerToCheck server_to_check_{ServerToCheck::kUpdate};
-  string cert_key_;
-
-  testing::StrictMock<MockCertificateCheckObserver> observer_;
-  CertificateChecker cert_checker{&prefs_, &openssl_wrapper_};
-};
-
-// check certificate change, new
-TEST_F(CertificateCheckerTest, NewCertificate) {
-  EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(nullptr, _, _, _))
-      .WillOnce(DoAll(
-          SetArgumentPointee<1>(depth_),
-          SetArgumentPointee<2>(length_),
-          SetArrayArgument<3>(digest_, digest_ + 4),
-          Return(true)));
-  EXPECT_CALL(prefs_, GetString(cert_key_, _)).WillOnce(Return(false));
-  EXPECT_CALL(prefs_, SetString(cert_key_, digest_hex_)).WillOnce(Return(true));
-  EXPECT_CALL(observer_,
-              CertificateChecked(server_to_check_,
-                                 CertificateCheckResult::kValid));
-  ASSERT_TRUE(
-      cert_checker.CheckCertificateChange(1, nullptr, server_to_check_));
-}
-
-// check certificate change, unchanged
-TEST_F(CertificateCheckerTest, SameCertificate) {
-  EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(nullptr, _, _, _))
-      .WillOnce(DoAll(
-          SetArgumentPointee<1>(depth_),
-          SetArgumentPointee<2>(length_),
-          SetArrayArgument<3>(digest_, digest_ + 4),
-          Return(true)));
-  EXPECT_CALL(prefs_, GetString(cert_key_, _))
-      .WillOnce(DoAll(SetArgumentPointee<1>(digest_hex_), Return(true)));
-  EXPECT_CALL(prefs_, SetString(_, _)).Times(0);
-  EXPECT_CALL(observer_,
-              CertificateChecked(server_to_check_,
-                                 CertificateCheckResult::kValid));
-  ASSERT_TRUE(
-      cert_checker.CheckCertificateChange(1, nullptr, server_to_check_));
-}
-
-// check certificate change, changed
-TEST_F(CertificateCheckerTest, ChangedCertificate) {
-  EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(nullptr, _, _, _))
-      .WillOnce(DoAll(
-          SetArgumentPointee<1>(depth_),
-          SetArgumentPointee<2>(length_),
-          SetArrayArgument<3>(digest_, digest_ + 4),
-          Return(true)));
-  EXPECT_CALL(prefs_, GetString(cert_key_, _))
-      .WillOnce(DoAll(SetArgumentPointee<1>(diff_digest_hex_), Return(true)));
-  EXPECT_CALL(observer_,
-              CertificateChecked(server_to_check_,
-                                 CertificateCheckResult::kValidChanged));
-  EXPECT_CALL(prefs_, SetString(cert_key_, digest_hex_)).WillOnce(Return(true));
-  ASSERT_TRUE(
-      cert_checker.CheckCertificateChange(1, nullptr, server_to_check_));
-}
-
-// check certificate change, failed
-TEST_F(CertificateCheckerTest, FailedCertificate) {
-  EXPECT_CALL(observer_, CertificateChecked(server_to_check_,
-                                            CertificateCheckResult::kFailed));
-  EXPECT_CALL(prefs_, GetString(_, _)).Times(0);
-  EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(_, _, _, _)).Times(0);
-  ASSERT_FALSE(
-      cert_checker.CheckCertificateChange(0, nullptr, server_to_check_));
-}
-
-}  // namespace chromeos_update_engine
diff --git a/common/file_fetcher.cc b/common/file_fetcher.cc
index 77dadd1..d0a109b 100644
--- a/common/file_fetcher.cc
+++ b/common/file_fetcher.cc
@@ -27,7 +27,6 @@
 #include <base/strings/stringprintf.h>
 #include <brillo/streams/file_stream.h>
 
-#include "update_engine/common/certificate_checker.h"
 #include "update_engine/common/hardware_interface.h"
 #include "update_engine/common/platform_constants.h"
 
diff --git a/common/hash_calculator_unittest.cc b/common/hash_calculator_unittest.cc
index 27dbc56..436e6a7 100644
--- a/common/hash_calculator_unittest.cc
+++ b/common/hash_calculator_unittest.cc
@@ -25,7 +25,6 @@
 #include <brillo/secure_blob.h>
 #include <gtest/gtest.h>
 
-#include "update_engine/common/libcurl_http_fetcher.h"
 #include "update_engine/common/utils.h"
 
 using std::string;
diff --git a/common/http_fetcher_unittest.cc b/common/http_fetcher_unittest.cc
index 6f3e480..0f34475 100644
--- a/common/http_fetcher_unittest.cc
+++ b/common/http_fetcher_unittest.cc
@@ -44,11 +44,11 @@
 #include "update_engine/common/fake_hardware.h"
 #include "update_engine/common/file_fetcher.h"
 #include "update_engine/common/http_common.h"
-#include "update_engine/common/libcurl_http_fetcher.h"
 #include "update_engine/common/mock_http_fetcher.h"
 #include "update_engine/common/multi_range_http_fetcher.h"
 #include "update_engine/common/test_utils.h"
 #include "update_engine/common/utils.h"
+#include "update_engine/libcurl_http_fetcher.h"
 #include "update_engine/mock_proxy_resolver.h"
 #include "update_engine/proxy_resolver.h"
 
diff --git a/common/libcurl_http_fetcher.cc b/common/libcurl_http_fetcher.cc
deleted file mode 100644
index a222139..0000000
--- a/common/libcurl_http_fetcher.cc
+++ /dev/null
@@ -1,697 +0,0 @@
-//
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/common/libcurl_http_fetcher.h"
-
-#include <algorithm>
-#include <string>
-
-#include <base/bind.h>
-#include <base/format_macros.h>
-#include <base/location.h>
-#include <base/logging.h>
-#include <base/strings/string_util.h>
-#include <base/strings/stringprintf.h>
-
-#include "update_engine/common/certificate_checker.h"
-#include "update_engine/common/hardware_interface.h"
-#include "update_engine/common/platform_constants.h"
-
-using base::TimeDelta;
-using brillo::MessageLoop;
-using std::max;
-using std::string;
-
-// This is a concrete implementation of HttpFetcher that uses libcurl to do the
-// http work.
-
-namespace chromeos_update_engine {
-
-namespace {
-const int kNoNetworkRetrySeconds = 10;
-}  // namespace
-
-LibcurlHttpFetcher::LibcurlHttpFetcher(ProxyResolver* proxy_resolver,
-                                       HardwareInterface* hardware)
-    : HttpFetcher(proxy_resolver), hardware_(hardware) {
-  // Dev users want a longer timeout (180 seconds) because they may
-  // be waiting on the dev server to build an image.
-  if (!hardware_->IsOfficialBuild())
-    low_speed_time_seconds_ = kDownloadDevModeLowSpeedTimeSeconds;
-  if (hardware_->IsOOBEEnabled() && !hardware_->IsOOBEComplete(nullptr))
-    max_retry_count_ = kDownloadMaxRetryCountOobeNotComplete;
-}
-
-LibcurlHttpFetcher::~LibcurlHttpFetcher() {
-  LOG_IF(ERROR, transfer_in_progress_)
-      << "Destroying the fetcher while a transfer is in progress.";
-  CleanUp();
-}
-
-bool LibcurlHttpFetcher::GetProxyType(const string& proxy,
-                                      curl_proxytype* out_type) {
-  if (base::StartsWith(
-          proxy, "socks5://", base::CompareCase::INSENSITIVE_ASCII) ||
-      base::StartsWith(
-          proxy, "socks://", base::CompareCase::INSENSITIVE_ASCII)) {
-    *out_type = CURLPROXY_SOCKS5_HOSTNAME;
-    return true;
-  }
-  if (base::StartsWith(
-          proxy, "socks4://", base::CompareCase::INSENSITIVE_ASCII)) {
-    *out_type = CURLPROXY_SOCKS4A;
-    return true;
-  }
-  if (base::StartsWith(
-          proxy, "http://", base::CompareCase::INSENSITIVE_ASCII) ||
-      base::StartsWith(
-          proxy, "https://", base::CompareCase::INSENSITIVE_ASCII)) {
-    *out_type = CURLPROXY_HTTP;
-    return true;
-  }
-  if (base::StartsWith(proxy, kNoProxy, base::CompareCase::INSENSITIVE_ASCII)) {
-    // known failure case. don't log.
-    return false;
-  }
-  LOG(INFO) << "Unknown proxy type: " << proxy;
-  return false;
-}
-
-void LibcurlHttpFetcher::ResumeTransfer(const string& url) {
-  LOG(INFO) << "Starting/Resuming transfer";
-  CHECK(!transfer_in_progress_);
-  url_ = url;
-  curl_multi_handle_ = curl_multi_init();
-  CHECK(curl_multi_handle_);
-
-  curl_handle_ = curl_easy_init();
-  CHECK(curl_handle_);
-  ignore_failure_ = false;
-
-  CHECK(HasProxy());
-  bool is_direct = (GetCurrentProxy() == kNoProxy);
-  LOG(INFO) << "Using proxy: " << (is_direct ? "no" : "yes");
-  if (is_direct) {
-    CHECK_EQ(curl_easy_setopt(curl_handle_,
-                              CURLOPT_PROXY,
-                              ""), CURLE_OK);
-  } else {
-    CHECK_EQ(curl_easy_setopt(curl_handle_,
-                              CURLOPT_PROXY,
-                              GetCurrentProxy().c_str()), CURLE_OK);
-    // Curl seems to require us to set the protocol
-    curl_proxytype type;
-    if (GetProxyType(GetCurrentProxy(), &type)) {
-      CHECK_EQ(curl_easy_setopt(curl_handle_,
-                                CURLOPT_PROXYTYPE,
-                                type), CURLE_OK);
-    }
-  }
-
-  if (post_data_set_) {
-    CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POST, 1), CURLE_OK);
-    CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDS,
-                              post_data_.data()),
-             CURLE_OK);
-    CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDSIZE,
-                              post_data_.size()),
-             CURLE_OK);
-  }
-
-  // Setup extra HTTP headers.
-  if (curl_http_headers_) {
-    curl_slist_free_all(curl_http_headers_);
-    curl_http_headers_ = nullptr;
-  }
-  for (const auto& header : extra_headers_) {
-    // curl_slist_append() copies the string.
-    curl_http_headers_ =
-        curl_slist_append(curl_http_headers_, header.second.c_str());
-  }
-  if (post_data_set_) {
-    // Set the Content-Type HTTP header, if one was specifically set.
-    if (post_content_type_ != kHttpContentTypeUnspecified) {
-      const string content_type_attr = base::StringPrintf(
-          "Content-Type: %s", GetHttpContentTypeString(post_content_type_));
-      curl_http_headers_ =
-          curl_slist_append(curl_http_headers_, content_type_attr.c_str());
-    } else {
-      LOG(WARNING) << "no content type set, using libcurl default";
-    }
-  }
-  CHECK_EQ(
-      curl_easy_setopt(curl_handle_, CURLOPT_HTTPHEADER, curl_http_headers_),
-      CURLE_OK);
-
-  if (bytes_downloaded_ > 0 || download_length_) {
-    // Resume from where we left off.
-    resume_offset_ = bytes_downloaded_;
-    CHECK_GE(resume_offset_, 0);
-
-    // Compute end offset, if one is specified. As per HTTP specification, this
-    // is an inclusive boundary. Make sure it doesn't overflow.
-    size_t end_offset = 0;
-    if (download_length_) {
-      end_offset = static_cast<size_t>(resume_offset_) + download_length_ - 1;
-      CHECK_LE((size_t) resume_offset_, end_offset);
-    }
-
-    // Create a string representation of the desired range.
-    string range_str = base::StringPrintf(
-        "%" PRIu64 "-", static_cast<uint64_t>(resume_offset_));
-    if (end_offset)
-      range_str += std::to_string(end_offset);
-    CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_RANGE, range_str.c_str()),
-             CURLE_OK);
-  }
-
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_WRITEDATA, this), CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_WRITEFUNCTION,
-                            StaticLibcurlWrite), CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_URL, url_.c_str()),
-           CURLE_OK);
-
-  // If the connection drops under |low_speed_limit_bps_| (10
-  // bytes/sec by default) for |low_speed_time_seconds_| (90 seconds,
-  // 180 on non-official builds), reconnect.
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_LOW_SPEED_LIMIT,
-                            low_speed_limit_bps_),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_LOW_SPEED_TIME,
-                            low_speed_time_seconds_),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_CONNECTTIMEOUT,
-                            connect_timeout_seconds_),
-           CURLE_OK);
-
-  // By default, libcurl doesn't follow redirections. Allow up to
-  // |kDownloadMaxRedirects| redirections.
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_FOLLOWLOCATION, 1), CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_MAXREDIRS,
-                            kDownloadMaxRedirects),
-           CURLE_OK);
-
-  // Lock down the appropriate curl options for HTTP or HTTPS depending on
-  // the url.
-  if (hardware_->IsOfficialBuild()) {
-    if (base::StartsWith(
-            url_, "http://", base::CompareCase::INSENSITIVE_ASCII)) {
-      SetCurlOptionsForHttp();
-    } else if (base::StartsWith(
-                   url_, "https://", base::CompareCase::INSENSITIVE_ASCII)) {
-      SetCurlOptionsForHttps();
-#if !defined(__CHROMEOS__) && !defined(__BRILLO__)
-    } else if (base::StartsWith(
-                   url_, "file://", base::CompareCase::INSENSITIVE_ASCII)) {
-      SetCurlOptionsForFile();
-#endif
-    } else {
-      LOG(ERROR) << "Received invalid URI: " << url_;
-      // Lock down to no protocol supported for the transfer.
-      CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_PROTOCOLS, 0), CURLE_OK);
-    }
-  } else {
-    LOG(INFO) << "Not setting http(s) curl options because we are "
-              << "running a dev/test image";
-  }
-
-  CHECK_EQ(curl_multi_add_handle(curl_multi_handle_, curl_handle_), CURLM_OK);
-  transfer_in_progress_ = true;
-}
-
-// Lock down only the protocol in case of HTTP.
-void LibcurlHttpFetcher::SetCurlOptionsForHttp() {
-  LOG(INFO) << "Setting up curl options for HTTP";
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_PROTOCOLS, CURLPROTO_HTTP),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_REDIR_PROTOCOLS,
-                            CURLPROTO_HTTP),
-           CURLE_OK);
-}
-
-// Security lock-down in official builds: makes sure that peer certificate
-// verification is enabled, restricts the set of trusted certificates,
-// restricts protocols to HTTPS, restricts ciphers to HIGH.
-void LibcurlHttpFetcher::SetCurlOptionsForHttps() {
-  LOG(INFO) << "Setting up curl options for HTTPS";
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_SSL_VERIFYPEER, 1),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_SSL_VERIFYHOST, 2),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_CAPATH,
-                            constants::kCACertificatesPath),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_REDIR_PROTOCOLS,
-                            CURLPROTO_HTTPS),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_SSL_CIPHER_LIST, "HIGH:!ADH"),
-           CURLE_OK);
-  if (server_to_check_ != ServerToCheck::kNone) {
-    CHECK_EQ(
-        curl_easy_setopt(curl_handle_, CURLOPT_SSL_CTX_DATA, &server_to_check_),
-        CURLE_OK);
-    CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_SSL_CTX_FUNCTION,
-                              CertificateChecker::ProcessSSLContext),
-             CURLE_OK);
-  }
-}
-
-// Lock down only the protocol in case of a local file.
-void LibcurlHttpFetcher::SetCurlOptionsForFile() {
-  LOG(INFO) << "Setting up curl options for FILE";
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_PROTOCOLS, CURLPROTO_FILE),
-           CURLE_OK);
-  CHECK_EQ(
-      curl_easy_setopt(curl_handle_, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_FILE),
-      CURLE_OK);
-}
-
-// Begins the transfer, which must not have already been started.
-void LibcurlHttpFetcher::BeginTransfer(const string& url) {
-  CHECK(!transfer_in_progress_);
-  url_ = url;
-  auto closure = base::Bind(&LibcurlHttpFetcher::ProxiesResolved,
-                            base::Unretained(this));
-  if (!ResolveProxiesForUrl(url_, closure)) {
-    LOG(ERROR) << "Couldn't resolve proxies";
-    if (delegate_)
-      delegate_->TransferComplete(this, false);
-  }
-}
-
-void LibcurlHttpFetcher::ProxiesResolved() {
-  transfer_size_ = -1;
-  resume_offset_ = 0;
-  retry_count_ = 0;
-  no_network_retry_count_ = 0;
-  http_response_code_ = 0;
-  terminate_requested_ = false;
-  sent_byte_ = false;
-
-  // If we are paused, we delay these two operations until Unpause is called.
-  if (transfer_paused_) {
-    restart_transfer_on_unpause_ = true;
-    return;
-  }
-  ResumeTransfer(url_);
-  CurlPerformOnce();
-}
-
-void LibcurlHttpFetcher::ForceTransferTermination() {
-  CleanUp();
-  if (delegate_) {
-    // Note that after the callback returns this object may be destroyed.
-    delegate_->TransferTerminated(this);
-  }
-}
-
-void LibcurlHttpFetcher::TerminateTransfer() {
-  if (in_write_callback_) {
-    terminate_requested_ = true;
-  } else {
-    ForceTransferTermination();
-  }
-}
-
-void LibcurlHttpFetcher::SetHeader(const string& header_name,
-                                   const string& header_value) {
-  string header_line = header_name + ": " + header_value;
-  // Avoid the space if no data on the right side of the semicolon.
-  if (header_value.empty())
-    header_line = header_name + ":";
-  TEST_AND_RETURN(header_line.find('\n') == string::npos);
-  TEST_AND_RETURN(header_name.find(':') == string::npos);
-  extra_headers_[base::ToLowerASCII(header_name)] = header_line;
-}
-
-void LibcurlHttpFetcher::CurlPerformOnce() {
-  CHECK(transfer_in_progress_);
-  int running_handles = 0;
-  CURLMcode retcode = CURLM_CALL_MULTI_PERFORM;
-
-  // libcurl may request that we immediately call curl_multi_perform after it
-  // returns, so we do. libcurl promises that curl_multi_perform will not block.
-  while (CURLM_CALL_MULTI_PERFORM == retcode) {
-    retcode = curl_multi_perform(curl_multi_handle_, &running_handles);
-    if (terminate_requested_) {
-      ForceTransferTermination();
-      return;
-    }
-  }
-
-  // If the transfer completes while paused, we should ignore the failure once
-  // the fetcher is unpaused.
-  if (running_handles == 0 && transfer_paused_ && !ignore_failure_) {
-    LOG(INFO) << "Connection closed while paused, ignoring failure.";
-    ignore_failure_ = true;
-  }
-
-  if (running_handles != 0 || transfer_paused_) {
-    // There's either more work to do or we are paused, so we just keep the
-    // file descriptors to watch up to date and exit, until we are done with the
-    // work and we are not paused.
-    SetupMessageLoopSources();
-    return;
-  }
-
-  // At this point, the transfer was completed in some way (error, connection
-  // closed or download finished).
-
-  GetHttpResponseCode();
-  if (http_response_code_) {
-    LOG(INFO) << "HTTP response code: " << http_response_code_;
-    no_network_retry_count_ = 0;
-  } else {
-    LOG(ERROR) << "Unable to get http response code.";
-  }
-
-  // we're done!
-  CleanUp();
-
-  // TODO(petkov): This temporary code tries to deal with the case where the
-  // update engine performs an update check while the network is not ready
-  // (e.g., right after resume). Longer term, we should check if the network
-  // is online/offline and return an appropriate error code.
-  if (!sent_byte_ &&
-      http_response_code_ == 0 &&
-      no_network_retry_count_ < no_network_max_retries_) {
-    no_network_retry_count_++;
-    MessageLoop::current()->PostDelayedTask(
-        FROM_HERE,
-        base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
-                   base::Unretained(this)),
-        TimeDelta::FromSeconds(kNoNetworkRetrySeconds));
-    LOG(INFO) << "No HTTP response, retry " << no_network_retry_count_;
-  } else if ((!sent_byte_ && !IsHttpResponseSuccess()) ||
-             IsHttpResponseError()) {
-    // The transfer completed w/ error and we didn't get any bytes.
-    // If we have another proxy to try, try that.
-    //
-    // TODO(garnold) in fact there are two separate cases here: one case is an
-    // other-than-success return code (including no return code) and no
-    // received bytes, which is necessary due to the way callbacks are
-    // currently processing error conditions;  the second is an explicit HTTP
-    // error code, where some data may have been received (as in the case of a
-    // semi-successful multi-chunk fetch).  This is a confusing behavior and
-    // should be unified into a complete, coherent interface.
-    LOG(INFO) << "Transfer resulted in an error (" << http_response_code_
-              << "), " << bytes_downloaded_ << " bytes downloaded";
-
-    PopProxy();  // Delete the proxy we just gave up on.
-
-    if (HasProxy()) {
-      // We have another proxy. Retry immediately.
-      LOG(INFO) << "Retrying with next proxy setting";
-      MessageLoop::current()->PostTask(
-          FROM_HERE,
-          base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
-                     base::Unretained(this)));
-    } else {
-      // Out of proxies. Give up.
-      LOG(INFO) << "No further proxies, indicating transfer complete";
-      if (delegate_)
-        delegate_->TransferComplete(this, false);  // signal fail
-      return;
-    }
-  } else if ((transfer_size_ >= 0) && (bytes_downloaded_ < transfer_size_)) {
-    if (!ignore_failure_)
-      retry_count_++;
-    LOG(INFO) << "Transfer interrupted after downloading "
-              << bytes_downloaded_ << " of " << transfer_size_ << " bytes. "
-              << transfer_size_ - bytes_downloaded_ << " bytes remaining "
-              << "after " << retry_count_ << " attempt(s)";
-
-    if (retry_count_ > max_retry_count_) {
-      LOG(INFO) << "Reached max attempts (" << retry_count_ << ")";
-      if (delegate_)
-        delegate_->TransferComplete(this, false);  // signal fail
-      return;
-    }
-    // Need to restart transfer
-    LOG(INFO) << "Restarting transfer to download the remaining bytes";
-    MessageLoop::current()->PostDelayedTask(
-        FROM_HERE,
-        base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
-                   base::Unretained(this)),
-        TimeDelta::FromSeconds(retry_seconds_));
-  } else {
-    LOG(INFO) << "Transfer completed (" << http_response_code_
-              << "), " << bytes_downloaded_ << " bytes downloaded";
-    if (delegate_) {
-      bool success = IsHttpResponseSuccess();
-      delegate_->TransferComplete(this, success);
-    }
-    return;
-  }
-  // If we reach this point is because TransferComplete() was not called in any
-  // of the previous branches. The delegate is allowed to destroy the object
-  // once TransferComplete is called so this would be illegal.
-  ignore_failure_ = false;
-}
-
-size_t LibcurlHttpFetcher::LibcurlWrite(void *ptr, size_t size, size_t nmemb) {
-  // Update HTTP response first.
-  GetHttpResponseCode();
-  const size_t payload_size = size * nmemb;
-
-  // Do nothing if no payload or HTTP response is an error.
-  if (payload_size == 0 || !IsHttpResponseSuccess()) {
-    LOG(INFO) << "HTTP response unsuccessful (" << http_response_code_
-              << ") or no payload (" << payload_size << "), nothing to do";
-    return 0;
-  }
-
-  sent_byte_ = true;
-  {
-    double transfer_size_double;
-    CHECK_EQ(curl_easy_getinfo(curl_handle_,
-                               CURLINFO_CONTENT_LENGTH_DOWNLOAD,
-                               &transfer_size_double), CURLE_OK);
-    off_t new_transfer_size = static_cast<off_t>(transfer_size_double);
-    if (new_transfer_size > 0) {
-      transfer_size_ = resume_offset_ + new_transfer_size;
-    }
-  }
-  bytes_downloaded_ += payload_size;
-  in_write_callback_ = true;
-  if (delegate_)
-    delegate_->ReceivedBytes(this, ptr, payload_size);
-  in_write_callback_ = false;
-  return payload_size;
-}
-
-void LibcurlHttpFetcher::Pause() {
-  if (transfer_paused_) {
-    LOG(ERROR) << "Fetcher already paused.";
-    return;
-  }
-  transfer_paused_ = true;
-  if (!transfer_in_progress_) {
-    // If pause before we started a connection, we don't need to notify curl
-    // about that, we will simply not start the connection later.
-    return;
-  }
-  CHECK(curl_handle_);
-  CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_ALL), CURLE_OK);
-}
-
-void LibcurlHttpFetcher::Unpause() {
-  if (!transfer_paused_) {
-    LOG(ERROR) << "Resume attempted when fetcher not paused.";
-    return;
-  }
-  transfer_paused_ = false;
-  if (restart_transfer_on_unpause_) {
-    restart_transfer_on_unpause_ = false;
-    ResumeTransfer(url_);
-    CurlPerformOnce();
-    return;
-  }
-  if (!transfer_in_progress_) {
-    // If resumed before starting the connection, there's no need to notify
-    // anybody. We will simply start the connection once it is time.
-    return;
-  }
-  CHECK(curl_handle_);
-  CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_CONT), CURLE_OK);
-  // Since the transfer is in progress, we need to dispatch a CurlPerformOnce()
-  // now to let the connection continue, otherwise it would be called by the
-  // TimeoutCallback but with a delay.
-  CurlPerformOnce();
-}
-
-// This method sets up callbacks with the MessageLoop.
-void LibcurlHttpFetcher::SetupMessageLoopSources() {
-  fd_set fd_read;
-  fd_set fd_write;
-  fd_set fd_exc;
-
-  FD_ZERO(&fd_read);
-  FD_ZERO(&fd_write);
-  FD_ZERO(&fd_exc);
-
-  int fd_max = 0;
-
-  // Ask libcurl for the set of file descriptors we should track on its
-  // behalf.
-  CHECK_EQ(curl_multi_fdset(curl_multi_handle_, &fd_read, &fd_write,
-                            &fd_exc, &fd_max), CURLM_OK);
-
-  // We should iterate through all file descriptors up to libcurl's fd_max or
-  // the highest one we're tracking, whichever is larger.
-  for (size_t t = 0; t < arraysize(fd_task_maps_); ++t) {
-    if (!fd_task_maps_[t].empty())
-      fd_max = max(fd_max, fd_task_maps_[t].rbegin()->first);
-  }
-
-  // For each fd, if we're not tracking it, track it. If we are tracking it, but
-  // libcurl doesn't care about it anymore, stop tracking it. After this loop,
-  // there should be exactly as many tasks scheduled in fd_task_maps_[0|1] as
-  // there are read/write fds that we're tracking.
-  for (int fd = 0; fd <= fd_max; ++fd) {
-    // Note that fd_exc is unused in the current version of libcurl so is_exc
-    // should always be false.
-    bool is_exc = FD_ISSET(fd, &fd_exc) != 0;
-    bool must_track[2] = {
-      is_exc || (FD_ISSET(fd, &fd_read) != 0),  // track 0 -- read
-      is_exc || (FD_ISSET(fd, &fd_write) != 0)  // track 1 -- write
-    };
-    MessageLoop::WatchMode watch_modes[2] = {
-      MessageLoop::WatchMode::kWatchRead,
-      MessageLoop::WatchMode::kWatchWrite,
-    };
-
-    for (size_t t = 0; t < arraysize(fd_task_maps_); ++t) {
-      auto fd_task_it = fd_task_maps_[t].find(fd);
-      bool tracked = fd_task_it != fd_task_maps_[t].end();
-
-      if (!must_track[t]) {
-        // If we have an outstanding io_channel, remove it.
-        if (tracked) {
-          MessageLoop::current()->CancelTask(fd_task_it->second);
-          fd_task_maps_[t].erase(fd_task_it);
-        }
-        continue;
-      }
-
-      // If we are already tracking this fd, continue -- nothing to do.
-      if (tracked)
-        continue;
-
-      // Track a new fd.
-      fd_task_maps_[t][fd] = MessageLoop::current()->WatchFileDescriptor(
-          FROM_HERE,
-          fd,
-          watch_modes[t],
-          true,  // persistent
-          base::Bind(&LibcurlHttpFetcher::CurlPerformOnce,
-                     base::Unretained(this)));
-
-      static int io_counter = 0;
-      io_counter++;
-      if (io_counter % 50 == 0) {
-        LOG(INFO) << "io_counter = " << io_counter;
-      }
-    }
-  }
-
-  // Set up a timeout callback for libcurl.
-  if (timeout_id_ == MessageLoop::kTaskIdNull) {
-    VLOG(1) << "Setting up timeout source: " << idle_seconds_ << " seconds.";
-    timeout_id_ = MessageLoop::current()->PostDelayedTask(
-        FROM_HERE,
-        base::Bind(&LibcurlHttpFetcher::TimeoutCallback,
-                   base::Unretained(this)),
-        TimeDelta::FromSeconds(idle_seconds_));
-  }
-}
-
-void LibcurlHttpFetcher::RetryTimeoutCallback() {
-  if (transfer_paused_) {
-    restart_transfer_on_unpause_ = true;
-    return;
-  }
-  ResumeTransfer(url_);
-  CurlPerformOnce();
-}
-
-void LibcurlHttpFetcher::TimeoutCallback() {
-  // We always re-schedule the callback, even if we don't want to be called
-  // anymore. We will remove the event source separately if we don't want to
-  // be called back.
-  timeout_id_ = MessageLoop::current()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&LibcurlHttpFetcher::TimeoutCallback, base::Unretained(this)),
-      TimeDelta::FromSeconds(idle_seconds_));
-
-  // CurlPerformOnce() may call CleanUp(), so we need to schedule our callback
-  // first, since it could be canceled by this call.
-  if (transfer_in_progress_)
-    CurlPerformOnce();
-}
-
-void LibcurlHttpFetcher::CleanUp() {
-  MessageLoop::current()->CancelTask(timeout_id_);
-  timeout_id_ = MessageLoop::kTaskIdNull;
-
-  for (size_t t = 0; t < arraysize(fd_task_maps_); ++t) {
-    for (const auto& fd_taks_pair : fd_task_maps_[t]) {
-      if (!MessageLoop::current()->CancelTask(fd_taks_pair.second)) {
-        LOG(WARNING) << "Error canceling the watch task "
-                     << fd_taks_pair.second << " for "
-                     << (t ? "writing" : "reading") << " the fd "
-                     << fd_taks_pair.first;
-      }
-    }
-    fd_task_maps_[t].clear();
-  }
-
-  if (curl_http_headers_) {
-    curl_slist_free_all(curl_http_headers_);
-    curl_http_headers_ = nullptr;
-  }
-  if (curl_handle_) {
-    if (curl_multi_handle_) {
-      CHECK_EQ(curl_multi_remove_handle(curl_multi_handle_, curl_handle_),
-               CURLM_OK);
-    }
-    curl_easy_cleanup(curl_handle_);
-    curl_handle_ = nullptr;
-  }
-  if (curl_multi_handle_) {
-    CHECK_EQ(curl_multi_cleanup(curl_multi_handle_), CURLM_OK);
-    curl_multi_handle_ = nullptr;
-  }
-  transfer_in_progress_ = false;
-  transfer_paused_ = false;
-  restart_transfer_on_unpause_ = false;
-}
-
-void LibcurlHttpFetcher::GetHttpResponseCode() {
-  long http_response_code = 0;  // NOLINT(runtime/int) - curl needs long.
-  if (base::StartsWith(url_, "file://", base::CompareCase::INSENSITIVE_ASCII)) {
-    // Fake out a valid response code for file:// URLs.
-    http_response_code_ = 299;
-  } else if (curl_easy_getinfo(curl_handle_,
-                               CURLINFO_RESPONSE_CODE,
-                               &http_response_code) == CURLE_OK) {
-    http_response_code_ = static_cast<int>(http_response_code);
-  }
-}
-
-}  // namespace chromeos_update_engine
diff --git a/common/libcurl_http_fetcher.h b/common/libcurl_http_fetcher.h
deleted file mode 100644
index 7101aaa..0000000
--- a/common/libcurl_http_fetcher.h
+++ /dev/null
@@ -1,268 +0,0 @@
-//
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_COMMON_LIBCURL_HTTP_FETCHER_H_
-#define UPDATE_ENGINE_COMMON_LIBCURL_HTTP_FETCHER_H_
-
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <curl/curl.h>
-
-#include <base/logging.h>
-#include <base/macros.h>
-#include <brillo/message_loops/message_loop.h>
-
-#include "update_engine/common/certificate_checker.h"
-#include "update_engine/common/hardware_interface.h"
-#include "update_engine/common/http_fetcher.h"
-
-// This is a concrete implementation of HttpFetcher that uses libcurl to do the
-// http work.
-
-namespace chromeos_update_engine {
-
-class LibcurlHttpFetcher : public HttpFetcher {
- public:
-  LibcurlHttpFetcher(ProxyResolver* proxy_resolver,
-                     HardwareInterface* hardware);
-
-  // Cleans up all internal state. Does not notify delegate
-  ~LibcurlHttpFetcher() override;
-
-  void SetOffset(off_t offset) override { bytes_downloaded_ = offset; }
-
-  void SetLength(size_t length) override { download_length_ = length; }
-  void UnsetLength() override { SetLength(0); }
-
-  // Begins the transfer if it hasn't already begun.
-  void BeginTransfer(const std::string& url) override;
-
-  // If the transfer is in progress, aborts the transfer early. The transfer
-  // cannot be resumed.
-  void TerminateTransfer() override;
-
-  // Pass the headers to libcurl.
-  void SetHeader(const std::string& header_name,
-                 const std::string& header_value) override;
-
-  // Suspend the transfer by calling curl_easy_pause(CURLPAUSE_ALL).
-  void Pause() override;
-
-  // Resume the transfer by calling curl_easy_pause(CURLPAUSE_CONT).
-  void Unpause() override;
-
-  // Libcurl sometimes asks to be called back after some time while
-  // leaving that time unspecified. In that case, we pick a reasonable
-  // default of one second, but it can be overridden here. This is
-  // primarily useful for testing.
-  // From http://curl.haxx.se/libcurl/c/curl_multi_timeout.html:
-  //     if libcurl returns a -1 timeout here, it just means that libcurl
-  //     currently has no stored timeout value. You must not wait too long
-  //     (more than a few seconds perhaps) before you call
-  //     curl_multi_perform() again.
-  void set_idle_seconds(int seconds) override { idle_seconds_ = seconds; }
-
-  // Sets the retry timeout. Useful for testing.
-  void set_retry_seconds(int seconds) override { retry_seconds_ = seconds; }
-
-  void set_no_network_max_retries(int retries) {
-    no_network_max_retries_ = retries;
-  }
-
-  void set_server_to_check(ServerToCheck server_to_check) {
-    server_to_check_ = server_to_check;
-  }
-
-  size_t GetBytesDownloaded() override {
-    return static_cast<size_t>(bytes_downloaded_);
-  }
-
-  void set_low_speed_limit(int low_speed_bps, int low_speed_sec) override {
-    low_speed_limit_bps_ = low_speed_bps;
-    low_speed_time_seconds_ = low_speed_sec;
-  }
-
-  void set_connect_timeout(int connect_timeout_seconds) override {
-    connect_timeout_seconds_ = connect_timeout_seconds;
-  }
-
-  void set_max_retry_count(int max_retry_count) override {
-    max_retry_count_ = max_retry_count;
-  }
-
- private:
-  // Callback for when proxy resolution has completed. This begins the
-  // transfer.
-  void ProxiesResolved();
-
-  // Asks libcurl for the http response code and stores it in the object.
-  void GetHttpResponseCode();
-
-  // Checks whether stored HTTP response is within the success range.
-  inline bool IsHttpResponseSuccess() {
-    return (http_response_code_ >= 200 && http_response_code_ < 300);
-  }
-
-  // Checks whether stored HTTP response is within the error range. This
-  // includes both errors with the request (4xx) and server errors (5xx).
-  inline bool IsHttpResponseError() {
-    return (http_response_code_ >= 400 && http_response_code_ < 600);
-  }
-
-  // Resumes a transfer where it left off. This will use the
-  // HTTP Range: header to make a new connection from where the last
-  // left off.
-  virtual void ResumeTransfer(const std::string& url);
-
-  void TimeoutCallback();
-  void RetryTimeoutCallback();
-
-  // Calls into curl_multi_perform to let libcurl do its work. Returns after
-  // curl_multi_perform is finished, which may actually be after more than
-  // one call to curl_multi_perform. This method will set up the message
-  // loop with sources for future work that libcurl will do, if any, or complete
-  // the transfer and finish the action if no work left to do.
-  // This method will not block.
-  void CurlPerformOnce();
-
-  // Sets up message loop sources as needed by libcurl. This is generally
-  // the file descriptor of the socket and a timer in case nothing happens
-  // on the fds.
-  void SetupMessageLoopSources();
-
-  // Callback called by libcurl when new data has arrived on the transfer
-  size_t LibcurlWrite(void *ptr, size_t size, size_t nmemb);
-  static size_t StaticLibcurlWrite(void *ptr, size_t size,
-                                   size_t nmemb, void *stream) {
-    return reinterpret_cast<LibcurlHttpFetcher*>(stream)->
-        LibcurlWrite(ptr, size, nmemb);
-  }
-
-  // Cleans up the following if they are non-null:
-  // curl(m) handles, fd_task_maps_, timeout_id_.
-  void CleanUp();
-
-  // Force terminate the transfer. This will invoke the delegate's (if any)
-  // TransferTerminated callback so, after returning, this fetcher instance may
-  // be destroyed.
-  void ForceTransferTermination();
-
-  // Sets the curl options for HTTP URL.
-  void SetCurlOptionsForHttp();
-
-  // Sets the curl options for HTTPS URL.
-  void SetCurlOptionsForHttps();
-
-  // Sets the curl options for file URI.
-  void SetCurlOptionsForFile();
-
-  // Convert a proxy URL into a curl proxy type, if applicable. Returns true iff
-  // conversion was successful, false otherwise (in which case nothing is
-  // written to |out_type|).
-  bool GetProxyType(const std::string& proxy, curl_proxytype* out_type);
-
-  // Hardware interface used to query dev-mode and official build settings.
-  HardwareInterface* hardware_;
-
-  // Handles for the libcurl library
-  CURLM* curl_multi_handle_{nullptr};
-  CURL* curl_handle_{nullptr};
-  struct curl_slist* curl_http_headers_{nullptr};
-
-  // The extra headers that will be sent on each request.
-  std::map<std::string, std::string> extra_headers_;
-
-  // Lists of all read(0)/write(1) file descriptors that we're waiting on from
-  // the message loop. libcurl may open/close descriptors and switch their
-  // directions so maintain two separate lists so that watch conditions can be
-  // set appropriately.
-  std::map<int, brillo::MessageLoop::TaskId> fd_task_maps_[2];
-
-  // The TaskId of the timer we're waiting on. kTaskIdNull if we are not waiting
-  // on it.
-  brillo::MessageLoop::TaskId timeout_id_{brillo::MessageLoop::kTaskIdNull};
-
-  bool transfer_in_progress_{false};
-  bool transfer_paused_{false};
-
-  // Whether it should ignore transfer failures for the purpose of retrying the
-  // connection.
-  bool ignore_failure_{false};
-
-  // Whether we should restart the transfer once Unpause() is called. This can
-  // be caused because either the connection dropped while pause or the proxy
-  // was resolved and we never started the transfer in the first place.
-  bool restart_transfer_on_unpause_{false};
-
-  // The transfer size. -1 if not known.
-  off_t transfer_size_{0};
-
-  // How many bytes have been downloaded and sent to the delegate.
-  off_t bytes_downloaded_{0};
-
-  // The remaining maximum number of bytes to download. Zero represents an
-  // unspecified length.
-  size_t download_length_{0};
-
-  // If we resumed an earlier transfer, data offset that we used for the
-  // new connection.  0 otherwise.
-  // In this class, resume refers to resuming a dropped HTTP connection,
-  // not to resuming an interrupted download.
-  off_t resume_offset_{0};
-
-  // Number of resumes performed so far and the max allowed.
-  int retry_count_{0};
-  int max_retry_count_{kDownloadMaxRetryCount};
-
-  // Seconds to wait before retrying a resume.
-  int retry_seconds_{20};
-
-  // Number of resumes due to no network (e.g., HTTP response code 0).
-  int no_network_retry_count_{0};
-  int no_network_max_retries_{0};
-
-  // Seconds to wait before asking libcurl to "perform".
-  int idle_seconds_{1};
-
-  // If true, we are currently performing a write callback on the delegate.
-  bool in_write_callback_{false};
-
-  // If true, we have returned at least one byte in the write callback
-  // to the delegate.
-  bool sent_byte_{false};
-
-  // We can't clean everything up while we're in a write callback, so
-  // if we get a terminate request, queue it until we can handle it.
-  bool terminate_requested_{false};
-
-  // The ServerToCheck used when checking this connection's certificate. If no
-  // certificate check needs to be performed, this should be set to
-  // ServerToCheck::kNone.
-  ServerToCheck server_to_check_{ServerToCheck::kNone};
-
-  int low_speed_limit_bps_{kDownloadLowSpeedLimitBps};
-  int low_speed_time_seconds_{kDownloadLowSpeedTimeSeconds};
-  int connect_timeout_seconds_{kDownloadConnectTimeoutSeconds};
-
-  DISALLOW_COPY_AND_ASSIGN(LibcurlHttpFetcher);
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_COMMON_LIBCURL_HTTP_FETCHER_H_
diff --git a/common/mock_certificate_checker.h b/common/mock_certificate_checker.h
deleted file mode 100644
index 1f55ca1..0000000
--- a/common/mock_certificate_checker.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// Copyright (C) 2011 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_COMMON_MOCK_CERTIFICATE_CHECKER_H_
-#define UPDATE_ENGINE_COMMON_MOCK_CERTIFICATE_CHECKER_H_
-
-#include <gmock/gmock.h>
-#include <openssl/ssl.h>
-
-#include "update_engine/common/certificate_checker.h"
-
-namespace chromeos_update_engine {
-
-class MockOpenSSLWrapper : public OpenSSLWrapper {
- public:
-  MOCK_CONST_METHOD4(GetCertificateDigest,
-                     bool(X509_STORE_CTX* x509_ctx,
-                          int* out_depth,
-                          unsigned int* out_digest_length,
-                          uint8_t* out_digest));
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_COMMON_MOCK_CERTIFICATE_CHECKER_H_