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