| // Copyright 2016 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/sth_distributor.h" |
| |
| #include "base/metrics/histogram_macros.h" |
| #include "base/time/time.h" |
| #include "net/cert/signed_tree_head.h" |
| |
| namespace { |
| const uint8_t kPilotLogID[] = {0xa4, 0xb9, 0x09, 0x90, 0xb4, 0x18, 0x58, 0x14, |
| 0x87, 0xbb, 0x13, 0xa2, 0xcc, 0x67, 0x70, 0x0a, |
| 0x3c, 0x35, 0x98, 0x04, 0xf9, 0x1b, 0xdf, 0xb8, |
| 0xe3, 0x77, 0xcd, 0x0e, 0xc8, 0x0d, 0xdc, 0x10}; |
| } |
| |
| namespace certificate_transparency { |
| |
| STHDistributor::STHDistributor() |
| : observer_list_(base::ObserverListPolicy::EXISTING_ONLY) {} |
| |
| STHDistributor::~STHDistributor() = default; |
| |
| void STHDistributor::NewSTHObserved(const net::ct::SignedTreeHead& sth) { |
| auto it = std::find_if(observed_sths_.begin(), observed_sths_.end(), |
| [&sth](const net::ct::SignedTreeHead& other) { |
| return sth.log_id == other.log_id; |
| }); |
| |
| if (it == observed_sths_.end()) |
| observed_sths_.push_back(sth); |
| else |
| *it = sth; |
| |
| for (auto& observer : observer_list_) |
| observer.NewSTHObserved(sth); |
| |
| if (sth.log_id.compare(0, sth.log_id.size(), |
| reinterpret_cast<const char*>(kPilotLogID), |
| sizeof(kPilotLogID)) != 0) |
| return; |
| |
| const base::TimeDelta sth_age = base::Time::Now() - sth.timestamp; |
| UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertificateTransparency.PilotSTHAge", sth_age, |
| base::TimeDelta::FromHours(1), |
| base::TimeDelta::FromDays(4), 100); |
| } |
| |
| void STHDistributor::RegisterObserver(STHObserver* observer) { |
| observer_list_.AddObserver(observer); |
| // Make a local copy, because notifying the |observer| of a |
| // new STH may result in this class being notified of a |
| // (different) new STH, thus invalidating the iterator. |
| std::vector<net::ct::SignedTreeHead> local_sths(observed_sths_); |
| |
| for (const auto& sth : local_sths) |
| observer->NewSTHObserved(sth); |
| } |
| |
| void STHDistributor::UnregisterObserver(STHObserver* observer) { |
| observer_list_.RemoveObserver(observer); |
| } |
| |
| } // namespace certificate_transparency |