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 14namespace policy { 15 16namespace { 17 18void 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 29void 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 42PolicyCertVerifier::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 48PolicyCertVerifier::~PolicyCertVerifier() { 49 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 50} 51 52void PolicyCertVerifier::InitializeOnIOThread( 53 const scoped_refptr<net::CertVerifyProc>& verify_proc) { 54 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 55 if (!verify_proc->SupportsAdditionalTrustAnchors()) { 56 LOG(WARNING) 57 << "Additional trust anchors not supported on the current platform!"; 58 } 59 net::MultiThreadedCertVerifier* verifier = 60 new net::MultiThreadedCertVerifier(verify_proc.get()); 61 verifier->SetCertTrustAnchorProvider(this); 62 delegate_.reset(verifier); 63} 64 65void PolicyCertVerifier::SetTrustAnchors( 66 const net::CertificateList& trust_anchors) { 67 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 68 trust_anchors_ = trust_anchors; 69} 70 71int PolicyCertVerifier::Verify( 72 net::X509Certificate* cert, 73 const std::string& hostname, 74 int flags, 75 net::CRLSet* crl_set, 76 net::CertVerifyResult* verify_result, 77 const net::CompletionCallback& completion_callback, 78 RequestHandle* out_req, 79 const net::BoundNetLog& net_log) { 80 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 81 DCHECK(delegate_); 82 net::CompletionCallback wrapped_callback = 83 base::Bind(&CompleteAndSignalAnchorUse, 84 anchor_used_callback_, 85 completion_callback, 86 verify_result); 87 int error = delegate_->Verify(cert, hostname, flags, crl_set, verify_result, 88 wrapped_callback, out_req, net_log); 89 MaybeSignalAnchorUse(error, anchor_used_callback_, *verify_result); 90 return error; 91} 92 93void PolicyCertVerifier::CancelRequest(RequestHandle req) { 94 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 95 delegate_->CancelRequest(req); 96} 97 98const net::CertificateList& PolicyCertVerifier::GetAdditionalTrustAnchors() { 99 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 100 return trust_anchors_; 101} 102 103} // namespace policy 104