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) { 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Only the software slot is passed, since that is the only one where user 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // trust settings are stored. 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) profile_filter_.Init( 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public_slot.Pass(), crypto::ScopedPK11Slot(), crypto::ScopedPK11Slot()); 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CertVerifyProcChromeOS::~CertVerifyProcChromeOS() {} 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int CertVerifyProcChromeOS::VerifyInternal( 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::X509Certificate* cert, 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& hostname, 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int flags, 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::CRLSet* crl_set, 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::CertificateList& additional_trust_anchors, 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::CertVerifyResult* verify_result) { 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ChainVerifyArgs chain_verify_args = {this, additional_trust_anchors}; 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CERTChainVerifyCallback chain_verify_callback; 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chain_verify_callback.isChainValid = 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &CertVerifyProcChromeOS::IsChainValidFunc; 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chain_verify_callback.isChainValidArg = 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<void*>(&chain_verify_args); 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return VerifyInternalImpl(cert, 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostname, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) flags, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crl_set, 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) additional_trust_anchors, 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &chain_verify_callback, 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) verify_result); 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SECStatus CertVerifyProcChromeOS::IsChainValidFunc( 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void* is_chain_valid_arg, 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const CERTCertList* current_chain, 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PRBool* chain_ok) { 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ChainVerifyArgs* args = static_cast<ChainVerifyArgs*>(is_chain_valid_arg); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CERTCertificate* cert = CERT_LIST_TAIL(current_chain)->cert; 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (net::TestRootCerts::HasInstance()) { 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (net::TestRootCerts::GetInstance()->Contains(cert)) { 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Certs in the TestRootCerts are not stored in any slot, and thus would 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // not be allowed by the profile_filter. This should only be hit in tests. 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(3) << cert->subjectName << " is a TestRootCert"; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *chain_ok = PR_TRUE; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return SECSuccess; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (net::CertificateList::const_iterator i = 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args->additional_trust_anchors.begin(); 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) i != args->additional_trust_anchors.end(); 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++i) { 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (net::X509Certificate::IsSameOSCert(cert, (*i)->os_cert_handle())) { 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Certs in the additional_trust_anchors should always be allowed, even if 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // they aren't stored in a slot that would be allowed by the 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // profile_filter. 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(3) << cert->subjectName << " is an additional_trust_anchor"; 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *chain_ok = PR_TRUE; 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return SECSuccess; 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(mattm): If crbug.com/334384 is fixed to allow setting trust 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // properly when the same cert is in multiple slots, this would also need 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // updating to check the per-slot trust values. 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *chain_ok = args->cert_verify_proc->profile_filter_.IsCertAllowed(cert) 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ? PR_TRUE 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : PR_FALSE; 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(3) << cert->subjectName << " is " << (*chain_ok ? "ok" : "not ok"); 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return SECSuccess; 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace chromeos 107