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