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 "base/memory/ref_counted.h"
      9 #include "base/prefs/pref_service.h"
     10 #include "chrome/browser/browser_process.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "chrome/browser/profiles/profile_manager.h"
     13 #include "chrome/common/pref_names.h"
     14 #include "content/public/browser/browser_thread.h"
     15 #include "net/base/net_errors.h"
     16 #include "net/cert/cert_verify_proc.h"
     17 #include "net/cert/multi_threaded_cert_verifier.h"
     18 
     19 namespace policy {
     20 
     21 namespace {
     22 
     23 void TaintProfile(void* profile_ptr) {
     24   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     25   Profile* profile = reinterpret_cast<Profile*>(profile_ptr);
     26   if (!g_browser_process->profile_manager()->IsValidProfile(profile))
     27     return;
     28   profile->GetPrefs()->SetBoolean(prefs::kUsedPolicyCertificatesOnce, true);
     29 }
     30 
     31 void MaybeTaintProfile(const net::CertVerifyResult& verify_result,
     32                        void* profile) {
     33   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     34   if (verify_result.is_issued_by_additional_trust_anchor) {
     35     content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
     36                                      base::Bind(&TaintProfile, profile));
     37   }
     38 }
     39 
     40 void CallbackWrapper(void* profile,
     41                      const net::CertVerifyResult* verify_result,
     42                      const net::CompletionCallback& original_callback,
     43                      int error) {
     44   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     45   if (error == net::OK)
     46     MaybeTaintProfile(*verify_result, profile);
     47   if (!original_callback.is_null())
     48     original_callback.Run(error);
     49 }
     50 
     51 }  // namespace
     52 
     53 PolicyCertVerifier::PolicyCertVerifier(
     54     void* profile,
     55     net::CertTrustAnchorProvider* trust_anchor_provider)
     56     : profile_(profile) {
     57   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     58   scoped_refptr<net::CertVerifyProc> verify_proc =
     59       net::CertVerifyProc::CreateDefault();
     60   if (!verify_proc->SupportsAdditionalTrustAnchors()) {
     61     LOG(WARNING)
     62         << "Additional trust anchors not supported in the current platform!";
     63   }
     64   net::MultiThreadedCertVerifier* verifier =
     65       new net::MultiThreadedCertVerifier(verify_proc.get());
     66   verifier->SetCertTrustAnchorProvider(trust_anchor_provider);
     67   delegate_.reset(verifier);
     68 }
     69 
     70 PolicyCertVerifier::~PolicyCertVerifier() {
     71   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     72 }
     73 
     74 int PolicyCertVerifier::Verify(net::X509Certificate* cert,
     75                                const std::string& hostname,
     76                                int flags,
     77                                net::CRLSet* crl_set,
     78                                net::CertVerifyResult* verify_result,
     79                                const net::CompletionCallback& callback,
     80                                RequestHandle* out_req,
     81                                const net::BoundNetLog& net_log) {
     82   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     83   net::CompletionCallback wrapped_callback =
     84       base::Bind(&CallbackWrapper, profile_, verify_result, callback);
     85   int error = delegate_->Verify(cert, hostname, flags, crl_set, verify_result,
     86                                 wrapped_callback, out_req, net_log);
     87   if (error == net::OK)
     88     MaybeTaintProfile(*verify_result, profile_);
     89   return error;
     90 }
     91 
     92 void PolicyCertVerifier::CancelRequest(RequestHandle req) {
     93   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     94   delegate_->CancelRequest(req);
     95 }
     96 
     97 }  // namespace policy
     98