• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BSSL_VERIFY_H_
2 #define BSSL_VERIFY_H_
3 
4 #include <chrono>
5 #include <optional>
6 #include <string>
7 #include <string_view>
8 #include <vector>
9 
10 #include <openssl/pki/signature_verify_cache.h>
11 #include <openssl/pki/verify_error.h>
12 
13 BSSL_NAMESPACE_BEGIN
14 
15 class CertIssuerSourceStatic;
16 class TrustStoreInMemory;
17 class CertificateVerifyOptions;
18 class CertificateVerifyStatus;
19 
20 class OPENSSL_EXPORT VerifyTrustStore {
21  public:
22   std::unique_ptr<TrustStoreInMemory> trust_store;
23 
24   ~VerifyTrustStore();
25 
26   // FromDER returns a |TrustStore| derived from interpreting the |der_certs| as
27   // a bunch of DER-encoded certs, concatenated. In the event of a failure nullptr
28   // e is returned and a diagnostic string is placed in |out_diagnostic|
29   static std::unique_ptr<VerifyTrustStore> FromDER(
30       std::string_view der_certs, std::string *out_diagnostic);
31 
32   // FromDER returns a |TrustStore| consisting of the supplied DER-encoded
33   // certs in |der_certs|. In the event of a failure nullptr is returned and a
34   // diagnostic string is placed in |out_diagnostic|
35   static std::unique_ptr<VerifyTrustStore> FromDER(
36       const std::vector<std::string_view> &der_certs,
37       std::string *out_diagnostic);
38 };
39 
40 class OPENSSL_EXPORT CertPool {
41  public:
42   CertPool();
43   CertPool(const CertPool &) = delete;
44   CertPool &operator=(const CertPool &) = delete;
45   virtual ~CertPool();
46 
47   // FromCerts returns a |CertPool| consisting of the supplied DER-encoded
48   // certs in |der_certs|. In the event of a failure nullptr is returned and a
49   // diagnostic string is placed in |out_diagnostic|
50   static std::unique_ptr<CertPool> FromCerts(
51       const std::vector<std::string_view> &der_certs,
52       std::string *out_diagnostic);
53 
54  private:
55   friend std::optional<std::vector<std::vector<std::string>>>
56   CertificateVerifyInternal(const CertificateVerifyOptions &opts,
57                             VerifyError *out_error,
58                             CertificateVerifyStatus *out_status,
59                             bool all_paths);
60   std::unique_ptr<CertIssuerSourceStatic> impl_;
61 };
62 
63 // CertificateVerifyOptions contains all the options for a certificate verification.
64 class OPENSSL_EXPORT CertificateVerifyOptions {
65  public:
66   // The key purpose (extended key usage) to check for during verification.
67   enum class KeyPurpose {
68     ANY_EKU,
69     SERVER_AUTH,
70     CLIENT_AUTH,
71     SERVER_AUTH_STRICT,
72     CLIENT_AUTH_STRICT,
73     SERVER_AUTH_STRICT_LEAF,
74     CLIENT_AUTH_STRICT_LEAF,
75   };
76 
77   CertificateVerifyOptions();
78   CertificateVerifyOptions(const CertificateVerifyOptions &) = delete;
79   CertificateVerifyOptions &operator=(const CertificateVerifyOptions &) =
80       delete;
81 
82   KeyPurpose key_purpose = KeyPurpose::SERVER_AUTH;
83   std::string_view leaf_cert;
84   std::vector<std::string_view> intermediates;
85 
86   // extra_intermediates optionally points to a pool of common intermediates.
87   const CertPool *extra_intermediates = nullptr;
88   // trust_store points to the set of root certificates to trust.
89   const VerifyTrustStore *trust_store = nullptr;
90   // min_rsa_modulus_length is the minimum acceptable RSA key size in a chain.
91   size_t min_rsa_modulus_length = 1024;
92   // time is the time in POSIX seconds since the POSIX epoch at which to
93   // validate the chain. It defaults to the current time if not set.
94   std::optional<int64_t> time;
95   // insecurely_allow_sha1 allows verification of signatures that use SHA-1
96   // message digests.  This option is insecure and should not be used.
97   bool insecurely_allow_sha1 = false;
98 
99   // max_iteration_count, if not zero, limits the number of times path building
100   // will try to append an intermediate to a potential path. This bounds the
101   // amount of time that a verification attempt can take, at the risk of
102   // rejecting cases that would be solved if only more effort were used.
103   uint32_t max_iteration_count = 0;
104 
105   // Sets an optional deadline for completing path building. It defaults
106   // to std::chrono::time_point::max() if it not set. If |deadline| has a
107   // value that has passed based on comparison to
108   // std::chrono::steady_clock::now(), and path building has not completed,
109   // path building will stop. Note that this is not a hard limit, there is no
110   // guarantee how far past |deadline| time will be when path building is
111   // aborted.
112   std::optional<std::chrono::time_point<std::chrono::steady_clock>> deadline;
113 
114   // max_path_building_depth, if not zero, limits the depth of the path that the
115   // path building algorithm attempts to build between leafs and roots. Using
116   // this comes at the risk of rejecting cases that would be solved if only one
117   // more certificate is added to the path.
118   uint32_t max_path_building_depth = 0;
119 
120   // signature_verify_cache, if not nullptr, points to an object implementing a
121   // signature verification cache derived from
122   // <openssl/pki/signature_verify_cache.h>
123   SignatureVerifyCache *signature_verify_cache = nullptr;
124 };
125 
126 // CertificateVerifyStatus describes the status of a certificate verification
127 // attempt.
128 class OPENSSL_EXPORT CertificateVerifyStatus {
129  public:
130   CertificateVerifyStatus();
131 
132   // IterationCount returns the total number of attempted certificate additions
133   // to any potential path while performing path building for verification. It
134   // is the same value which may be bound by max_iteration_count in
135   // CertificateVerifyOptions.
136   size_t IterationCount() const;
137 
138   // MaxDepthSeen returns the maximum path depth seen during path building.
139   size_t MaxDepthSeen() const;
140 
141  private:
142   friend std::optional<std::vector<std::vector<std::string>>>
143   CertificateVerifyInternal(const CertificateVerifyOptions &opts,
144                             VerifyError *out_error,
145                             CertificateVerifyStatus *out_status,
146                             bool all_paths);
147   size_t iteration_count_ = 0;
148   size_t max_depth_seen_ = 0;
149 };
150 
151 // Verify verifies |opts.leaf_cert| using the other values in |opts|. It
152 // returns either an error, or else a validated chain from leaf to root.
153 //
154 // In the event of an error return, |out_error| will be updated with information
155 // about the error.  It may be |nullptr|.
156 //
157 // Status information about the verification will be returned in |out_status|.
158 // It may be |nullptr|.
159 OPENSSL_EXPORT std::optional<std::vector<std::string>> CertificateVerify(
160     const CertificateVerifyOptions &opts, VerifyError *out_error = nullptr,
161     CertificateVerifyStatus *out_status = nullptr);
162 
163 // VerifyAllPaths verifies |opts.leaf_cert| using the other values in |opts|,
164 // and returns all possible valid chains from the leaf to a root. If no chains
165 // exist, it returns an error.
166 OPENSSL_EXPORT std::optional<std::vector<std::vector<std::string>>>
167 CertificateVerifyAllPaths(const CertificateVerifyOptions &opts);
168 
169 BSSL_NAMESPACE_END
170 
171 #endif  // BSSL_VERIFY_H_
172