Skip to content

Commit

Permalink
network_time_tracker: add temporary time protocol.
Browse files Browse the repository at this point in the history
This adds queries of the temporary secure time server, with signature
verification, and a very conservative scheduler.  (Checks once per hour,
queries only if sync believed to be lost.)

BUG=589700

Committed: https://crrev.com/ee2016a374b73ba35508ae26837755a23b3defa4
Cr-Commit-Position: refs/heads/master@{#392208}

Review-Url: https://codereview.chromium.org/1835823002
Cr-Commit-Position: refs/heads/master@{#392711}
  • Loading branch information
mab authored and Commit bot committed May 10, 2016
1 parent 4727ab6 commit 2f07cb9
Show file tree
Hide file tree
Showing 14 changed files with 591 additions and 56 deletions.
14 changes: 8 additions & 6 deletions chrome/browser/browser_process_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,16 @@ void BrowserProcessImpl::StartTearDown() {
tearing_down_ = true;
DCHECK(IsShuttingDown());
// We need to destroy the MetricsServicesManager, IntranetRedirectDetector,
// PromoResourceService, and SafeBrowsing ClientSideDetectionService (owned by
// the SafeBrowsingService) before the io_thread_ gets destroyed, since their
// destructors can call the URLFetcher destructor, which does a
// PostDelayedTask operation on the IO thread. (The IO thread will handle that
// URLFetcher operation before going away.)
// PromoResourceService, NetworkTimeTracker, and SafeBrowsing
// ClientSideDetectionService (owned by the SafeBrowsingService) before the
// io_thread_ gets destroyed, since their destructors can call the URLFetcher
// destructor, which does a PostDelayedTask operation on the IO thread. (The
// IO thread will handle that URLFetcher operation before going away.)
metrics_services_manager_.reset();
intranet_redirect_detector_.reset();
if (safe_browsing_service_.get())
safe_browsing_service()->ShutDown();
network_time_tracker_.reset();
#if defined(ENABLE_PLUGIN_INSTALLATION)
plugins_resource_service_.reset();
#endif
Expand Down Expand Up @@ -747,7 +748,8 @@ network_time::NetworkTimeTracker* BrowserProcessImpl::network_time_tracker() {
if (!network_time_tracker_) {
network_time_tracker_.reset(new network_time::NetworkTimeTracker(
base::WrapUnique(new base::DefaultClock()),
base::WrapUnique(new base::DefaultTickClock()), local_state()));
base::WrapUnique(new base::DefaultTickClock()), local_state(),
system_request_context()));
}
return network_time_tracker_.get();
}
Expand Down
2 changes: 1 addition & 1 deletion chrome/test/base/testing_browser_process.cc
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ TestingBrowserProcess::network_time_tracker() {
network_time_tracker_.reset(new network_time::NetworkTimeTracker(
std::unique_ptr<base::Clock>(new base::DefaultClock()),
std::unique_ptr<base::TickClock>(new base::DefaultTickClock()),
local_state_));
local_state_, system_request_context()));
}
return network_time_tracker_.get();
}
Expand Down
6 changes: 5 additions & 1 deletion components/client_update_protocol/ecdsa.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,13 @@ std::unique_ptr<Ecdsa> Ecdsa::Create(int key_version,
return base::WrapUnique(new Ecdsa(key_version, public_key));
}

void Ecdsa::OverrideNonceForTesting(int key_version, uint32_t nonce) {
DCHECK(!request_query_cup2key_.empty());
request_query_cup2key_ = base::StringPrintf("%d:%u", pub_key_version_, nonce);
}

void Ecdsa::SignRequest(const base::StringPiece& request_body,
std::string* query_params) {
DCHECK(!request_body.empty());
DCHECK(query_params);

// Generate a random nonce to use for freshness, build the cup2key query
Expand Down
16 changes: 9 additions & 7 deletions components/client_update_protocol/ecdsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,18 @@ class Ecdsa {

// Validates a response given to a ping previously signed with
// SignRequest(). |response_body| contains the body of the response in
// UTF-8. |server_proof| contains the ECDSA signature and observed request
// hash, which is passed in the ETag HTTP header. Returns true if the response
// is valid and the observed request hash matches the sent hash. This method
// uses internal state that is set by a prior SignRequest() call.
// UTF-8. |signature| contains the ECDSA signature and observed request
// hash. Returns true if the response is valid and the observed request hash
// matches the sent hash. This method uses internal state that is set by a
// prior SignRequest() call.
bool ValidateResponse(const base::StringPiece& response_body,
const base::StringPiece& server_etag);
const base::StringPiece& signature);

private:
friend class CupEcdsaTest;
// Sets the key and nonce that were used to generate a signature that is baked
// into a unit test.
void OverrideNonceForTesting(int key_version, uint32_t nonce);

private:
Ecdsa(int key_version, const base::StringPiece& public_key);

// The server keeps multiple signing keys; a version must be sent so that
Expand Down
9 changes: 2 additions & 7 deletions components/client_update_protocol/ecdsa_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@ class CupEcdsaTest : public testing::Test {
ASSERT_TRUE(cup_.get());
}

void OverrideNonce(uint32_t nonce) {
cup_->request_query_cup2key_ =
base::StringPrintf("%d:%u", cup_->pub_key_version_, nonce);
}

Ecdsa& CUP() { return *cup_.get(); }

private:
Expand Down Expand Up @@ -86,7 +81,7 @@ TEST_F(CupEcdsaTest, ValidateResponse_TestETagParsing) {
// Invalid ETags must be gracefully rejected without a crash.
std::string query_discard;
CUP().SignRequest("Request_A", &query_discard);
OverrideNonce(12345);
CUP().OverrideNonceForTesting(8, 12345);

// Expect a pass for a well-formed etag.
EXPECT_TRUE(CUP().ValidateResponse(
Expand Down Expand Up @@ -238,7 +233,7 @@ TEST_F(CupEcdsaTest, ValidateResponse_TestETagParsing) {
TEST_F(CupEcdsaTest, ValidateResponse_TestSigning) {
std::string query_discard;
CUP().SignRequest("Request_A", &query_discard);
OverrideNonce(12345);
CUP().OverrideNonceForTesting(8, 12345);

// How to generate an ECDSA signature:
// echo -n Request_A | sha256sum | cut -d " " -f 1 > h
Expand Down
5 changes: 5 additions & 0 deletions components/network_time/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ static_library("network_time") {
deps = [
"//base",
"//base:i18n",
"//components/client_update_protocol",
"//components/prefs",
"//net",
]
}

Expand All @@ -27,7 +29,10 @@ source_set("unit_tests") {
":network_time",
"//base",
"//base/test:test_support",
"//components/client_update_protocol",
"//components/prefs:test_support",
"//net",
"//net:test_support",
"//testing/gtest",
]
}
2 changes: 2 additions & 0 deletions components/network_time/DEPS
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
include_rules = [
"+components/client_update_protocol",
"+components/prefs",
"+net",
]
Loading

0 comments on commit 2f07cb9

Please sign in to comment.