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