// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_CERTIFICATE_CHECKER_H_
#define CHROMEOS_PLATFORM_UPDATE_ENGINE_CERTIFICATE_CHECKER_H_

#include <string>

#include <base/basictypes.h>
#include <curl/curl.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST
#include <openssl/ssl.h>

class MetricsLibraryInterface;
namespace chromeos_update_engine { class PrefsInterface; }

namespace chromeos_update_engine {

// Wrapper for openssl operations with the certificates.
class OpenSSLWrapper {
 public:
  OpenSSLWrapper() {}
  virtual ~OpenSSLWrapper() {}

  // 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,
                                    unsigned char* out_digest) const;

 private:
  DISALLOW_COPY_AND_ASSIGN(OpenSSLWrapper);
};

// 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:
  // 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.
  enum ServerToCheck {
    kUpdate = 0,
    kDownload = 1,
    kNone = 2  // This needs to be the last element. Changing its value is ok.
  };

  CertificateChecker() {}
  virtual ~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. |ptr| is expected to be a
  // pointer to a ServerToCheck.
  static CURLcode ProcessSSLContext(CURL* curl_handle, SSL_CTX* ssl_ctx,
                                    void* ptr);

  // Flushes to UMA any certificate-related report that was persisted.
  static void FlushReport();

  // Setters.
  static void set_metrics_lib(MetricsLibraryInterface* metrics_lib) {
    metrics_lib_ = metrics_lib;
  }

  static void set_prefs(PrefsInterface* prefs) {
    prefs_ = prefs;
  }

  static void set_openssl_wrapper(OpenSSLWrapper* openssl_wrapper) {
    openssl_wrapper_ = openssl_wrapper;
  }

 private:
  FRIEND_TEST(CertificateCheckerTest, NewCertificate);
  FRIEND_TEST(CertificateCheckerTest, SameCertificate);
  FRIEND_TEST(CertificateCheckerTest, ChangedCertificate);
  FRIEND_TEST(CertificateCheckerTest, FailedCertificate);
  FRIEND_TEST(CertificateCheckerTest, FlushReport);
  FRIEND_TEST(CertificateCheckerTest, FlushNothingToReport);

  // These callbacks are 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 VerifySSLCallbackUpdateCheck(int preverify_ok,
                                          X509_STORE_CTX* x509_ctx);
  static int VerifySSLCallbackDownload(int preverify_ok,
                                       X509_STORE_CTX* x509_ctx);

  // Checks if server certificate for |server_to_check|, stored in |x509_ctx|,
  // has changed since last connection to that same server. This is called by
  // one of the two callbacks defined above. If certificate fails to check or
  // changes, a report is generated and persisted, to be later sent by
  // FlushReport. Returns true on success and false otherwise.
  static bool CheckCertificateChange(ServerToCheck server_to_check,
                                     int preverify_ok,
                                     X509_STORE_CTX* x509_ctx);

  // Metrics library used to report to UMA.
  static MetricsLibraryInterface* metrics_lib_;

  // Prefs used to store certificates and UMA reports.
  static PrefsInterface* prefs_;

  // The wrapper for openssl operations.
  static OpenSSLWrapper* openssl_wrapper_;

  DISALLOW_COPY_AND_ASSIGN(CertificateChecker);
};

}  // namespace chromeos_update_engine

#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_CERTIFICATE_CHECKER_H_
