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 #ifndef BSSL_PKI_TRUST_STORE_IN_MEMORY_H_
16 #define BSSL_PKI_TRUST_STORE_IN_MEMORY_H_
17 
18 #include <set>
19 #include <unordered_map>
20 
21 #include <openssl/base.h>
22 
23 #include "trust_store.h"
24 
25 BSSL_NAMESPACE_BEGIN
26 
27 // A very simple implementation of a TrustStore, which contains a set of
28 // certificates and their trustedness.
29 class OPENSSL_EXPORT TrustStoreInMemory : public TrustStore {
30  public:
31   TrustStoreInMemory();
32 
33   TrustStoreInMemory(const TrustStoreInMemory &) = delete;
34   TrustStoreInMemory &operator=(const TrustStoreInMemory &) = delete;
35 
36   ~TrustStoreInMemory() override;
37 
38   // Returns whether the TrustStore is in the initial empty state.
39   bool IsEmpty() const;
40 
41   // Empties the trust store, resetting it to original state.
42   void Clear();
43 
44   // Adds a certificate with the specified trust settings. Both trusted and
45   // distrusted certificates require a full DER match.
46   void AddCertificate(std::shared_ptr<const ParsedCertificate> cert,
47                       const CertificateTrust &trust);
48 
49   // Adds a certificate as a trust anchor (only the SPKI and subject will be
50   // used during verification).
51   void AddTrustAnchor(std::shared_ptr<const ParsedCertificate> cert);
52 
53   // Adds a certificate as a trust anchor which will have expiration enforced.
54   // See VerifyCertificateChain for details.
55   void AddTrustAnchorWithExpiration(
56       std::shared_ptr<const ParsedCertificate> cert);
57 
58   // Adds a certificate as a trust anchor and extracts anchor constraints from
59   // the certificate. See VerifyCertificateChain for details.
60   void AddTrustAnchorWithConstraints(
61       std::shared_ptr<const ParsedCertificate> cert);
62 
63   // TODO(eroman): This is marked "ForTest" as the current implementation
64   // requires an exact match on the certificate DER (a wider match by say
65   // issuer/serial is probably what we would want for a real implementation).
66   void AddDistrustedCertificateForTest(
67       std::shared_ptr<const ParsedCertificate> cert);
68 
69   // Distrusts the provided SPKI. This will override any other trust (e.g. if a
70   // certificate is passed into AddTrustAnchor() and the certificate's SPKI is
71   // passed into AddDistrustedCertificateBySPKI(), GetTrust() will return
72   // CertificateTrust::ForDistrusted()).
73   void AddDistrustedCertificateBySPKI(std::string spki);
74 
75   // Adds a certificate to the store, that is neither trusted nor untrusted.
76   void AddCertificateWithUnspecifiedTrust(
77       std::shared_ptr<const ParsedCertificate> cert);
78 
79   // TrustStore implementation:
80   void SyncGetIssuersOf(const ParsedCertificate *cert,
81                         ParsedCertificateList *issuers) override;
82   CertificateTrust GetTrust(const ParsedCertificate *cert) override;
83 
84   // Returns true if the trust store contains the given ParsedCertificate
85   // (matches by DER).
86   bool Contains(const ParsedCertificate *cert) const;
87 
88  private:
89   struct Entry {
90     Entry();
91     Entry(const Entry &other);
92     ~Entry();
93 
94     std::shared_ptr<const ParsedCertificate> cert;
95     CertificateTrust trust;
96   };
97 
98   // Multimap from normalized subject -> Entry.
99   std::unordered_multimap<std::string_view, Entry> entries_;
100 
101   // Set of distrusted SPKIs.
102   std::set<std::string, std::less<>> distrusted_spkis_;
103 
104   // Returns the `Entry` matching `cert`, or `nullptr` if not in the trust
105   // store.
106   const Entry *GetEntry(const ParsedCertificate *cert) const;
107 };
108 
109 BSSL_NAMESPACE_END
110 
111 #endif  // BSSL_PKI_TRUST_STORE_IN_MEMORY_H_
112