| // Copyright 2020 The Chromium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "components/reporting/encryption/encryption_module.h" | |
| #include <string> | |
| #include <string_view> | |
| #include <utility> | |
| #include "base/functional/bind.h" | |
| #include "base/functional/callback.h" | |
| #include "base/task/thread_pool.h" | |
| #include "base/time/time.h" | |
| #include "base/types/expected.h" | |
| #include "components/reporting/encryption/encryption_module_interface.h" | |
| #include "components/reporting/proto/synced/record.pb.h" | |
| #include "components/reporting/util/status.h" | |
| #include "components/reporting/util/statusor.h" | |
| namespace reporting { | |
| namespace { | |
| // Helper function for asynchronous encryption. | |
| void AddToRecord(std::string_view record, | |
| Encryptor::Handle* handle, | |
| base::OnceCallback<void(StatusOr<EncryptedRecord>)> cb) { | |
| handle->AddToRecord( | |
| record, | |
| base::BindOnce( | |
| [](Encryptor::Handle* handle, | |
| base::OnceCallback<void(StatusOr<EncryptedRecord>)> cb, | |
| Status status) { | |
| if (!status.ok()) { | |
| std::move(cb).Run(base::unexpected(std::move(status))); | |
| return; | |
| } | |
| base::ThreadPool::PostTask( | |
| FROM_HERE, | |
| base::BindOnce(&Encryptor::Handle::CloseRecord, | |
| base::Unretained(handle), std::move(cb))); | |
| }, | |
| base::Unretained(handle), std::move(cb))); | |
| } | |
| } // namespace | |
| EncryptionModule::EncryptionModule(base::TimeDelta renew_encryption_key_period) | |
| : EncryptionModuleInterface(renew_encryption_key_period) { | |
| static_assert(std::is_same<PublicKeyId, Encryptor::PublicKeyId>::value, | |
| "Public key id types must match"); | |
| auto encryptor_result = Encryptor::Create(); | |
| CHECK(encryptor_result.has_value()) << encryptor_result.error(); | |
| encryptor_ = std::move(encryptor_result.value()); | |
| } | |
| EncryptionModule::~EncryptionModule() = default; | |
| void EncryptionModule::EncryptRecordImpl( | |
| std::string_view record, | |
| base::OnceCallback<void(StatusOr<EncryptedRecord>)> cb) const { | |
| // Encryption key is available, encrypt. | |
| encryptor_->OpenRecord(base::BindOnce( | |
| [](std::string record, | |
| base::OnceCallback<void(StatusOr<EncryptedRecord>)> cb, | |
| StatusOr<Encryptor::Handle*> handle_result) { | |
| if (!handle_result.has_value()) { | |
| std::move(cb).Run(base::unexpected(std::move(handle_result).error())); | |
| return; | |
| } | |
| base::ThreadPool::PostTask( | |
| FROM_HERE, base::BindOnce(&AddToRecord, record, | |
| base::Unretained(handle_result.value()), | |
| std::move(cb))); | |
| }, | |
| std::string(record), std::move(cb))); | |
| } | |
| void EncryptionModule::UpdateAsymmetricKeyImpl( | |
| std::string_view new_public_key, | |
| PublicKeyId new_public_key_id, | |
| base::OnceCallback<void(Status)> response_cb) { | |
| encryptor_->UpdateAsymmetricKey(new_public_key, new_public_key_id, | |
| std::move(response_cb)); | |
| } | |
| // static | |
| scoped_refptr<EncryptionModuleInterface> EncryptionModule::Create( | |
| base::TimeDelta renew_encryption_key_period) { | |
| return base::WrapRefCounted( | |
| new EncryptionModule(renew_encryption_key_period)); | |
| } | |
| } // namespace reporting |