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

Unified Diff: components/certificate_transparency/log_proof_fetcher_unittest.cc

Issue 1222953002: Certificate Transparency: Add STH Fetching capability. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simplified handling of responses per review comments Created 5 years, 5 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: components/certificate_transparency/log_proof_fetcher_unittest.cc
diff --git a/components/certificate_transparency/log_proof_fetcher_unittest.cc b/components/certificate_transparency/log_proof_fetcher_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ba44973bbcaeaed51312087b258a1522c078a545
--- /dev/null
+++ b/components/certificate_transparency/log_proof_fetcher_unittest.cc
@@ -0,0 +1,197 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/certificate_transparency/log_proof_fetcher.h"
+
+#include <string>
+
+#include "components/safe_json/testing_json_parser.h"
+#include "net/base/network_delegate.h"
+#include "net/cert/signed_tree_head.h"
+#include "net/test/ct_test_util.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_filter.h"
+#include "net/url_request/url_request_interceptor.h"
+#include "net/url_request/url_request_job.h"
+#include "net/url_request/url_request_test_job.h"
+#include "net/url_request/url_request_test_util.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace certificate_transparency {
+
+namespace {
+
+const char kGetSTHHeaders[] =
+ "HTTP/1.1 200 OK\0"
+ "Content-Type: application/json; charset=ISO-8859-1\0"
+ "\0";
+
+const char kLogSchema[] = "https";
+const char kLogURL[] = "ct.log.example.com";
+
+std::string GetLogID() {
+ return std::string("some_id");
+}
+
+class GetSTHResponseHandler : public net::URLRequestInterceptor {
+ public:
+ GetSTHResponseHandler(const std::string& headers,
+ const std::string& get_sth_data)
+ : headers_(headers), sth_data_(get_sth_data) {}
+ ~GetSTHResponseHandler() override {}
+
+ // URLRequestInterceptor implementation:
+ net::URLRequestJob* MaybeInterceptRequest(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return new net::URLRequestTestJob(request, network_delegate, headers_,
+ sth_data_, true);
+ }
+
+ private:
+ std::string headers_;
+ const std::string& sth_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(GetSTHResponseHandler);
+};
+
+class LogProofFetcherTest : public ::testing::Test {
+ public:
+ LogProofFetcherTest()
+ : context_(true),
+ log_url_(std::string(kLogSchema) + "://" + std::string(kLogURL) + "/") {
+ context_.Init();
+ }
+
+ void SetUp() override {
+ scoped_ptr<GetSTHResponseHandler> handler(
+ new GetSTHResponseHandler(kGetSTHHeaders, sth_json_reply_data_));
+
+ net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
+ kLogSchema, kLogURL, handler.Pass());
+
+ fetcher_.reset(new LogProofFetcher(&context_));
+ }
+
+ void TearDown() override {
+ net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(kLogSchema,
+ kLogURL);
+ }
+
+ protected:
+ base::MessageLoopForIO message_loop_;
+ net::TestURLRequestContext context_;
+ safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_;
+ scoped_ptr<LogProofFetcher> fetcher_;
+ std::string sth_json_reply_data_;
+ GURL log_url_;
+};
+
+class RecordFetchCallbackInvocations {
+ public:
+ RecordFetchCallbackInvocations() : invoked_(false), failed_(false) {}
+
+ virtual void STHFetched(const std::string& log_id,
+ const net::ct::SignedTreeHead& sth) {
+ invoked_ = true;
+ }
+
+ void FetchingFailed(const std::string& log_id,
+ int error_value,
+ int http_response_code) {
+ invoked_ = true;
+ failed_ = true;
+ }
+
+ bool invoked() { return invoked_; }
+
+ bool failed() { return failed_; }
+
+ private:
+ bool invoked_;
+ bool failed_;
+};
+
+class ExpectedSuccessCallback : public RecordFetchCallbackInvocations {
+ public:
+ ExpectedSuccessCallback(const net::ct::SignedTreeHead& sth)
+ : known_sth_(sth) {}
+
+ void STHFetched(const std::string& log_id,
+ const net::ct::SignedTreeHead& sth) override {
+ ASSERT_EQ(GetLogID(), log_id);
+ ASSERT_EQ(sth.version, known_sth_.version);
+ ASSERT_EQ(sth.timestamp, known_sth_.timestamp);
+ ASSERT_EQ(sth.tree_size, known_sth_.tree_size);
+ ASSERT_STREQ(sth.sha256_root_hash, known_sth_.sha256_root_hash);
+ ASSERT_EQ(sth.signature.hash_algorithm,
+ known_sth_.signature.hash_algorithm);
+ ASSERT_EQ(sth.signature.signature_algorithm,
+ known_sth_.signature.signature_algorithm);
+ ASSERT_EQ(sth.signature.signature_data,
+ known_sth_.signature.signature_data);
+
+ RecordFetchCallbackInvocations::STHFetched(log_id, sth);
+ }
+
+ private:
+ net::ct::SignedTreeHead known_sth_;
+};
+
+TEST_F(LogProofFetcherTest, TestValidGetSTHReply) {
+ sth_json_reply_data_ = net::ct::GetSampleSTHAsJson();
+
+ net::ct::SignedTreeHead valid_sth;
+ net::ct::GetSampleSignedTreeHead(&valid_sth);
+ ExpectedSuccessCallback cb(valid_sth);
+
+ fetcher_->FetchSignedTreeHead(
+ log_url_, GetLogID(),
+ base::Bind(&ExpectedSuccessCallback::STHFetched, base::Unretained(&cb)),
+ base::Bind(&ExpectedSuccessCallback::FetchingFailed,
+ base::Unretained(&cb)));
+ message_loop_.RunUntilIdle();
+
+ ASSERT_TRUE(cb.invoked());
+ ASSERT_FALSE(cb.failed());
+}
+
+TEST_F(LogProofFetcherTest, TestInvalidGetSTHReplyIncompleteSTH) {
+ RecordFetchCallbackInvocations cb;
+ sth_json_reply_data_ = net::ct::CreateSignedTreeHeadJsonString(
+ 21 /* tree_size */, 123456u /* timestamp */, std::string(""),
+ std::string(""));
+
+ fetcher_->FetchSignedTreeHead(
+ log_url_, GetLogID(),
+ base::Bind(&RecordFetchCallbackInvocations::STHFetched,
+ base::Unretained(&cb)),
+ base::Bind(&RecordFetchCallbackInvocations::FetchingFailed,
+ base::Unretained(&cb)));
+ message_loop_.RunUntilIdle();
+
+ ASSERT_TRUE(cb.invoked());
+ ASSERT_TRUE(cb.failed());
+}
+
+TEST_F(LogProofFetcherTest, TestInvalidGetSTHReplyInvalidJSON) {
+ RecordFetchCallbackInvocations cb;
+ sth_json_reply_data_ = "{\"tree_size\":21,\"timestamp\":}";
+
+ fetcher_->FetchSignedTreeHead(
+ log_url_, GetLogID(),
+ base::Bind(&RecordFetchCallbackInvocations::STHFetched,
+ base::Unretained(&cb)),
+ base::Bind(&RecordFetchCallbackInvocations::FetchingFailed,
+ base::Unretained(&cb)));
+ message_loop_.RunUntilIdle();
+
+ ASSERT_TRUE(cb.invoked());
+ ASSERT_TRUE(cb.failed());
+}
+
mmenke 2015/07/29 18:51:51 Suggested other tests: Network error before we ge
Eran Messeri 2015/07/31 12:55:53 I've added a test for async IO and non-2xx status
mmenke 2015/07/31 15:40:25 URLRequestFailedJob
+} // namespace
+
+} // namespace certificate_transparency

Powered by Google App Engine
This is Rietveld 408576698