Home | History | Annotate | Download | only in policy
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/policy/policy_cert_verifier.h"
      6 
      7 #include "base/logging.h"
      8 #include "chrome/browser/browser_process.h"
      9 #include "content/public/browser/browser_thread.h"
     10 #include "net/base/net_errors.h"
     11 #include "net/cert/cert_verify_proc.h"
     12 #include "net/cert/multi_threaded_cert_verifier.h"
     13 
     14 namespace policy {
     15 
     16 namespace {
     17 
     18 void MaybeSignalAnchorUse(int error,
     19                           const base::Closure& anchor_used_callback,
     20                           const net::CertVerifyResult& verify_result) {
     21   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     22   if (error != net::OK || !verify_result.is_issued_by_additional_trust_anchor ||
     23       anchor_used_callback.is_null()) {
     24     return;
     25   }
     26   anchor_used_callback.Run();
     27 }
     28 
     29 void CompleteAndSignalAnchorUse(
     30     const base::Closure& anchor_used_callback,
     31     const net::CompletionCallback& completion_callback,
     32     const net::CertVerifyResult* verify_result,
     33     int error) {
     34   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     35   MaybeSignalAnchorUse(error, anchor_used_callback, *verify_result);
     36   if (!completion_callback.is_null())
     37     completion_callback.Run(error);
     38 }
     39 
     40 }  // namespace
     41 
     42 PolicyCertVerifier::PolicyCertVerifier(
     43     const base::Closure& anchor_used_callback)
     44     : anchor_used_callback_(anchor_used_callback) {
     45   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     46 }
     47 
     48 PolicyCertVerifier::~PolicyCertVerifier() {
     49   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     50 }
     51 
     52 void PolicyCertVerifier::InitializeOnIOThread() {
     53   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     54   scoped_refptr<net::CertVerifyProc> verify_proc =
     55       net::CertVerifyProc::CreateDefault();
     56   if (!verify_proc->SupportsAdditionalTrustAnchors()) {
     57     LOG(WARNING)
     58         << "Additional trust anchors not supported on the current platform!";
     59   }
     60   net::MultiThreadedCertVerifier* verifier =
     61       new net::MultiThreadedCertVerifier(verify_proc.get());
     62   verifier->SetCertTrustAnchorProvider(this);
     63   delegate_.reset(verifier);
     64 }
     65 
     66 void PolicyCertVerifier::SetTrustAnchors(
     67     const net::CertificateList& trust_anchors) {
     68   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     69   trust_anchors_ = trust_anchors;
     70 }
     71 
     72 int PolicyCertVerifier::Verify(
     73     net::X509Certificate* cert,
     74     const std::string& hostname,
     75     int flags,
     76     net::CRLSet* crl_set,
     77     net::CertVerifyResult* verify_result,
     78     const net::CompletionCallback& completion_callback,
     79     RequestHandle* out_req,
     80     const net::BoundNetLog& net_log) {
     81   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     82   DCHECK(delegate_);
     83   net::CompletionCallback wrapped_callback =
     84       base::Bind(&CompleteAndSignalAnchorUse,
     85                  anchor_used_callback_,
     86                  completion_callback,
     87                  verify_result);
     88   int error = delegate_->Verify(cert, hostname, flags, crl_set, verify_result,
     89                                 wrapped_callback, out_req, net_log);
     90   MaybeSignalAnchorUse(error, anchor_used_callback_, *verify_result);
     91   return error;
     92 }
     93 
     94 void PolicyCertVerifier::CancelRequest(RequestHandle req) {
     95   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     96   delegate_->CancelRequest(req);
     97 }
     98 
     99 const net::CertificateList& PolicyCertVerifier::GetAdditionalTrustAnchors() {
    100   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
    101   return trust_anchors_;
    102 }
    103 
    104 }  // namespace policy
    105