OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/internal/test_helpers.h" | 5 #include "net/cert/internal/test_helpers.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/base_paths.h" | 8 #include "base/base_paths.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
11 #include "net/cert/pem_tokenizer.h" | 11 #include "net/cert/pem_tokenizer.h" |
12 #include "net/der/parser.h" | 12 #include "net/der/parser.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
14 | 14 |
15 namespace net { | 15 namespace net { |
16 | 16 |
| 17 namespace { |
| 18 |
| 19 // Reads a data file from the unit-test data. |
| 20 ::testing::AssertionResult ReadTestFileToString( |
| 21 const std::string& file_path_ascii, |
| 22 std::string* out_file_data) { |
| 23 // Compute the full path, relative to the src/ directory. |
| 24 base::FilePath src_root; |
| 25 PathService::Get(base::DIR_SOURCE_ROOT, &src_root); |
| 26 base::FilePath filepath = src_root.AppendASCII(file_path_ascii); |
| 27 |
| 28 // Read the full contents of the file. |
| 29 if (!base::ReadFileToString(filepath, out_file_data)) { |
| 30 return ::testing::AssertionFailure() << "Couldn't read file: " |
| 31 << filepath.value(); |
| 32 } |
| 33 |
| 34 return ::testing::AssertionSuccess(); |
| 35 } |
| 36 |
| 37 } // namespace |
| 38 |
17 namespace der { | 39 namespace der { |
18 | 40 |
19 void PrintTo(const Input& data, ::std::ostream* os) { | 41 void PrintTo(const Input& data, ::std::ostream* os) { |
20 std::string b64; | 42 std::string b64; |
21 base::Base64Encode( | 43 base::Base64Encode( |
22 base::StringPiece(reinterpret_cast<const char*>(data.UnsafeData()), | 44 base::StringPiece(reinterpret_cast<const char*>(data.UnsafeData()), |
23 data.Length()), | 45 data.Length()), |
24 &b64); | 46 &b64); |
25 | 47 |
26 *os << "[" << b64 << "]"; | 48 *os << "[" << b64 << "]"; |
(...skipping 12 matching lines...) Expand all Loading... |
39 ADD_FAILURE(); | 61 ADD_FAILURE(); |
40 return der::Input(); | 62 return der::Input(); |
41 } | 63 } |
42 return data; | 64 return data; |
43 } | 65 } |
44 | 66 |
45 ::testing::AssertionResult ReadTestDataFromPemFile( | 67 ::testing::AssertionResult ReadTestDataFromPemFile( |
46 const std::string& file_path_ascii, | 68 const std::string& file_path_ascii, |
47 const PemBlockMapping* mappings, | 69 const PemBlockMapping* mappings, |
48 size_t mappings_length) { | 70 size_t mappings_length) { |
49 // Compute the full path, relative to the src/ directory. | |
50 base::FilePath src_root; | |
51 PathService::Get(base::DIR_SOURCE_ROOT, &src_root); | |
52 base::FilePath filepath = src_root.AppendASCII(file_path_ascii); | |
53 | |
54 // Read the full contents of the PEM file. | |
55 std::string file_data; | 71 std::string file_data; |
56 if (!base::ReadFileToString(filepath, &file_data)) { | 72 ::testing::AssertionResult r = |
57 return ::testing::AssertionFailure() << "Couldn't read file: " | 73 ReadTestFileToString(file_path_ascii, &file_data); |
58 << filepath.value(); | 74 if (!r) |
59 } | 75 return r; |
60 | 76 |
61 // mappings_copy is used to keep track of which mappings have already been | 77 // mappings_copy is used to keep track of which mappings have already been |
62 // satisfied (by nulling the |value| field). This is used to track when | 78 // satisfied (by nulling the |value| field). This is used to track when |
63 // blocks are mulitply defined. | 79 // blocks are mulitply defined. |
64 std::vector<PemBlockMapping> mappings_copy(mappings, | 80 std::vector<PemBlockMapping> mappings_copy(mappings, |
65 mappings + mappings_length); | 81 mappings + mappings_length); |
66 | 82 |
67 // Build the |pem_headers| vector needed for PEMTokenzier. | 83 // Build the |pem_headers| vector needed for PEMTokenzier. |
68 std::vector<std::string> pem_headers; | 84 std::vector<std::string> pem_headers; |
69 for (const auto& mapping : mappings_copy) { | 85 for (const auto& mapping : mappings_copy) { |
(...skipping 23 matching lines...) Expand all Loading... |
93 for (const auto& mapping : mappings_copy) { | 109 for (const auto& mapping : mappings_copy) { |
94 if (mapping.value && !mapping.optional) { | 110 if (mapping.value && !mapping.optional) { |
95 return ::testing::AssertionFailure() << "PEM block missing: " | 111 return ::testing::AssertionFailure() << "PEM block missing: " |
96 << mapping.block_name; | 112 << mapping.block_name; |
97 } | 113 } |
98 } | 114 } |
99 | 115 |
100 return ::testing::AssertionSuccess(); | 116 return ::testing::AssertionSuccess(); |
101 } | 117 } |
102 | 118 |
| 119 // Reads a test case from |file_name|. Test cases are comprised of a |
| 120 // certificate chain, trust store, a timestamp to validate at, and the |
| 121 // expected result of verification. |
| 122 void ReadCertChainTestFromFile(const std::string& file_path_ascii, |
| 123 ParsedCertificateList* chain, |
| 124 ParsedCertificateList* roots, |
| 125 der::GeneralizedTime* time, |
| 126 bool* verify_result) { |
| 127 chain->clear(); |
| 128 roots->clear(); |
| 129 |
| 130 std::string file_data; |
| 131 ASSERT_TRUE(ReadTestFileToString(file_path_ascii, &file_data)); |
| 132 |
| 133 std::vector<std::string> pem_headers; |
| 134 |
| 135 const char kCertificateHeader[] = "CERTIFICATE"; |
| 136 const char kTrustedCertificateHeader[] = "TRUSTED_CERTIFICATE"; |
| 137 const char kTimeHeader[] = "TIME"; |
| 138 const char kResultHeader[] = "VERIFY_RESULT"; |
| 139 |
| 140 pem_headers.push_back(kCertificateHeader); |
| 141 pem_headers.push_back(kTrustedCertificateHeader); |
| 142 pem_headers.push_back(kTimeHeader); |
| 143 pem_headers.push_back(kResultHeader); |
| 144 |
| 145 bool has_time = false; |
| 146 bool has_result = false; |
| 147 |
| 148 PEMTokenizer pem_tokenizer(file_data, pem_headers); |
| 149 while (pem_tokenizer.GetNext()) { |
| 150 const std::string& block_type = pem_tokenizer.block_type(); |
| 151 const std::string& block_data = pem_tokenizer.data(); |
| 152 |
| 153 if (block_type == kCertificateHeader) { |
| 154 ASSERT_TRUE(net::ParsedCertificate::CreateAndAddToVector( |
| 155 reinterpret_cast<const uint8_t*>(block_data.data()), |
| 156 block_data.size(), net::ParsedCertificate::DataSource::INTERNAL_COPY, |
| 157 {}, chain)); |
| 158 } else if (block_type == kTrustedCertificateHeader) { |
| 159 ASSERT_TRUE(net::ParsedCertificate::CreateAndAddToVector( |
| 160 reinterpret_cast<const uint8_t*>(block_data.data()), |
| 161 block_data.size(), net::ParsedCertificate::DataSource::INTERNAL_COPY, |
| 162 {}, roots)); |
| 163 } else if (block_type == kTimeHeader) { |
| 164 ASSERT_FALSE(has_time) << "Duplicate " << kTimeHeader; |
| 165 has_time = true; |
| 166 ASSERT_TRUE(der::ParseUTCTime(der::Input(&block_data), time)); |
| 167 } else if (block_type == kResultHeader) { |
| 168 ASSERT_FALSE(has_result) << "Duplicate " << kResultHeader; |
| 169 ASSERT_TRUE(block_data == "SUCCESS" || block_data == "FAIL") |
| 170 << "Unrecognized result: " << block_data; |
| 171 has_result = true; |
| 172 *verify_result = block_data == "SUCCESS"; |
| 173 } |
| 174 } |
| 175 |
| 176 ASSERT_TRUE(has_time); |
| 177 ASSERT_TRUE(has_result); |
| 178 } |
| 179 |
103 } // namespace net | 180 } // namespace net |
OLD | NEW |