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