File: cert_verify_proc_chromeos.cc

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (106 lines) | stat: -rw-r--r-- 3,713 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/net/cert_verify_proc_chromeos.h"

#include "net/cert/test_root_certs.h"
#include "net/cert/x509_certificate.h"

// NSS doesn't currently define CERT_LIST_TAIL.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=962413
// Can be removed once chrome requires NSS version 3.16 to build.
#ifndef CERT_LIST_TAIL
#define CERT_LIST_TAIL(l) ((CERTCertListNode *)PR_LIST_TAIL(&l->list))
#endif

namespace chromeos {

namespace {

struct ChainVerifyArgs {
  CertVerifyProcChromeOS* cert_verify_proc;
  const net::CertificateList& additional_trust_anchors;
};

}  // namespace

CertVerifyProcChromeOS::CertVerifyProcChromeOS() {}

CertVerifyProcChromeOS::CertVerifyProcChromeOS(
    crypto::ScopedPK11Slot public_slot) {
  // Only the software slot is passed, since that is the only one where user
  // trust settings are stored.
  profile_filter_.Init(
      public_slot.Pass(), crypto::ScopedPK11Slot(), crypto::ScopedPK11Slot());
}

CertVerifyProcChromeOS::~CertVerifyProcChromeOS() {}

int CertVerifyProcChromeOS::VerifyInternal(
    net::X509Certificate* cert,
    const std::string& hostname,
    int flags,
    net::CRLSet* crl_set,
    const net::CertificateList& additional_trust_anchors,
    net::CertVerifyResult* verify_result) {
  ChainVerifyArgs chain_verify_args = {this, additional_trust_anchors};

  CERTChainVerifyCallback chain_verify_callback;
  chain_verify_callback.isChainValid =
      &CertVerifyProcChromeOS::IsChainValidFunc;
  chain_verify_callback.isChainValidArg =
      static_cast<void*>(&chain_verify_args);

  return VerifyInternalImpl(cert,
                            hostname,
                            flags,
                            crl_set,
                            additional_trust_anchors,
                            &chain_verify_callback,
                            verify_result);
}

// static
SECStatus CertVerifyProcChromeOS::IsChainValidFunc(
    void* is_chain_valid_arg,
    const CERTCertList* current_chain,
    PRBool* chain_ok) {
  ChainVerifyArgs* args = static_cast<ChainVerifyArgs*>(is_chain_valid_arg);
  CERTCertificate* cert = CERT_LIST_TAIL(current_chain)->cert;

  if (net::TestRootCerts::HasInstance()) {
    if (net::TestRootCerts::GetInstance()->Contains(cert)) {
      // Certs in the TestRootCerts are not stored in any slot, and thus would
      // not be allowed by the profile_filter. This should only be hit in tests.
      DVLOG(3) << cert->subjectName << " is a TestRootCert";
      *chain_ok = PR_TRUE;
      return SECSuccess;
    }
  }

  for (net::CertificateList::const_iterator i =
           args->additional_trust_anchors.begin();
       i != args->additional_trust_anchors.end();
       ++i) {
    if (net::X509Certificate::IsSameOSCert(cert, (*i)->os_cert_handle())) {
      // Certs in the additional_trust_anchors should always be allowed, even if
      // they aren't stored in a slot that would be allowed by the
      // profile_filter.
      DVLOG(3) << cert->subjectName << " is an additional_trust_anchor";
      *chain_ok = PR_TRUE;
      return SECSuccess;
    }
  }

  // TODO(mattm): If crbug.com/334384 is fixed to allow setting trust
  // properly when the same cert is in multiple slots, this would also need
  // updating to check the per-slot trust values.
  *chain_ok = args->cert_verify_proc->profile_filter_.IsCertAllowed(cert)
                  ? PR_TRUE
                  : PR_FALSE;
  DVLOG(3) << cert->subjectName << " is " << (*chain_ok ? "ok" : "not ok");
  return SECSuccess;
}

}  // namespace chromeos