58 lines
2.1 KiB
C++
58 lines
2.1 KiB
C++
// Copyright 2017 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "net/cert/known_roots_nss.h"
|
|
|
|
#include <cert.h>
|
|
#include <dlfcn.h>
|
|
#include <pk11pub.h>
|
|
#include <secmod.h>
|
|
|
|
#include <memory>
|
|
|
|
#include "crypto/nss_util_internal.h"
|
|
#include "net/cert/x509_util_nss.h"
|
|
|
|
namespace net {
|
|
|
|
// IsKnownRoot returns true if the given certificate is one that we believe
|
|
// is a standard (as opposed to user-installed) root.
|
|
bool IsKnownRoot(CERTCertificate* root) {
|
|
if (!root || !root->slot)
|
|
return false;
|
|
|
|
// Historically, the set of root certs was determined based on whether or
|
|
// not it was part of nssckbi.[so,dll], the read-only PKCS#11 module that
|
|
// exported the certs with trust settings. However, some distributions,
|
|
// notably those in the Red Hat family, replace nssckbi with a redirect to
|
|
// their own store, such as from p11-kit, which can support more robust
|
|
// trust settings, like per-system trust, admin-defined, and user-defined
|
|
// trust.
|
|
//
|
|
// As a given certificate may exist in multiple modules and slots, scan
|
|
// through all of the available modules, all of the (connected) slots on
|
|
// those modules, and check to see if it has the CKA_NSS_MOZILLA_CA_POLICY
|
|
// attribute set. This attribute indicates it's from the upstream Mozilla
|
|
// trust store, and these distributions preserve the attribute as a flag.
|
|
crypto::AutoSECMODListReadLock lock_id;
|
|
for (const SECMODModuleList* item = SECMOD_GetDefaultModuleList();
|
|
item != nullptr; item = item->next) {
|
|
for (int i = 0; i < item->module->slotCount; ++i) {
|
|
PK11SlotInfo* slot = item->module->slots[i];
|
|
if (PK11_IsPresent(slot) && PK11_HasRootCerts(slot)) {
|
|
CK_OBJECT_HANDLE handle = PK11_FindCertInSlot(slot, root, nullptr);
|
|
if (handle != CK_INVALID_HANDLE &&
|
|
PK11_HasAttributeSet(slot, handle, CKA_NSS_MOZILLA_CA_POLICY,
|
|
PR_FALSE) == CK_TRUE) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
} // namespace net
|