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