cert_verify_proc_chromeos.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2014 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/net/cert_verify_proc_chromeos.h" 6 7#include "net/cert/test_root_certs.h" 8#include "net/cert/x509_certificate.h" 9 10// NSS doesn't currently define CERT_LIST_TAIL. 11// See https://bugzilla.mozilla.org/show_bug.cgi?id=962413 12// Can be removed once chrome requires NSS version 3.16 to build. 13#ifndef CERT_LIST_TAIL 14#define CERT_LIST_TAIL(l) ((CERTCertListNode *)PR_LIST_TAIL(&l->list)) 15#endif 16 17namespace chromeos { 18 19namespace { 20 21struct ChainVerifyArgs { 22 CertVerifyProcChromeOS* cert_verify_proc; 23 const net::CertificateList& additional_trust_anchors; 24}; 25 26} // namespace 27 28CertVerifyProcChromeOS::CertVerifyProcChromeOS() {} 29 30CertVerifyProcChromeOS::CertVerifyProcChromeOS( 31 crypto::ScopedPK11Slot public_slot) { 32 profile_filter_.Init(public_slot.Pass(), crypto::ScopedPK11Slot()); 33} 34 35CertVerifyProcChromeOS::~CertVerifyProcChromeOS() {} 36 37int CertVerifyProcChromeOS::VerifyInternal( 38 net::X509Certificate* cert, 39 const std::string& hostname, 40 int flags, 41 net::CRLSet* crl_set, 42 const net::CertificateList& additional_trust_anchors, 43 net::CertVerifyResult* verify_result) { 44 ChainVerifyArgs chain_verify_args = {this, additional_trust_anchors}; 45 46 CERTChainVerifyCallback chain_verify_callback; 47 chain_verify_callback.isChainValid = 48 &CertVerifyProcChromeOS::IsChainValidFunc; 49 chain_verify_callback.isChainValidArg = 50 static_cast<void*>(&chain_verify_args); 51 52 return VerifyInternalImpl(cert, 53 hostname, 54 flags, 55 crl_set, 56 additional_trust_anchors, 57 &chain_verify_callback, 58 verify_result); 59} 60 61// static 62SECStatus CertVerifyProcChromeOS::IsChainValidFunc( 63 void* is_chain_valid_arg, 64 const CERTCertList* current_chain, 65 PRBool* chain_ok) { 66 ChainVerifyArgs* args = static_cast<ChainVerifyArgs*>(is_chain_valid_arg); 67 CERTCertificate* cert = CERT_LIST_TAIL(current_chain)->cert; 68 69 if (net::TestRootCerts::HasInstance()) { 70 if (net::TestRootCerts::GetInstance()->Contains(cert)) { 71 // Certs in the TestRootCerts are not stored in any slot, and thus would 72 // not be allowed by the profile_filter. This should only be hit in tests. 73 DVLOG(3) << cert->subjectName << " is a TestRootCert"; 74 *chain_ok = PR_TRUE; 75 return SECSuccess; 76 } 77 } 78 79 for (net::CertificateList::const_iterator i = 80 args->additional_trust_anchors.begin(); 81 i != args->additional_trust_anchors.end(); 82 ++i) { 83 if (net::X509Certificate::IsSameOSCert(cert, (*i)->os_cert_handle())) { 84 // Certs in the additional_trust_anchors should always be allowed, even if 85 // they aren't stored in a slot that would be allowed by the 86 // profile_filter. 87 DVLOG(3) << cert->subjectName << " is an additional_trust_anchor"; 88 *chain_ok = PR_TRUE; 89 return SECSuccess; 90 } 91 } 92 93 // TODO(mattm): If crbug.com/334384 is fixed to allow setting trust 94 // properly when the same cert is in multiple slots, this would also need 95 // updating to check the per-slot trust values. 96 *chain_ok = args->cert_verify_proc->profile_filter_.IsCertAllowed(cert) 97 ? PR_TRUE 98 : PR_FALSE; 99 DVLOG(3) << cert->subjectName << " is " << (*chain_ok ? "ok" : "not ok"); 100 return SECSuccess; 101} 102 103} // namespace chromeos 104