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 "parsed_certificate.h"
16 #include "simple_path_builder_delegate.h"
17 #include "trust_store.h"
18 #include "verify_certificate_chain.h"
19 #include "input.h"
20 #include <gtest/gtest.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(const 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,
69 const PemBlockMapping* mappings,
70 size_t mappings_length);
71
72 // This is the same as the variant above, however it uses template magic so an
73 // mappings array can be passed in directly (and the correct length is
74 // inferred).
75 template <size_t N>
ReadTestDataFromPemFile(const std::string & file_path_ascii,const PemBlockMapping (& mappings)[N])76 ::testing::AssertionResult ReadTestDataFromPemFile(
77 const std::string& file_path_ascii,
78 const PemBlockMapping (&mappings)[N]) {
79 return ReadTestDataFromPemFile(file_path_ascii, mappings, N);
80 }
81
82 // Test cases are comprised of all the parameters to certificate
83 // verification, as well as the expected outputs.
84 struct VerifyCertChainTest {
85 VerifyCertChainTest();
86 ~VerifyCertChainTest();
87
88 // The chain of certificates (with the zero-th being the target).
89 ParsedCertificateList chain;
90
91 // Details on the trustedness of the last certificate.
92 CertificateTrust last_cert_trust;
93
94 // The time to use when verifying the chain.
95 der::GeneralizedTime time;
96
97 // The Key Purpose to use when verifying the chain.
98 KeyPurpose key_purpose = KeyPurpose::ANY_EKU;
99
100 InitialExplicitPolicy initial_explicit_policy = InitialExplicitPolicy::kFalse;
101
102 std::set<der::Input> user_initial_policy_set;
103
104 InitialPolicyMappingInhibit initial_policy_mapping_inhibit =
105 InitialPolicyMappingInhibit::kFalse;
106
107 InitialAnyPolicyInhibit initial_any_policy_inhibit =
108 InitialAnyPolicyInhibit::kFalse;
109
110 // The expected errors/warnings from verification (as a string).
111 std::string expected_errors;
112
113 // Expected user_constrained_policy_set, as a set of numeric OID strings.
114 std::set<std::string> expected_user_constrained_policy_set;
115
116 SimplePathBuilderDelegate::DigestPolicy digest_policy =
117 SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1;
118
119 // Returns true if |expected_errors| contains any high severity errors (a
120 // non-empty expected_errors doesn't necessarily mean verification is
121 // expected to fail, as it may have contained warnings).
122 bool HasHighSeverityErrors() const;
123 };
124
125 // Reads a test case from |file_path_ascii| (which is relative to //src).
126 // Generally |file_path_ascii| will start with:
127 // net/data/verify_certificate_chain_unittest/
128 bool ReadVerifyCertChainTestFromFile(const std::string& file_path_ascii,
129 VerifyCertChainTest* test);
130
131 // Reads a certificate chain from |file_path_ascii|
132 bool ReadCertChainFromFile(const std::string& file_path_ascii,
133 ParsedCertificateList* chain);
134
135 // Reads a certificate from |file_path_ascii|. Returns nullptr if the file
136 // contained more that one certificate.
137 std::shared_ptr<const ParsedCertificate> ReadCertFromFile(
138 const std::string& file_path_ascii);
139
140 // Reads a data file relative to the src root directory.
141 std::string ReadTestFileToString(const std::string& file_path_ascii);
142
143 // Asserts that |actual_errors| matches |expected_errors_str|.
144 //
145 // This is a helper function to simplify rebasing the error expectations when
146 // they originate from a test file.
147 void VerifyCertPathErrors(const std::string& expected_errors_str,
148 const CertPathErrors& actual_errors,
149 const ParsedCertificateList& chain,
150 const std::string& errors_file_path);
151
152 // Asserts that |actual_errors| matches |expected_errors_str|.
153 //
154 // This is a helper function to simplify rebasing the error expectations when
155 // they originate from a test file.
156 void VerifyCertErrors(const std::string& expected_errors_str,
157 const CertErrors& actual_errors,
158 const std::string& errors_file_path);
159
160 // Asserts that |actual_user_constrained_policy_set| matches
161 // |expected_user_constrained_policy_set|.
162 void VerifyUserConstrainedPolicySet(
163 const std::set<std::string>& expected_user_constrained_policy_str_set,
164 const std::set<der::Input>& actual_user_constrained_policy_set,
165 const std::string& errors_file_path);
166
167 } // namespace net
168
169 #endif // BSSL_PKI_TEST_HELPERS_H_
170