1 // Copyright 2016 The Chromium Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "trust_store_in_memory.h"
16 
17 BSSL_NAMESPACE_BEGIN
18 
19 TrustStoreInMemory::TrustStoreInMemory() = default;
20 TrustStoreInMemory::~TrustStoreInMemory() = default;
21 
IsEmpty() const22 bool TrustStoreInMemory::IsEmpty() const { return entries_.empty(); }
23 
Clear()24 void TrustStoreInMemory::Clear() { entries_.clear(); }
25 
AddTrustAnchor(std::shared_ptr<const ParsedCertificate> cert)26 void TrustStoreInMemory::AddTrustAnchor(
27     std::shared_ptr<const ParsedCertificate> cert) {
28   AddCertificate(std::move(cert), CertificateTrust::ForTrustAnchor());
29 }
30 
AddTrustAnchorWithExpiration(std::shared_ptr<const ParsedCertificate> cert)31 void TrustStoreInMemory::AddTrustAnchorWithExpiration(
32     std::shared_ptr<const ParsedCertificate> cert) {
33   AddCertificate(std::move(cert),
34                  CertificateTrust::ForTrustAnchor().WithEnforceAnchorExpiry());
35 }
36 
AddTrustAnchorWithConstraints(std::shared_ptr<const ParsedCertificate> cert)37 void TrustStoreInMemory::AddTrustAnchorWithConstraints(
38     std::shared_ptr<const ParsedCertificate> cert) {
39   AddCertificate(
40       std::move(cert),
41       CertificateTrust::ForTrustAnchor().WithEnforceAnchorConstraints());
42 }
43 
AddDistrustedCertificateForTest(std::shared_ptr<const ParsedCertificate> cert)44 void TrustStoreInMemory::AddDistrustedCertificateForTest(
45     std::shared_ptr<const ParsedCertificate> cert) {
46   AddCertificate(std::move(cert), CertificateTrust::ForDistrusted());
47 }
48 
AddDistrustedCertificateBySPKI(std::string spki)49 void TrustStoreInMemory::AddDistrustedCertificateBySPKI(std::string spki) {
50   distrusted_spkis_.insert(std::move(spki));
51 }
52 
AddCertificateWithUnspecifiedTrust(std::shared_ptr<const ParsedCertificate> cert)53 void TrustStoreInMemory::AddCertificateWithUnspecifiedTrust(
54     std::shared_ptr<const ParsedCertificate> cert) {
55   AddCertificate(std::move(cert), CertificateTrust::ForUnspecified());
56 }
57 
SyncGetIssuersOf(const ParsedCertificate * cert,ParsedCertificateList * issuers)58 void TrustStoreInMemory::SyncGetIssuersOf(const ParsedCertificate *cert,
59                                           ParsedCertificateList *issuers) {
60   auto range =
61       entries_.equal_range(BytesAsStringView(cert->normalized_issuer()));
62   for (auto it = range.first; it != range.second; ++it) {
63     issuers->push_back(it->second.cert);
64   }
65 }
66 
GetTrust(const ParsedCertificate * cert)67 CertificateTrust TrustStoreInMemory::GetTrust(const ParsedCertificate *cert) {
68   // Check SPKI distrust first.
69   if (distrusted_spkis_.find(BytesAsStringView(cert->tbs().spki_tlv)) !=
70       distrusted_spkis_.end()) {
71     return CertificateTrust::ForDistrusted();
72   }
73 
74   const Entry *entry = GetEntry(cert);
75   return entry ? entry->trust : CertificateTrust::ForUnspecified();
76 }
77 
Contains(const ParsedCertificate * cert) const78 bool TrustStoreInMemory::Contains(const ParsedCertificate *cert) const {
79   return GetEntry(cert) != nullptr;
80 }
81 
82 TrustStoreInMemory::Entry::Entry() = default;
83 TrustStoreInMemory::Entry::Entry(const Entry &other) = default;
84 TrustStoreInMemory::Entry::~Entry() = default;
85 
AddCertificate(std::shared_ptr<const ParsedCertificate> cert,const CertificateTrust & trust)86 void TrustStoreInMemory::AddCertificate(
87     std::shared_ptr<const ParsedCertificate> cert,
88     const CertificateTrust &trust) {
89   Entry entry;
90   entry.cert = std::move(cert);
91   entry.trust = trust;
92 
93   // TODO(mattm): should this check for duplicate certificates?
94   entries_.emplace(BytesAsStringView(entry.cert->normalized_subject()), entry);
95 }
96 
GetEntry(const ParsedCertificate * cert) const97 const TrustStoreInMemory::Entry *TrustStoreInMemory::GetEntry(
98     const ParsedCertificate *cert) const {
99   auto range =
100       entries_.equal_range(BytesAsStringView(cert->normalized_subject()));
101   for (auto it = range.first; it != range.second; ++it) {
102     if (cert == it->second.cert.get() ||
103         cert->der_cert() == it->second.cert->der_cert()) {
104       // NOTE: ambiguity when there are duplicate entries.
105       return &it->second;
106     }
107   }
108   return nullptr;
109 }
110 
111 BSSL_NAMESPACE_END
112