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 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); 61 verifier->SetCertTrustAnchorProvider(this); 62 delegate_.reset(verifier); 63 } 64 65 void PolicyCertVerifier::SetTrustAnchors( 66 const net::CertificateList& trust_anchors) { 67 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 68 trust_anchors_ = trust_anchors; 69 } 70 71 int 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 93 void PolicyCertVerifier::CancelRequest(RequestHandle req) { 94 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 95 delegate_->CancelRequest(req); 96 } 97 98 const net::CertificateList& PolicyCertVerifier::GetAdditionalTrustAnchors() { 99 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 100 return trust_anchors_; 101 } 102 103 } // namespace policy 104