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