1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/policy/messaging_layer/encryption/encryption_module.h"
6 
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/feature_list.h"
10 #include "base/strings/string_piece.h"
11 #include "base/task/thread_pool.h"
12 #include "chrome/browser/policy/messaging_layer/util/status.h"
13 #include "chrome/browser/policy/messaging_layer/util/statusor.h"
14 #include "components/policy/proto/record.pb.h"
15 
16 namespace reporting {
17 
18 namespace {
19 
20 // Temporary: enable/disable encryption.
21 const base::Feature kEncryptedReportingFeature{
22     EncryptionModule::kEncryptedReporting, base::FEATURE_DISABLED_BY_DEFAULT};
23 
24 // Helper function for asynchronous encryption.
AddToRecord(base::StringPiece record,Encryptor::Handle * handle,base::OnceCallback<void (StatusOr<EncryptedRecord>)> cb)25 void AddToRecord(base::StringPiece record,
26                  Encryptor::Handle* handle,
27                  base::OnceCallback<void(StatusOr<EncryptedRecord>)> cb) {
28   handle->AddToRecord(
29       record,
30       base::BindOnce(
31           [](Encryptor::Handle* handle,
32              base::OnceCallback<void(StatusOr<EncryptedRecord>)> cb,
33              Status status) {
34             if (!status.ok()) {
35               std::move(cb).Run(status);
36               return;
37             }
38             base::ThreadPool::PostTask(
39                 FROM_HERE,
40                 base::BindOnce(&Encryptor::Handle::CloseRecord,
41                                base::Unretained(handle), std::move(cb)));
42           },
43           base::Unretained(handle), std::move(cb)));
44 }
45 
46 }  // namespace
47 
48 const char EncryptionModule::kEncryptedReporting[] = "EncryptedReporting";
49 
EncryptionModule()50 EncryptionModule::EncryptionModule() {
51   auto encryptor_result = Encryptor::Create();
52   DCHECK(encryptor_result.ok());
53   encryptor_ = std::move(encryptor_result.ValueOrDie());
54 }
55 
56 EncryptionModule::~EncryptionModule() = default;
57 
EncryptRecord(base::StringPiece record,base::OnceCallback<void (StatusOr<EncryptedRecord>)> cb) const58 void EncryptionModule::EncryptRecord(
59     base::StringPiece record,
60     base::OnceCallback<void(StatusOr<EncryptedRecord>)> cb) const {
61   if (!base::FeatureList::IsEnabled(kEncryptedReportingFeature)) {
62     // Encryptor disabled.
63     EncryptedRecord encrypted_record;
64     encrypted_record.mutable_encrypted_wrapped_record()->assign(record.begin(),
65                                                                 record.end());
66     // encryption_info is not set.
67     std::move(cb).Run(encrypted_record);
68     return;
69   }
70 
71   // Encryptor enabled: start encryption of the record as a whole.
72   encryptor_->OpenRecord(base::BindOnce(
73       [](base::StringPiece record,
74          base::OnceCallback<void(StatusOr<EncryptedRecord>)> cb,
75          StatusOr<Encryptor::Handle*> handle_result) {
76         if (!handle_result.ok()) {
77           std::move(cb).Run(handle_result.status());
78           return;
79         }
80         base::ThreadPool::PostTask(
81             FROM_HERE,
82             base::BindOnce(&AddToRecord, std::string(record),
83                            base::Unretained(handle_result.ValueOrDie()),
84                            std::move(cb)));
85       },
86       std::string(record), std::move(cb)));
87 }
88 
UpdateAsymmetricKey(base::StringPiece new_public_key,Encryptor::PublicKeyId new_public_key_id,base::OnceCallback<void (Status)> response_cb)89 void EncryptionModule::UpdateAsymmetricKey(
90     base::StringPiece new_public_key,
91     Encryptor::PublicKeyId new_public_key_id,
92     base::OnceCallback<void(Status)> response_cb) {
93   encryptor_->UpdateAsymmetricKey(new_public_key, new_public_key_id,
94                                   std::move(response_cb));
95 }
96 
97 }  // namespace reporting
98