| 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 |