| // Copyright 2015 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef BSSL_PKI_TEST_HELPERS_H_ |
| #define BSSL_PKI_TEST_HELPERS_H_ |
| |
| #include <stddef.h> |
| |
| #include <ostream> |
| #include <string> |
| #include <string_view> |
| #include <vector> |
| |
| #include <gtest/gtest.h> |
| #include "input.h" |
| #include "parsed_certificate.h" |
| #include "simple_path_builder_delegate.h" |
| #include "trust_store.h" |
| #include "verify_certificate_chain.h" |
| |
| BSSL_NAMESPACE_BEGIN |
| |
| namespace der { |
| |
| // This function is used by GTest to support EXPECT_EQ() for der::Input. |
| void PrintTo(Input data, ::std::ostream *os); |
| |
| } // namespace der |
| |
| // Parses |s| as a DER SEQUENCE TLV and returns a der::Input corresponding to |
| // the value portion. On error returns an empty der::Input and adds a gtest |
| // failure. |
| // |
| // The returned der::Input() is only valid so long as the input string is alive |
| // and is not mutated. |
| der::Input SequenceValueFromString(std::string_view s); |
| |
| // Helper structure that maps a PEM block header (for instance "CERTIFICATE") to |
| // the destination where the value for that block should be written. |
| struct PemBlockMapping { |
| // The name of the PEM header. Example "CERTIFICATE". |
| const char *block_name; |
| |
| // The destination where the read value should be written to. |
| std::string *value; |
| |
| // True to indicate that the block is not required to be present. If the |
| // block is optional and is not present, then |value| will not be modified. |
| bool optional = false; |
| }; |
| |
| // ReadTestDataFromPemFile() is a helper function that reads a PEM test file |
| // rooted in the "src/" directory. |
| // |
| // * file_path_ascii: |
| // The path to the PEM file, relative to src. For instance |
| // "testdata/verify_signed_data_unittest/foopy.pem" |
| // |
| // * mappings: |
| // An array of length |mappings_length| which maps the expected PEM |
| // headers to the destination to write its data. |
| // |
| // The function ensures that each of the chosen mappings is satisfied exactly |
| // once. In other words, the header must be present (unless marked as |
| // optional=true), have valid data, and appear no more than once. |
| ::testing::AssertionResult ReadTestDataFromPemFile( |
| const std::string &file_path_ascii, const PemBlockMapping *mappings, |
| size_t mappings_length); |
| |
| // This is the same as the variant above, however it uses template magic so an |
| // mappings array can be passed in directly (and the correct length is |
| // inferred). |
| template <size_t N> |
| ::testing::AssertionResult ReadTestDataFromPemFile( |
| const std::string &file_path_ascii, const PemBlockMapping (&mappings)[N]) { |
| return ReadTestDataFromPemFile(file_path_ascii, mappings, N); |
| } |
| |
| // Test cases are comprised of all the parameters to certificate |
| // verification, as well as the expected outputs. |
| struct VerifyCertChainTest { |
| VerifyCertChainTest(); |
| ~VerifyCertChainTest(); |
| |
| // The chain of certificates (with the zero-th being the target). |
| ParsedCertificateList chain; |
| |
| // Details on the trustedness of the last certificate. |
| CertificateTrust last_cert_trust; |
| |
| // The time to use when verifying the chain. |
| der::GeneralizedTime time; |
| |
| // The Key Purpose to use when verifying the chain. |
| KeyPurpose key_purpose = KeyPurpose::ANY_EKU; |
| |
| InitialExplicitPolicy initial_explicit_policy = InitialExplicitPolicy::kFalse; |
| |
| std::set<der::Input> user_initial_policy_set; |
| |
| InitialPolicyMappingInhibit initial_policy_mapping_inhibit = |
| InitialPolicyMappingInhibit::kFalse; |
| |
| InitialAnyPolicyInhibit initial_any_policy_inhibit = |
| InitialAnyPolicyInhibit::kFalse; |
| |
| // The expected errors/warnings from verification (as a string). |
| std::string expected_errors; |
| |
| // Expected user_constrained_policy_set, as a set of numeric OID strings. |
| std::set<std::string> expected_user_constrained_policy_set; |
| |
| SimplePathBuilderDelegate::DigestPolicy digest_policy = |
| SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1; |
| |
| // Returns true if |expected_errors| contains any high severity errors (a |
| // non-empty expected_errors doesn't necessarily mean verification is |
| // expected to fail, as it may have contained warnings). |
| bool HasHighSeverityErrors() const; |
| }; |
| |
| // Reads a test case from |file_path_ascii| (which is relative to //src). |
| // Generally |file_path_ascii| will start with: |
| // net/data/verify_certificate_chain_unittest/ |
| bool ReadVerifyCertChainTestFromFile(const std::string &file_path_ascii, |
| VerifyCertChainTest *test); |
| |
| // Reads a certificate chain from |file_path_ascii| |
| bool ReadCertChainFromFile(const std::string &file_path_ascii, |
| ParsedCertificateList *chain); |
| |
| // Reads a certificate from |file_path_ascii|. Returns nullptr if the file |
| // contained more that one certificate. |
| std::shared_ptr<const ParsedCertificate> ReadCertFromFile( |
| const std::string &file_path_ascii); |
| |
| // Reads a data file relative to the src root directory. |
| std::string ReadTestFileToString(const std::string &file_path_ascii); |
| |
| // Asserts that |actual_errors| matches |expected_errors_str|. |
| // |
| // This is a helper function to simplify rebasing the error expectations when |
| // they originate from a test file. |
| void VerifyCertPathErrors(const std::string &expected_errors_str, |
| const CertPathErrors &actual_errors, |
| const ParsedCertificateList &chain, |
| const std::string &errors_file_path); |
| |
| // Asserts that |actual_errors| matches |expected_errors_str|. |
| // |
| // This is a helper function to simplify rebasing the error expectations when |
| // they originate from a test file. |
| void VerifyCertErrors(const std::string &expected_errors_str, |
| const CertErrors &actual_errors, |
| const std::string &errors_file_path); |
| |
| // Asserts that |actual_user_constrained_policy_set| matches |
| // |expected_user_constrained_policy_set|. |
| void VerifyUserConstrainedPolicySet( |
| const std::set<std::string> &expected_user_constrained_policy_str_set, |
| const std::set<der::Input> &actual_user_constrained_policy_set, |
| const std::string &errors_file_path); |
| |
| BSSL_NAMESPACE_END |
| |
| #endif // BSSL_PKI_TEST_HELPERS_H_ |