1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef BSSL_PKI_TEST_HELPERS_H_
6 #define BSSL_PKI_TEST_HELPERS_H_
7
8 #include <stddef.h>
9
10 #include <ostream>
11 #include <string>
12 #include <string_view>
13 #include <vector>
14
15 #include <gtest/gtest.h>
16 #include "input.h"
17 #include "parsed_certificate.h"
18 #include "simple_path_builder_delegate.h"
19 #include "trust_store.h"
20 #include "verify_certificate_chain.h"
21
22 namespace bssl {
23
24 namespace der {
25
26 // This function is used by GTest to support EXPECT_EQ() for der::Input.
27 void PrintTo(Input data, ::std::ostream *os);
28
29 } // namespace der
30
31 // Parses |s| as a DER SEQUENCE TLV and returns a der::Input corresponding to
32 // the value portion. On error returns an empty der::Input and adds a gtest
33 // failure.
34 //
35 // The returned der::Input() is only valid so long as the input string is alive
36 // and is not mutated.
37 der::Input SequenceValueFromString(std::string_view s);
38
39 // Helper structure that maps a PEM block header (for instance "CERTIFICATE") to
40 // the destination where the value for that block should be written.
41 struct PemBlockMapping {
42 // The name of the PEM header. Example "CERTIFICATE".
43 const char *block_name;
44
45 // The destination where the read value should be written to.
46 std::string *value;
47
48 // True to indicate that the block is not required to be present. If the
49 // block is optional and is not present, then |value| will not be modified.
50 bool optional = false;
51 };
52
53 // ReadTestDataFromPemFile() is a helper function that reads a PEM test file
54 // rooted in the "src/" directory.
55 //
56 // * file_path_ascii:
57 // The path to the PEM file, relative to src. For instance
58 // "testdata/verify_signed_data_unittest/foopy.pem"
59 //
60 // * mappings:
61 // An array of length |mappings_length| which maps the expected PEM
62 // headers to the destination to write its data.
63 //
64 // The function ensures that each of the chosen mappings is satisfied exactly
65 // once. In other words, the header must be present (unless marked as
66 // optional=true), have valid data, and appear no more than once.
67 ::testing::AssertionResult ReadTestDataFromPemFile(
68 const std::string &file_path_ascii, const PemBlockMapping *mappings,
69 size_t mappings_length);
70
71 // This is the same as the variant above, however it uses template magic so an
72 // mappings array can be passed in directly (and the correct length is
73 // inferred).
74 template <size_t N>
ReadTestDataFromPemFile(const std::string & file_path_ascii,const PemBlockMapping (& mappings)[N])75 ::testing::AssertionResult ReadTestDataFromPemFile(
76 const std::string &file_path_ascii, const PemBlockMapping (&mappings)[N]) {
77 return ReadTestDataFromPemFile(file_path_ascii, mappings, N);
78 }
79
80 // Test cases are comprised of all the parameters to certificate
81 // verification, as well as the expected outputs.
82 struct VerifyCertChainTest {
83 VerifyCertChainTest();
84 ~VerifyCertChainTest();
85
86 // The chain of certificates (with the zero-th being the target).
87 ParsedCertificateList chain;
88
89 // Details on the trustedness of the last certificate.
90 CertificateTrust last_cert_trust;
91
92 // The time to use when verifying the chain.
93 der::GeneralizedTime time;
94
95 // The Key Purpose to use when verifying the chain.
96 KeyPurpose key_purpose = KeyPurpose::ANY_EKU;
97
98 InitialExplicitPolicy initial_explicit_policy = InitialExplicitPolicy::kFalse;
99
100 std::set<der::Input> user_initial_policy_set;
101
102 InitialPolicyMappingInhibit initial_policy_mapping_inhibit =
103 InitialPolicyMappingInhibit::kFalse;
104
105 InitialAnyPolicyInhibit initial_any_policy_inhibit =
106 InitialAnyPolicyInhibit::kFalse;
107
108 // The expected errors/warnings from verification (as a string).
109 std::string expected_errors;
110
111 // Expected user_constrained_policy_set, as a set of numeric OID strings.
112 std::set<std::string> expected_user_constrained_policy_set;
113
114 SimplePathBuilderDelegate::DigestPolicy digest_policy =
115 SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1;
116
117 // Returns true if |expected_errors| contains any high severity errors (a
118 // non-empty expected_errors doesn't necessarily mean verification is
119 // expected to fail, as it may have contained warnings).
120 bool HasHighSeverityErrors() const;
121 };
122
123 // Reads a test case from |file_path_ascii| (which is relative to //src).
124 // Generally |file_path_ascii| will start with:
125 // net/data/verify_certificate_chain_unittest/
126 bool ReadVerifyCertChainTestFromFile(const std::string &file_path_ascii,
127 VerifyCertChainTest *test);
128
129 // Reads a certificate chain from |file_path_ascii|
130 bool ReadCertChainFromFile(const std::string &file_path_ascii,
131 ParsedCertificateList *chain);
132
133 // Reads a certificate from |file_path_ascii|. Returns nullptr if the file
134 // contained more that one certificate.
135 std::shared_ptr<const ParsedCertificate> ReadCertFromFile(
136 const std::string &file_path_ascii);
137
138 // Reads a data file relative to the src root directory.
139 std::string ReadTestFileToString(const std::string &file_path_ascii);
140
141 // Asserts that |actual_errors| matches |expected_errors_str|.
142 //
143 // This is a helper function to simplify rebasing the error expectations when
144 // they originate from a test file.
145 void VerifyCertPathErrors(const std::string &expected_errors_str,
146 const CertPathErrors &actual_errors,
147 const ParsedCertificateList &chain,
148 const std::string &errors_file_path);
149
150 // Asserts that |actual_errors| matches |expected_errors_str|.
151 //
152 // This is a helper function to simplify rebasing the error expectations when
153 // they originate from a test file.
154 void VerifyCertErrors(const std::string &expected_errors_str,
155 const CertErrors &actual_errors,
156 const std::string &errors_file_path);
157
158 // Asserts that |actual_user_constrained_policy_set| matches
159 // |expected_user_constrained_policy_set|.
160 void VerifyUserConstrainedPolicySet(
161 const std::set<std::string> &expected_user_constrained_policy_str_set,
162 const std::set<der::Input> &actual_user_constrained_policy_set,
163 const std::string &errors_file_path);
164
165 } // namespace bssl
166
167 #endif // BSSL_PKI_TEST_HELPERS_H_
168