// Copyright (c) 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 "chrome/browser/chromeos/policy/policy_cert_verifier.h"

#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/browser_process.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_verify_proc.h"
#include "net/cert/multi_threaded_cert_verifier.h"

namespace policy {

namespace {

void MaybeSignalAnchorUse(int error,
                          const base::Closure& anchor_used_callback,
                          const net::CertVerifyResult& verify_result) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  if (error != net::OK || !verify_result.is_issued_by_additional_trust_anchor ||
      anchor_used_callback.is_null()) {
    return;
  }
  anchor_used_callback.Run();
}

void CompleteAndSignalAnchorUse(
    const base::Closure& anchor_used_callback,
    const net::CompletionCallback& completion_callback,
    const net::CertVerifyResult* verify_result,
    int error) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  MaybeSignalAnchorUse(error, anchor_used_callback, *verify_result);
  if (!completion_callback.is_null())
    completion_callback.Run(error);
}

}  // namespace

PolicyCertVerifier::PolicyCertVerifier(
    const base::Closure& anchor_used_callback)
    : anchor_used_callback_(anchor_used_callback) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
}

PolicyCertVerifier::~PolicyCertVerifier() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
}

void PolicyCertVerifier::InitializeOnIOThread() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  scoped_refptr<net::CertVerifyProc> verify_proc =
      net::CertVerifyProc::CreateDefault();
  if (!verify_proc->SupportsAdditionalTrustAnchors()) {
    LOG(WARNING)
        << "Additional trust anchors not supported in the current platform!";
  }
  net::MultiThreadedCertVerifier* verifier =
      new net::MultiThreadedCertVerifier(verify_proc.get());
  verifier->SetCertTrustAnchorProvider(this);
  delegate_.reset(verifier);
}

void PolicyCertVerifier::SetTrustAnchors(
    const net::CertificateList& trust_anchors) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  trust_anchors_ = trust_anchors;
}

int PolicyCertVerifier::Verify(
    net::X509Certificate* cert,
    const std::string& hostname,
    int flags,
    net::CRLSet* crl_set,
    net::CertVerifyResult* verify_result,
    const net::CompletionCallback& completion_callback,
    RequestHandle* out_req,
    const net::BoundNetLog& net_log) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  DCHECK(delegate_);
  net::CompletionCallback wrapped_callback =
      base::Bind(&CompleteAndSignalAnchorUse,
                 anchor_used_callback_,
                 completion_callback,
                 verify_result);
  int error = delegate_->Verify(cert, hostname, flags, crl_set, verify_result,
                                wrapped_callback, out_req, net_log);
  MaybeSignalAnchorUse(error, anchor_used_callback_, *verify_result);
  return error;
}

void PolicyCertVerifier::CancelRequest(RequestHandle req) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  delegate_->CancelRequest(req);
}

const net::CertificateList& PolicyCertVerifier::GetAdditionalTrustAnchors() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  return trust_anchors_;
}

}  // namespace policy
