xref: /aosp_15_r20/external/cronet/net/cert/nss_profile_filter_chromeos.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/cert/nss_profile_filter_chromeos.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "base/logging.h"
11 #include "net/cert/x509_certificate.h"
12 
13 namespace net {
14 
15 NSSProfileFilterChromeOS::NSSProfileFilterChromeOS() = default;
16 
NSSProfileFilterChromeOS(const NSSProfileFilterChromeOS & other)17 NSSProfileFilterChromeOS::NSSProfileFilterChromeOS(
18     const NSSProfileFilterChromeOS& other) {
19   public_slot_.reset(other.public_slot_
20                          ? PK11_ReferenceSlot(other.public_slot_.get())
21                          : nullptr);
22   private_slot_.reset(other.private_slot_
23                           ? PK11_ReferenceSlot(other.private_slot_.get())
24                           : nullptr);
25   system_slot_.reset(other.system_slot_
26                          ? PK11_ReferenceSlot(other.system_slot_.get())
27                          : nullptr);
28 }
29 
30 NSSProfileFilterChromeOS::~NSSProfileFilterChromeOS() = default;
31 
operator =(const NSSProfileFilterChromeOS & other)32 NSSProfileFilterChromeOS& NSSProfileFilterChromeOS::operator=(
33     const NSSProfileFilterChromeOS& other) {
34   public_slot_.reset(other.public_slot_
35                          ? PK11_ReferenceSlot(other.public_slot_.get())
36                          : nullptr);
37   private_slot_.reset(other.private_slot_
38                           ? PK11_ReferenceSlot(other.private_slot_.get())
39                           : nullptr);
40   system_slot_.reset(other.system_slot_
41                          ? PK11_ReferenceSlot(other.system_slot_.get())
42                          : nullptr);
43   return *this;
44 }
45 
Init(crypto::ScopedPK11Slot public_slot,crypto::ScopedPK11Slot private_slot,crypto::ScopedPK11Slot system_slot)46 void NSSProfileFilterChromeOS::Init(crypto::ScopedPK11Slot public_slot,
47                                     crypto::ScopedPK11Slot private_slot,
48                                     crypto::ScopedPK11Slot system_slot) {
49   // crypto::ScopedPK11Slot actually holds a reference counted object.
50   // Because std::unique_ptr<T> assignment is a no-op if it already points to
51   // the same pointer, a reference would be leaked because std::move() does
52   // not release its reference, and the receiving object won't free
53   // its copy.
54   // TODO(dcheng): This comment doesn't seem quite right.
55   if (public_slot_.get() != public_slot.get())
56     public_slot_ = std::move(public_slot);
57   if (private_slot_.get() != private_slot.get())
58     private_slot_ = std::move(private_slot);
59   if (system_slot_.get() != system_slot.get())
60     system_slot_ = std::move(system_slot);
61 }
62 
IsModuleAllowed(PK11SlotInfo * slot) const63 bool NSSProfileFilterChromeOS::IsModuleAllowed(PK11SlotInfo* slot) const {
64   // If this is one of the public/private slots for this profile or the system
65   // slot, allow it.
66   if (slot == public_slot_.get() || slot == private_slot_.get() ||
67       slot == system_slot_.get()) {
68     return true;
69   }
70   // Allow the root certs module.
71   if (PK11_HasRootCerts(slot))
72     return true;
73   // If it's from the read-only slots, allow it.
74   if (PK11_IsInternal(slot) && !PK11_IsRemovable(slot))
75     return true;
76   // If |public_slot_| or |private_slot_| is null, there isn't a way to get the
77   // modules to use in the final test.
78   if (!public_slot_.get() || !private_slot_.get())
79     return false;
80   // If this is not the internal (file-system) module or the TPM module, allow
81   // it. This would allow smartcards/etc, although ChromeOS doesn't currently
82   // support that. (This assumes that private_slot_ and system_slot_ are on the
83   // same module.)
84   DCHECK(!system_slot_.get() ||
85          PK11_GetModule(private_slot_.get()) ==
86              PK11_GetModule(system_slot_.get()));
87   SECMODModule* module_for_slot = PK11_GetModule(slot);
88   if (module_for_slot != PK11_GetModule(public_slot_.get()) &&
89       module_for_slot != PK11_GetModule(private_slot_.get())) {
90     return true;
91   }
92   return false;
93 }
94 
IsCertAllowed(CERTCertificate * cert) const95 bool NSSProfileFilterChromeOS::IsCertAllowed(CERTCertificate* cert) const {
96   crypto::ScopedPK11SlotList slots_for_cert(
97       PK11_GetAllSlotsForCert(cert, nullptr));
98   if (!slots_for_cert)
99     return false;
100 
101   for (PK11SlotListElement* slot_element =
102            PK11_GetFirstSafe(slots_for_cert.get());
103        slot_element;
104        slot_element =
105            PK11_GetNextSafe(slots_for_cert.get(), slot_element, PR_FALSE)) {
106     if (IsModuleAllowed(slot_element->slot)) {
107       PK11_FreeSlotListElement(slots_for_cert.get(), slot_element);
108       return true;
109     }
110   }
111 
112   return false;
113 }
114 
115 }  // namespace net
116