Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Unified Diff: net/cert/internal/test_helpers.cc

Issue 2805213004: Refactor how net/data/verify_certificate_chain_unittest/* (Closed)
Patch Set: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/cert/internal/test_helpers.cc
diff --git a/net/cert/internal/test_helpers.cc b/net/cert/internal/test_helpers.cc
index ab8ed5510949b2a4f5496c06ca4d451f8ae86521..ccd4387e6e7aef390370c6a876ed878152e67122 100644
--- a/net/cert/internal/test_helpers.cc
+++ b/net/cert/internal/test_helpers.cc
@@ -8,6 +8,7 @@
#include "base/base_paths.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
+#include "base/strings/string_split.h"
#include "net/cert/internal/cert_errors.h"
#include "net/cert/pem_tokenizer.h"
#include "net/der/parser.h"
@@ -16,6 +17,27 @@
namespace net {
+namespace {
+
+bool GetValue(base::StringPiece prefix,
+ base::StringPiece line,
+ std::string* value,
+ bool* has_value) {
+ if (!line.starts_with(prefix))
+ return false;
+
+ if (*has_value) {
+ ADD_FAILURE() << "Duplicated " << prefix;
+ return false;
+ }
+
+ *has_value = true;
+ *value = line.substr(prefix.size()).as_string();
+ return true;
+}
+
+} // namespace
+
namespace der {
void PrintTo(const Input& data, ::std::ostream* os) {
@@ -56,8 +78,8 @@ der::Input SequenceValueFromString(const std::string* s) {
// Read the full contents of the PEM file.
std::string file_data;
if (!base::ReadFileToString(filepath, &file_data)) {
- return ::testing::AssertionFailure() << "Couldn't read file: "
- << filepath.value();
+ return ::testing::AssertionFailure()
+ << "Couldn't read file: " << filepath.value();
}
// mappings_copy is used to keep track of which mappings have already been
@@ -94,8 +116,8 @@ der::Input SequenceValueFromString(const std::string* s) {
// Ensure that all specified blocks were found.
for (const auto& mapping : mappings_copy) {
if (mapping.value && !mapping.optional) {
- return ::testing::AssertionFailure() << "PEM block missing: "
- << mapping.block_name;
+ return ::testing::AssertionFailure()
+ << "PEM block missing: " << mapping.block_name;
}
}
@@ -105,103 +127,135 @@ der::Input SequenceValueFromString(const std::string* s) {
VerifyCertChainTest::VerifyCertChainTest() = default;
VerifyCertChainTest::~VerifyCertChainTest() = default;
-void ReadVerifyCertChainTestFromFile(const std::string& file_path_ascii,
+bool ReadCertChainFromFile(const std::string& file_path_ascii,
+ ParsedCertificateList* chain) {
+ // Reset all the out parameters to their defaults.
+ *chain = ParsedCertificateList();
+
+ std::string file_data = ReadTestFileToString(file_path_ascii);
+ if (file_data.empty())
+ return false;
+
+ std::vector<std::string> pem_headers = {"CERTIFICATE"};
+
+ PEMTokenizer pem_tokenizer(file_data, pem_headers);
+ while (pem_tokenizer.GetNext()) {
+ const std::string& block_data = pem_tokenizer.data();
+
+ CertErrors errors;
+ if (!net::ParsedCertificate::CreateAndAddToVector(
+ bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
+ reinterpret_cast<const uint8_t*>(block_data.data()),
+ block_data.size(), nullptr)),
+ {}, chain, &errors)) {
+ ADD_FAILURE() << errors.ToDebugString();
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ReadVerifyCertChainTestFromFile(const std::string& file_path_ascii,
VerifyCertChainTest* test) {
// Reset all the out parameters to their defaults.
*test = {};
std::string file_data = ReadTestFileToString(file_path_ascii);
+ if (file_data.empty())
+ return false;
- std::vector<std::string> pem_headers;
-
- // For details on the file format refer to:
- // net/data/verify_certificate_chain_unittest/README.
- const char kCertificateHeader[] = "CERTIFICATE";
- const char kTrustAnchorUnconstrained[] = "TRUST_ANCHOR_UNCONSTRAINED";
- const char kTrustAnchorConstrained[] = "TRUST_ANCHOR_CONSTRAINED";
- const char kTimeHeader[] = "TIME";
- const char kResultHeader[] = "VERIFY_RESULT";
- const char kErrorsHeader[] = "ERRORS";
- const char kKeyPurpose[] = "KEY_PURPOSE";
-
- pem_headers.push_back(kCertificateHeader);
- pem_headers.push_back(kTrustAnchorUnconstrained);
- pem_headers.push_back(kTrustAnchorConstrained);
- pem_headers.push_back(kTimeHeader);
- pem_headers.push_back(kResultHeader);
- pem_headers.push_back(kErrorsHeader);
- pem_headers.push_back(kKeyPurpose);
+ std::vector<std::string> lines = base::SplitString(
+ file_data, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ bool has_chain = false;
+ bool has_trust = false;
bool has_time = false;
- bool has_result = false;
bool has_errors = false;
bool has_key_purpose = false;
- bool has_trust_anchor = false;
- PEMTokenizer pem_tokenizer(file_data, pem_headers);
- while (pem_tokenizer.GetNext()) {
- const std::string& block_type = pem_tokenizer.block_type();
- const std::string& block_data = pem_tokenizer.data();
+ for (const std::string& line : lines) {
+ base::StringPiece line_piece(line);
- if (block_type == kCertificateHeader) {
- ASSERT_FALSE(has_trust_anchor) << "Trust anchor must appear last";
- CertErrors errors;
- ASSERT_TRUE(net::ParsedCertificate::CreateAndAddToVector(
- bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
- reinterpret_cast<const uint8_t*>(block_data.data()),
- block_data.size(), nullptr)),
- {}, &test->chain, &errors))
- << errors.ToDebugString();
- } else if (block_type == kTrustAnchorUnconstrained ||
- block_type == kTrustAnchorConstrained) {
- ASSERT_FALSE(has_trust_anchor) << "Duplicate trust anchor";
- CertErrors errors;
- scoped_refptr<ParsedCertificate> root = net::ParsedCertificate::Create(
- bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
- reinterpret_cast<const uint8_t*>(block_data.data()),
- block_data.size(), nullptr)),
- {}, &errors);
- ASSERT_TRUE(root) << errors.ToDebugString();
- test->chain.push_back(std::move(root));
- test->last_cert_trust =
- (block_type == kTrustAnchorUnconstrained)
- ? CertificateTrust::ForTrustAnchor()
- : CertificateTrust::ForTrustAnchorEnforcingConstraints();
- has_trust_anchor = true;
- } else if (block_type == kTimeHeader) {
- ASSERT_FALSE(has_time) << "Duplicate " << kTimeHeader;
- has_time = true;
- ASSERT_TRUE(der::ParseUTCTime(der::Input(&block_data), &test->time));
- } else if (block_type == kKeyPurpose) {
- ASSERT_FALSE(has_key_purpose) << "Duplicate " << kKeyPurpose;
- has_key_purpose = true;
-
- if (block_data == "anyExtendedKeyUsage") {
+ std::string value;
+
+ // For details on the file format refer to:
+ // net/data/verify_certificate_chain_unittest/README.
+ if (GetValue("chain: ", line_piece, &value, &has_chain)) {
+ std::string chain_path = file_path_ascii;
mattm 2017/05/02 06:43:46 initialized value here isn't used.
eroman 2017/05/02 19:20:23 Done.
+ size_t slash = file_path_ascii.rfind('/');
+ if (slash == std::string::npos) {
+ ADD_FAILURE() << "Bad path - expecting slashes";
+ return false;
+ }
+ chain_path = file_path_ascii.substr(0, slash) + "/" + value;
+
+ ReadCertChainFromFile(chain_path, &test->chain);
+ } else if (GetValue("utc_time: ", line_piece, &value, &has_time)) {
+ if (!der::ParseUTCTime(der::Input(&value), &test->time)) {
+ ADD_FAILURE() << "Failed parsing UTC time";
+ return false;
+ }
+ } else if (GetValue("key_purpose: ", line_piece, &value,
+ &has_key_purpose)) {
+ if (value == "anyExtendedKeyUsage") {
test->key_purpose = KeyPurpose::ANY_EKU;
- } else if (block_data == "serverAuth") {
+ } else if (value == "serverAuth") {
test->key_purpose = KeyPurpose::SERVER_AUTH;
- } else if (block_data == "clientAuth") {
+ } else if (value == "clientAuth") {
test->key_purpose = KeyPurpose::CLIENT_AUTH;
} else {
- ADD_FAILURE() << "Unrecognized " << block_type << ": " << block_data;
+ ADD_FAILURE() << "Unrecognized key_purpose: " << value;
+ return false;
+ }
+ } else if (GetValue("last_cert_trust: ", line_piece, &value, &has_trust)) {
+ if (value == "trustAnchor") {
+ test->last_cert_trust = CertificateTrust::ForTrustAnchor();
+ } else if (value == "trustAnchor (enforcesConstraints)") {
+ test->last_cert_trust =
+ CertificateTrust::ForTrustAnchorEnforcingConstraints();
+ } else if (value == "distrusted") {
+ test->last_cert_trust = CertificateTrust::ForDistrusted();
+ } else if (value == "unspecified") {
+ test->last_cert_trust = CertificateTrust::ForUnspecified();
+ } else {
+ ADD_FAILURE() << "Unrecognized last_cert_trust: " << value;
+ return false;
+ }
+ } else if (GetValue("expected_errors:", line_piece, &value, &has_errors)) {
+ // The errors start on the next line, and extend until the end of the
+ // file.
+ size_t errors_start = file_data.find("\nexpected_errors:\n");
+ if (errors_start == std::string::npos) {
+ ADD_FAILURE() << "expected_errors not found";
+ return false;
}
- } else if (block_type == kResultHeader) {
- ASSERT_FALSE(has_result) << "Duplicate " << kResultHeader;
- ASSERT_TRUE(block_data == "SUCCESS" || block_data == "FAIL")
- << "Unrecognized result: " << block_data;
- has_result = true;
- test->expected_result = block_data == "SUCCESS";
- } else if (block_type == kErrorsHeader) {
- ASSERT_FALSE(has_errors) << "Duplicate " << kErrorsHeader;
- has_errors = true;
- test->expected_errors = block_data;
+ test->expected_errors = file_data.substr(errors_start + 18);
mattm 2017/05/02 06:43:46 I guess "\nexpected_errors:\n" could be a constant
eroman 2017/05/02 19:20:23 Done.
+ break;
}
mattm 2017/05/02 06:43:46 should it error on unrecognized lines?
eroman 2017/05/02 19:20:23 Done.
}
- ASSERT_TRUE(has_time);
- ASSERT_TRUE(has_result);
- ASSERT_TRUE(has_trust_anchor);
- ASSERT_TRUE(has_key_purpose);
+ if (!has_chain) {
+ ADD_FAILURE() << "Missing chain: ";
+ return false;
+ }
+
+ if (!has_trust) {
+ ADD_FAILURE() << "Missing last_cert_trust: ";
+ return false;
+ }
+
+ if (!has_time) {
+ ADD_FAILURE() << "Missing time: ";
+ return false;
+ }
+
+ if (!has_key_purpose) {
+ ADD_FAILURE() << "Missing key_purpose: ";
+ return false;
+ }
+
+ return true;
}
std::string ReadTestFileToString(const std::string& file_path_ascii) {

Powered by Google App Engine
This is Rietveld 408576698