cert_verify_proc_chromeos.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/net/cert_verify_proc_chromeos.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/cert/test_root_certs.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/cert/x509_certificate.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// NSS doesn't currently define CERT_LIST_TAIL. 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// See https://bugzilla.mozilla.org/show_bug.cgi?id=962413 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Can be removed once chrome requires NSS version 3.16 to build. 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef CERT_LIST_TAIL 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define CERT_LIST_TAIL(l) ((CERTCertListNode *)PR_LIST_TAIL(&l->list)) 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace chromeos { 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct ChainVerifyArgs { 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CertVerifyProcChromeOS* cert_verify_proc; 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::CertificateList& additional_trust_anchors; 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CertVerifyProcChromeOS::CertVerifyProcChromeOS() {} 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CertVerifyProcChromeOS::CertVerifyProcChromeOS( 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crypto::ScopedPK11Slot public_slot) { 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_filter_.Init(public_slot.Pass(), crypto::ScopedPK11Slot()); 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CertVerifyProcChromeOS::~CertVerifyProcChromeOS() {} 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int CertVerifyProcChromeOS::VerifyInternal( 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::X509Certificate* cert, 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& hostname, 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int flags, 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::CRLSet* crl_set, 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::CertificateList& additional_trust_anchors, 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::CertVerifyResult* verify_result) { 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ChainVerifyArgs chain_verify_args = {this, additional_trust_anchors}; 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CERTChainVerifyCallback chain_verify_callback; 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chain_verify_callback.isChainValid = 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &CertVerifyProcChromeOS::IsChainValidFunc; 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chain_verify_callback.isChainValidArg = 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<void*>(&chain_verify_args); 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return VerifyInternalImpl(cert, 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostname, 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) flags, 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crl_set, 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) additional_trust_anchors, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &chain_verify_callback, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) verify_result); 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SECStatus CertVerifyProcChromeOS::IsChainValidFunc( 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void* is_chain_valid_arg, 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const CERTCertList* current_chain, 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PRBool* chain_ok) { 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ChainVerifyArgs* args = static_cast<ChainVerifyArgs*>(is_chain_valid_arg); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CERTCertificate* cert = CERT_LIST_TAIL(current_chain)->cert; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (net::TestRootCerts::HasInstance()) { 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (net::TestRootCerts::GetInstance()->Contains(cert)) { 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Certs in the TestRootCerts are not stored in any slot, and thus would 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // not be allowed by the profile_filter. This should only be hit in tests. 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(3) << cert->subjectName << " is a TestRootCert"; 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *chain_ok = PR_TRUE; 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return SECSuccess; 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (net::CertificateList::const_iterator i = 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args->additional_trust_anchors.begin(); 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) i != args->additional_trust_anchors.end(); 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++i) { 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (net::X509Certificate::IsSameOSCert(cert, (*i)->os_cert_handle())) { 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Certs in the additional_trust_anchors should always be allowed, even if 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // they aren't stored in a slot that would be allowed by the 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // profile_filter. 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(3) << cert->subjectName << " is an additional_trust_anchor"; 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *chain_ok = PR_TRUE; 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return SECSuccess; 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(mattm): If crbug.com/334384 is fixed to allow setting trust 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // properly when the same cert is in multiple slots, this would also need 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // updating to check the per-slot trust values. 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *chain_ok = args->cert_verify_proc->profile_filter_.IsCertAllowed(cert) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ? PR_TRUE 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : PR_FALSE; 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(3) << cert->subjectName << " is " << (*chain_ok ? "ok" : "not ok"); 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return SECSuccess; 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace chromeos 104