Commit 05857696 authored by Josh Nohle's avatar Josh Nohle Committed by Commit Bot

[Nearby] Refactor private cert expiration handling in manager

Use the certificate storage class to remove expired private
certificates.

Bug: b/166112705
Change-Id: I029ab2fccaa35100adf9f2e5a03b9bbd7003e00c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2412485Reviewed-by: default avatarJames Vecore <vecore@google.com>
Commit-Queue: Josh Nohle <nohle@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807292}
parent f97cdc4c
...@@ -56,6 +56,42 @@ size_t NumExpectedPrivateCertificates() { ...@@ -56,6 +56,42 @@ size_t NumExpectedPrivateCertificates() {
return kVisibilities.size() * kNearbyShareNumPrivateCertificates; return kVisibilities.size() * kNearbyShareNumPrivateCertificates;
} }
base::Optional<nearbyshare::proto::EncryptedMetadata> BuildMetadata(
base::Optional<std::string> device_name,
base::Optional<std::string> full_name,
base::Optional<std::string> icon_url,
device::BluetoothAdapter* bluetooth_adapter) {
nearbyshare::proto::EncryptedMetadata metadata;
if (!device_name) {
NS_LOG(WARNING)
<< __func__
<< ": Cannot create private certificate metadata; missing device name.";
return base::nullopt;
}
metadata.set_device_name(*device_name);
if (full_name) {
metadata.set_full_name(*full_name);
}
if (icon_url) {
metadata.set_icon_url(*icon_url);
}
std::array<uint8_t, 6> bytes;
if (bluetooth_adapter &&
device::ParseBluetoothAddress(bluetooth_adapter->GetAddress(), bytes)) {
metadata.set_bluetooth_mac_address(std::string(bytes.begin(), bytes.end()));
} else {
NS_LOG(WARNING) << __func__
<< ": No valid Bluetooth MAC available for private "
<< "certificate metadata.";
// TODO(https://crbug.com/1122641): Decide the best way to handle
// missing/invalid Bluetooth MAC addresses. Also, log a metric to track how
// often this happens.
}
return metadata;
}
void RecordGetDecryptedPublicCertificateResultMetric( void RecordGetDecryptedPublicCertificateResultMetric(
GetDecryptedPublicCertificateResult result) { GetDecryptedPublicCertificateResult result) {
base::UmaHistogramEnumeration( base::UmaHistogramEnumeration(
...@@ -355,86 +391,52 @@ void NearbyShareCertificateManagerImpl::OnPrivateCertificateExpiration() { ...@@ -355,86 +391,52 @@ void NearbyShareCertificateManagerImpl::OnPrivateCertificateExpiration() {
NS_LOG(VERBOSE) NS_LOG(VERBOSE)
<< __func__ << __func__
<< ": Private certificate expiration detected; refreshing certificates."; << ": Private certificate expiration detected; refreshing certificates.";
base::Time now = clock_->Now();
base::flat_map<nearby_share::mojom::Visibility, size_t> num_valid_certs;
base::flat_map<nearby_share::mojom::Visibility, base::Time> latest_not_after;
for (nearby_share::mojom::Visibility visibility : kVisibilities) {
num_valid_certs[visibility] = 0;
latest_not_after[visibility] = now;
}
// Remove all expired certificates.
std::vector<NearbySharePrivateCertificate> old_certs =
*certificate_storage_->GetPrivateCertificates();
std::vector<NearbySharePrivateCertificate> new_certs;
for (const NearbySharePrivateCertificate& cert : old_certs) {
if (IsNearbyShareCertificateExpired(
now, cert.not_after(),
/*use_public_certificate_tolerance=*/false)) {
continue;
}
++num_valid_certs[cert.visibility()];
latest_not_after[cert.visibility()] =
std::max(latest_not_after[cert.visibility()], cert.not_after());
new_certs.push_back(cert);
}
if (!old_certs.empty() && new_certs.size() == old_certs.size()) {
NS_LOG(VERBOSE) << __func__
<< ": All private certificates are still valid.";
private_certificate_expiration_scheduler_->HandleResult(/*success=*/true);
return;
}
device::BluetoothAdapterFactory::Get()->GetAdapter(base::BindOnce( device::BluetoothAdapterFactory::Get()->GetAdapter(base::BindOnce(
&NearbyShareCertificateManagerImpl::FinishPrivateCertificateRefresh, &NearbyShareCertificateManagerImpl::FinishPrivateCertificateRefresh,
weak_ptr_factory_.GetWeakPtr(), std::move(new_certs), weak_ptr_factory_.GetWeakPtr()));
std::move(num_valid_certs), std::move(latest_not_after)));
} }
void NearbyShareCertificateManagerImpl::FinishPrivateCertificateRefresh( void NearbyShareCertificateManagerImpl::FinishPrivateCertificateRefresh(
std::vector<NearbySharePrivateCertificate> new_certs,
base::flat_map<nearby_share::mojom::Visibility, size_t> num_valid_certs,
base::flat_map<nearby_share::mojom::Visibility, base::Time>
latest_not_after,
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) { scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) {
nearbyshare::proto::EncryptedMetadata metadata; base::Time now = clock_->Now();
certificate_storage_->RemoveExpiredPrivateCertificates(now);
base::Optional<std::string> device_name = std::vector<NearbySharePrivateCertificate> certs =
local_device_data_manager_->GetDeviceName(); *certificate_storage_->GetPrivateCertificates();
if (!device_name) { if (certs.size() == NumExpectedPrivateCertificates()) {
NS_LOG(WARNING) NS_LOG(VERBOSE) << __func__
<< __func__ << ": All private certificates are still valid.";
<< ": Cannot create private certificates; missing device name."; private_certificate_expiration_scheduler_->HandleResult(/*success=*/true);
private_certificate_expiration_scheduler_->HandleResult(/*success=*/false);
return; return;
} }
metadata.set_device_name(*device_name);
base::Optional<std::string> full_name = // Determine how many private certificates of each visibility need to be
local_device_data_manager_->GetFullName(); // created, and determine the validity period for the new certificates.
base::Optional<std::string> icon_url = base::flat_map<nearby_share::mojom::Visibility, size_t> num_valid_certs;
local_device_data_manager_->GetIconUrl(); base::flat_map<nearby_share::mojom::Visibility, base::Time> latest_not_after;
if (full_name) { for (nearby_share::mojom::Visibility visibility : kVisibilities) {
metadata.set_full_name(*full_name); num_valid_certs[visibility] = 0;
latest_not_after[visibility] = now;
} }
if (icon_url) { for (const NearbySharePrivateCertificate& cert : certs) {
metadata.set_icon_url(*icon_url); ++num_valid_certs[cert.visibility()];
latest_not_after[cert.visibility()] =
std::max(latest_not_after[cert.visibility()], cert.not_after());
} }
std::array<uint8_t, 6> bytes; base::Optional<nearbyshare::proto::EncryptedMetadata> metadata =
if (bluetooth_adapter && BuildMetadata(local_device_data_manager_->GetDeviceName(),
device::ParseBluetoothAddress(bluetooth_adapter->GetAddress(), bytes)) { local_device_data_manager_->GetFullName(),
metadata.set_bluetooth_mac_address(std::string(bytes.begin(), bytes.end())); local_device_data_manager_->GetIconUrl(),
} else { bluetooth_adapter.get());
NS_LOG(WARNING) << __func__ if (!metadata) {
<< ": No valid Bluetooth MAC available during private " private_certificate_expiration_scheduler_->HandleResult(/*success=*/false);
<< "certificate creation."; return;
// TODO(https://crbug.com/1122641): Decide the best way to handle
// missing/invalid Bluetooth MAC addresses. Also, log a metric to track how
// often this happens.
} }
// Add new certificates if necessary. Each visibility should have
// kNearbyShareNumPrivateCertificates.
NS_LOG(VERBOSE) NS_LOG(VERBOSE)
<< __func__ << ": Creating " << __func__ << ": Creating "
<< kNearbyShareNumPrivateCertificates - << kNearbyShareNumPrivateCertificates -
...@@ -443,18 +445,17 @@ void NearbyShareCertificateManagerImpl::FinishPrivateCertificateRefresh( ...@@ -443,18 +445,17 @@ void NearbyShareCertificateManagerImpl::FinishPrivateCertificateRefresh(
<< kNearbyShareNumPrivateCertificates - << kNearbyShareNumPrivateCertificates -
num_valid_certs[nearby_share::mojom::Visibility::kSelectedContacts] num_valid_certs[nearby_share::mojom::Visibility::kSelectedContacts]
<< " selected-contacts visibility private certificates."; << " selected-contacts visibility private certificates.";
// Add new certificates if necessary. Each visibility should have
// kNearbyShareNumPrivateCertificates.
for (nearby_share::mojom::Visibility visibility : kVisibilities) { for (nearby_share::mojom::Visibility visibility : kVisibilities) {
while (num_valid_certs[visibility] < kNearbyShareNumPrivateCertificates) { while (num_valid_certs[visibility] < kNearbyShareNumPrivateCertificates) {
new_certs.emplace_back( certs.emplace_back(visibility,
visibility, /*not_before=*/latest_not_after[visibility], metadata); /*not_before=*/latest_not_after[visibility],
*metadata);
++num_valid_certs[visibility]; ++num_valid_certs[visibility];
latest_not_after[visibility] = new_certs.back().not_after(); latest_not_after[visibility] = certs.back().not_after();
} }
} }
certificate_storage_->ReplacePrivateCertificates(new_certs); certificate_storage_->ReplacePrivateCertificates(certs);
NotifyPrivateCertificatesChanged(); NotifyPrivateCertificatesChanged();
private_certificate_expiration_scheduler_->HandleResult(/*success=*/true); private_certificate_expiration_scheduler_->HandleResult(/*success=*/true);
......
...@@ -150,10 +150,6 @@ class NearbyShareCertificateManagerImpl ...@@ -150,10 +150,6 @@ class NearbyShareCertificateManagerImpl
void OnPrivateCertificateExpiration(); void OnPrivateCertificateExpiration();
void FinishPrivateCertificateRefresh( void FinishPrivateCertificateRefresh(
std::vector<NearbySharePrivateCertificate> new_certs,
base::flat_map<nearby_share::mojom::Visibility, size_t> num_valid_certs,
base::flat_map<nearby_share::mojom::Visibility, base::Time>
latest_not_after,
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter); scoped_refptr<device::BluetoothAdapter> bluetooth_adapter);
// Invoked by the certificate upload scheduler when private certificates need // Invoked by the certificate upload scheduler when private certificates need
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment