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

#include "platform_verification_flow.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "chrome/browser/chromeos/attestation/attestation_ca_client.h"
#include "chrome/browser/chromeos/attestation/attestation_signed_data.pb.h"
#include "chrome/browser/chromeos/attestation/platform_verification_dialog.h"
#include "chrome/browser/chromeos/login/user.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "chromeos/attestation/attestation_flow.h"
#include "chromeos/cryptohome/async_method_caller.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"

namespace {

// A callback method to handle DBus errors.
void DBusCallback(const base::Callback<void(bool)>& on_success,
                  const base::Closure& on_failure,
                  chromeos::DBusMethodCallStatus call_status,
                  bool result) {
  if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS) {
    on_success.Run(result);
  } else {
    LOG(ERROR) << "PlatformVerificationFlow: DBus call failed!";
    on_failure.Run();
  }
}

// A helper to call a ChallengeCallback with an error result.
void ReportError(
    const chromeos::attestation::PlatformVerificationFlow::ChallengeCallback&
        callback,
    chromeos::attestation::PlatformVerificationFlow::Result error) {
  callback.Run(error, std::string(), std::string(), std::string());
}
}  // namespace

namespace chromeos {
namespace attestation {

// A default implementation of the Delegate interface.
class DefaultDelegate : public PlatformVerificationFlow::Delegate {
 public:
  DefaultDelegate() {}
  virtual ~DefaultDelegate() {}

  virtual void ShowConsentPrompt(
      PlatformVerificationFlow::ConsentType type,
      content::WebContents* web_contents,
      const PlatformVerificationFlow::Delegate::ConsentCallback& callback)
      OVERRIDE {
    PlatformVerificationDialog::ShowDialog(web_contents, callback);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(DefaultDelegate);
};

PlatformVerificationFlow::PlatformVerificationFlow()
    : attestation_flow_(NULL),
      async_caller_(cryptohome::AsyncMethodCaller::GetInstance()),
      cryptohome_client_(DBusThreadManager::Get()->GetCryptohomeClient()),
      user_manager_(UserManager::Get()),
      delegate_(NULL),
      testing_prefs_(NULL),
      weak_factory_(this) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  scoped_ptr<ServerProxy> attestation_ca_client(new AttestationCAClient());
  default_attestation_flow_.reset(new AttestationFlow(
      async_caller_,
      cryptohome_client_,
      attestation_ca_client.Pass()));
  attestation_flow_ = default_attestation_flow_.get();
  default_delegate_.reset(new DefaultDelegate());
  delegate_ = default_delegate_.get();
}

PlatformVerificationFlow::PlatformVerificationFlow(
    AttestationFlow* attestation_flow,
    cryptohome::AsyncMethodCaller* async_caller,
    CryptohomeClient* cryptohome_client,
    UserManager* user_manager,
    Delegate* delegate)
    : attestation_flow_(attestation_flow),
      async_caller_(async_caller),
      cryptohome_client_(cryptohome_client),
      user_manager_(user_manager),
      delegate_(delegate),
      testing_prefs_(NULL),
      weak_factory_(this) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
}

PlatformVerificationFlow::~PlatformVerificationFlow() {
}

void PlatformVerificationFlow::ChallengePlatformKey(
    content::WebContents* web_contents,
    const std::string& service_id,
    const std::string& challenge,
    const ChallengeCallback& callback) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  if (!IsAttestationEnabled(web_contents)) {
    LOG(INFO) << "PlatformVerificationFlow: Feature disabled.";
    ReportError(callback, POLICY_REJECTED);
    return;
  }
  BoolDBusMethodCallback dbus_callback = base::Bind(
      &DBusCallback,
      base::Bind(&PlatformVerificationFlow::CheckConsent,
                 weak_factory_.GetWeakPtr(),
                 web_contents,
                 service_id,
                 challenge,
                 callback),
      base::Bind(&ReportError, callback, INTERNAL_ERROR));
  cryptohome_client_->TpmAttestationIsEnrolled(dbus_callback);
}

void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents,
                                            const std::string& service_id,
                                            const std::string& challenge,
                                            const ChallengeCallback& callback,
                                            bool attestation_enrolled) {
  ConsentType consent_type = CONSENT_TYPE_NONE;
  if (!attestation_enrolled || IsFirstUse(web_contents)) {
    consent_type = CONSENT_TYPE_ATTESTATION;
  } else if (IsAlwaysAskRequired(web_contents)) {
    consent_type = CONSENT_TYPE_ALWAYS;
  }
  Delegate::ConsentCallback consent_callback = base::Bind(
      &PlatformVerificationFlow::OnConsentResponse,
      weak_factory_.GetWeakPtr(),
      web_contents,
      service_id,
      challenge,
      callback,
      consent_type);
  if (consent_type == CONSENT_TYPE_NONE) {
    consent_callback.Run(CONSENT_RESPONSE_NONE);
  } else {
    delegate_->ShowConsentPrompt(consent_type,
                                 web_contents,
                                 consent_callback);
  }
}

void PlatformVerificationFlow::RegisterProfilePrefs(
    user_prefs::PrefRegistrySyncable* prefs) {
  prefs->RegisterBooleanPref(prefs::kRAConsentFirstTime,
                             false,
                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
  prefs->RegisterDictionaryPref(
      prefs::kRAConsentDomains,
      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
  prefs->RegisterBooleanPref(prefs::kRAConsentAlways,
                             false,
                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
}

void PlatformVerificationFlow::OnConsentResponse(
    content::WebContents* web_contents,
    const std::string& service_id,
    const std::string& challenge,
    const ChallengeCallback& callback,
    ConsentType consent_type,
    ConsentResponse consent_response) {
  if (consent_type != CONSENT_TYPE_NONE) {
    if (consent_response == CONSENT_RESPONSE_NONE) {
      // No user response - do not proceed and do not modify any settings.
      LOG(WARNING) << "PlatformVerificationFlow: No response from user.";
      ReportError(callback, USER_REJECTED);
      return;
    }
    if (!UpdateSettings(web_contents, consent_type, consent_response)) {
      ReportError(callback, INTERNAL_ERROR);
      return;
    }
    if (consent_response == CONSENT_RESPONSE_DENY) {
      LOG(INFO) << "PlatformVerificationFlow: User rejected request.";
      content::RecordAction(
          content::UserMetricsAction("PlatformVerificationRejected"));
      ReportError(callback, USER_REJECTED);
      return;
    } else if (consent_response == CONSENT_RESPONSE_ALLOW) {
      content::RecordAction(
          content::UserMetricsAction("PlatformVerificationAccepted"));
    }
  }

  // At this point all user interaction is complete and we can proceed with the
  // certificate request.
  chromeos::User* user = GetUser(web_contents);
  if (!user) {
    ReportError(callback, INTERNAL_ERROR);
    LOG(ERROR) << "Profile does not map to a valid user.";
    return;
  }
  AttestationFlow::CertificateCallback certificate_callback = base::Bind(
      &PlatformVerificationFlow::OnCertificateReady,
      weak_factory_.GetWeakPtr(),
      user->email(),
      service_id,
      challenge,
      callback);
  attestation_flow_->GetCertificate(
      PROFILE_CONTENT_PROTECTION_CERTIFICATE,
      user->email(),
      service_id,
      false,  // Don't force a new key.
      certificate_callback);
}

void PlatformVerificationFlow::OnCertificateReady(
    const std::string& user_id,
    const std::string& service_id,
    const std::string& challenge,
    const ChallengeCallback& callback,
    bool operation_success,
    const std::string& certificate) {
  if (!operation_success) {
    LOG(WARNING) << "PlatformVerificationFlow: Failed to certify platform.";
    ReportError(callback, PLATFORM_NOT_VERIFIED);
    return;
  }
  cryptohome::AsyncMethodCaller::DataCallback cryptohome_callback = base::Bind(
      &PlatformVerificationFlow::OnChallengeReady,
      weak_factory_.GetWeakPtr(),
      certificate,
      challenge,
      callback);
  std::string key_name = kContentProtectionKeyPrefix;
  key_name += service_id;
  async_caller_->TpmAttestationSignSimpleChallenge(KEY_USER,
                                                   user_id,
                                                   key_name,
                                                   challenge,
                                                   cryptohome_callback);
}

void PlatformVerificationFlow::OnChallengeReady(
    const std::string& certificate,
    const std::string& challenge,
    const ChallengeCallback& callback,
    bool operation_success,
    const std::string& response_data) {
  if (!operation_success) {
    LOG(ERROR) << "PlatformVerificationFlow: Failed to sign challenge.";
    ReportError(callback, INTERNAL_ERROR);
    return;
  }
  SignedData signed_data_pb;
  if (response_data.empty() || !signed_data_pb.ParseFromString(response_data)) {
    LOG(ERROR) << "PlatformVerificationFlow: Failed to parse response data.";
    ReportError(callback, INTERNAL_ERROR);
    return;
  }
  callback.Run(SUCCESS,
               signed_data_pb.data(),
               signed_data_pb.signature(),
               certificate);
  LOG(INFO) << "PlatformVerificationFlow: Platform successfully verified.";
}

PrefService* PlatformVerificationFlow::GetPrefs(
    content::WebContents* web_contents) {
  if (testing_prefs_)
    return testing_prefs_;
  return user_prefs::UserPrefs::Get(web_contents->GetBrowserContext());
}

const GURL& PlatformVerificationFlow::GetURL(
    content::WebContents* web_contents) {
  if (!testing_url_.is_empty())
    return testing_url_;
  return web_contents->GetLastCommittedURL();
}

User* PlatformVerificationFlow::GetUser(content::WebContents* web_contents) {
  if (!web_contents)
    return user_manager_->GetActiveUser();
  return user_manager_->GetUserByProfile(
      Profile::FromBrowserContext(web_contents->GetBrowserContext()));
}

bool PlatformVerificationFlow::IsAttestationEnabled(
    content::WebContents* web_contents) {
  // Check the device policy for the feature.
  bool enabled_for_device = false;
  if (!CrosSettings::Get()->GetBoolean(kAttestationForContentProtectionEnabled,
                                       &enabled_for_device)) {
    LOG(ERROR) << "Failed to get device setting.";
    return false;
  }
  if (!enabled_for_device)
    return false;

  // Check the user preference for the feature.
  PrefService* pref_service = GetPrefs(web_contents);
  if (!pref_service) {
    LOG(ERROR) << "Failed to get user prefs.";
    return false;
  }
  if (!pref_service->GetBoolean(prefs::kEnableDRM))
    return false;

  // Check the user preference for this domain.
  bool enabled_for_domain = false;
  bool found = GetDomainPref(web_contents, &enabled_for_domain);
  return (!found || enabled_for_domain);
}

bool PlatformVerificationFlow::IsFirstUse(content::WebContents* web_contents) {
  PrefService* pref_service = GetPrefs(web_contents);
  if (!pref_service) {
    LOG(ERROR) << "Failed to get user prefs.";
    return true;
  }
  return !pref_service->GetBoolean(prefs::kRAConsentFirstTime);
}

bool PlatformVerificationFlow::IsAlwaysAskRequired(
    content::WebContents* web_contents) {
  PrefService* pref_service = GetPrefs(web_contents);
  if (!pref_service) {
    LOG(ERROR) << "Failed to get user prefs.";
    return true;
  }
  if (!pref_service->GetBoolean(prefs::kRAConsentAlways))
    return false;
  // Show the consent UI if the user has not already explicitly allowed or
  // denied for this domain.
  return !GetDomainPref(web_contents, NULL);
}

bool PlatformVerificationFlow::UpdateSettings(
    content::WebContents* web_contents,
    ConsentType consent_type,
    ConsentResponse consent_response) {
  PrefService* pref_service = GetPrefs(web_contents);
  if (!pref_service) {
    LOG(ERROR) << "Failed to get user prefs.";
    return false;
  }
  if (consent_type == CONSENT_TYPE_ATTESTATION) {
    if (consent_response == CONSENT_RESPONSE_DENY) {
      pref_service->SetBoolean(prefs::kEnableDRM, false);
    } else if (consent_response == CONSENT_RESPONSE_ALLOW) {
      pref_service->SetBoolean(prefs::kRAConsentFirstTime, true);
      RecordDomainConsent(web_contents, true);
    } else if (consent_response == CONSENT_RESPONSE_ALWAYS_ASK) {
      pref_service->SetBoolean(prefs::kRAConsentFirstTime, true);
      pref_service->SetBoolean(prefs::kRAConsentAlways, true);
      RecordDomainConsent(web_contents, true);
    }
  } else if (consent_type == CONSENT_TYPE_ALWAYS) {
    bool allowed = (consent_response == CONSENT_RESPONSE_ALLOW ||
                    consent_response == CONSENT_RESPONSE_ALWAYS_ASK);
    RecordDomainConsent(web_contents, allowed);
  }
  return true;
}

bool PlatformVerificationFlow::GetDomainPref(
    content::WebContents* web_contents,
    bool* pref_value) {
  PrefService* pref_service = GetPrefs(web_contents);
  CHECK(pref_service);
  base::DictionaryValue::Iterator iter(
      *pref_service->GetDictionary(prefs::kRAConsentDomains));
  const GURL& url = GetURL(web_contents);
  while (!iter.IsAtEnd()) {
    if (url.DomainIs(iter.key().c_str())) {
      if (pref_value) {
        if (!iter.value().GetAsBoolean(pref_value)) {
          LOG(ERROR) << "Unexpected pref type.";
          *pref_value = false;
        }
      }
      return true;
    }
    iter.Advance();
  }
  return false;
}

void PlatformVerificationFlow::RecordDomainConsent(
    content::WebContents* web_contents,
    bool allow_domain) {
  PrefService* pref_service = GetPrefs(web_contents);
  CHECK(pref_service);
  DictionaryPrefUpdate updater(pref_service, prefs::kRAConsentDomains);
  const GURL& url = GetURL(web_contents);
  updater->SetBoolean(url.host(), allow_domain);
}

}  // namespace attestation
}  // namespace chromeos
