blob: 279a6da8b7974cf4be03283499d3a9525a095de0 [file] [log] [blame]
Alex Chaua76a6e32019-06-26 16:20:011// Copyright 2019 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 "components/gcm_driver/gcm_driver_desktop.h"
6
7#include <stdint.h>
8
9#include "base/base64.h"
10#include "base/bind.h"
11#include "base/files/scoped_temp_dir.h"
12#include "base/macros.h"
13#include "base/message_loop/message_loop_current.h"
14#include "base/optional.h"
15#include "base/run_loop.h"
Gabriel Charettec7108742019-08-23 03:31:4016#include "base/test/task_environment.h"
Alex Chaua76a6e32019-06-26 16:20:0117#include "base/test/test_simple_task_runner.h"
18#include "base/threading/thread.h"
19#include "base/threading/thread_task_runner_handle.h"
Alex Chau1fe6bab92019-06-28 12:33:0220#include "components/gcm_driver/crypto/gcm_decryption_result.h"
Alex Chaua76a6e32019-06-26 16:20:0121#include "components/gcm_driver/crypto/gcm_encryption_provider.h"
Alex Chauda2073d62020-01-29 11:26:0822#include "components/gcm_driver/crypto/gcm_encryption_result.h"
Alex Chaua76a6e32019-06-26 16:20:0123#include "components/gcm_driver/fake_gcm_client_factory.h"
Alex Chaua76a6e32019-06-26 16:20:0124#include "components/gcm_driver/gcm_client_factory.h"
25#include "components/prefs/pref_registry_simple.h"
26#include "components/prefs/testing_pref_service.h"
27#include "crypto/ec_private_key.h"
28#include "net/url_request/url_request_context_getter.h"
29#include "net/url_request/url_request_test_util.h"
30#include "services/network/public/cpp/shared_url_loader_factory.h"
31#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
32#include "services/network/test/test_network_connection_tracker.h"
33#include "services/network/test/test_url_loader_factory.h"
34#include "services/network/test/test_utils.h"
35#include "testing/gtest/include/gtest/gtest.h"
36
37namespace gcm {
38
39namespace {
40
Alex Chaua76a6e32019-06-26 16:20:0141const char kTestAppID1[] = "TestApp1";
42
Alex Chaua76a6e32019-06-26 16:20:0143void PumpCurrentLoop() {
44 base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
45}
46
47} // namespace
48
49class GCMDriverBaseTest : public testing::Test {
50 public:
51 enum WaitToFinish { DO_NOT_WAIT, WAIT };
52
53 GCMDriverBaseTest();
54 ~GCMDriverBaseTest() override;
55
56 // testing::Test:
57 void SetUp() override;
58 void TearDown() override;
59
60 GCMDriverDesktop* driver() { return driver_.get(); }
Alex Chauda2073d62020-01-29 11:26:0861
Alex Chaua76a6e32019-06-26 16:20:0162 const std::string& p256dh() const { return p256dh_; }
63 const std::string& auth_secret() const { return auth_secret_; }
64 network::TestURLLoaderFactory& loader() { return test_url_loader_factory_; }
Alex Chauda2073d62020-01-29 11:26:0865 GCMEncryptionResult encryption_result() { return encryption_result_; }
66 const std::string& encrypted_message() { return encrypted_message_; }
Alex Chau1fe6bab92019-06-28 12:33:0267 GCMDecryptionResult decryption_result() { return decryption_result_; }
Alex Chauda2073d62020-01-29 11:26:0868 const std::string& decrypted_message() { return decrypted_message_; }
Alex Chaua76a6e32019-06-26 16:20:0169
70 void PumpIOLoop();
71
72 void CreateDriver();
73 void ShutdownDriver();
74
Alex Chaua76a6e32019-06-26 16:20:0175 void GetEncryptionInfo(const std::string& app_id,
76 WaitToFinish wait_to_finish);
Alex Chauda2073d62020-01-29 11:26:0877 void EncryptMessage(const std::string& app_id,
78 const std::string& authorized_entity,
79 const std::string& p256dh,
80 const std::string& auth_secret,
81 const std::string& message,
82 WaitToFinish wait_to_finish);
Alex Chau1fe6bab92019-06-28 12:33:0283 void DecryptMessage(const std::string& app_id,
Alex Chauda2073d62020-01-29 11:26:0884 const std::string& authorized_entity,
85 const std::string& message,
Alex Chau1fe6bab92019-06-28 12:33:0286 WaitToFinish wait_to_finish);
Alex Chaua76a6e32019-06-26 16:20:0187
Peter Beverloo9635b662019-07-10 19:05:1888 void GetEncryptionInfoCompleted(std::string p256dh, std::string auth_secret);
Alex Chauda2073d62020-01-29 11:26:0889 void EncryptMessageCompleted(GCMEncryptionResult result, std::string message);
90 void DecryptMessageCompleted(GCMDecryptionResult result, std::string message);
Alex Chaua76a6e32019-06-26 16:20:0191 void UnregisterCompleted(GCMClient::Result result);
92
93 private:
94 base::ScopedTempDir temp_dir_;
95 TestingPrefServiceSimple prefs_;
Gabriel Charettedfa36042019-08-19 17:30:1196 base::test::TaskEnvironment task_environment_{
97 base::test::TaskEnvironment::MainThreadType::UI};
Alex Chaua76a6e32019-06-26 16:20:0198 base::Thread io_thread_;
99 network::TestURLLoaderFactory test_url_loader_factory_;
100
101 std::unique_ptr<GCMDriverDesktop> driver_;
102
Reilly Grantaa7bc2f2020-01-31 11:49:29103 base::OnceClosure async_operation_completed_callback_;
Alex Chaua76a6e32019-06-26 16:20:01104 std::string p256dh_;
105 std::string auth_secret_;
106
Alex Chauda2073d62020-01-29 11:26:08107 GCMEncryptionResult encryption_result_ =
108 GCMEncryptionResult::ENCRYPTION_FAILED;
109 std::string encrypted_message_;
Alex Chau1fe6bab92019-06-28 12:33:02110 GCMDecryptionResult decryption_result_ = GCMDecryptionResult::UNENCRYPTED;
Alex Chauda2073d62020-01-29 11:26:08111 std::string decrypted_message_;
Alex Chau1fe6bab92019-06-28 12:33:02112
Alex Chaua76a6e32019-06-26 16:20:01113 DISALLOW_COPY_AND_ASSIGN(GCMDriverBaseTest);
114};
115
116GCMDriverBaseTest::GCMDriverBaseTest() : io_thread_("IOThread") {}
117
118GCMDriverBaseTest::~GCMDriverBaseTest() = default;
119
120void GCMDriverBaseTest::SetUp() {
Alex Chaua76a6e32019-06-26 16:20:01121 io_thread_.Start();
122 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
123
124 CreateDriver();
125 PumpIOLoop();
126 PumpCurrentLoop();
127}
128
129void GCMDriverBaseTest::TearDown() {
130 if (!driver_)
131 return;
132
133 ShutdownDriver();
134 driver_.reset();
135 PumpIOLoop();
136
137 io_thread_.Stop();
Greg Thompson28dd8462019-11-29 13:28:07138 task_environment_.RunUntilIdle();
139 ASSERT_TRUE(temp_dir_.Delete());
Alex Chaua76a6e32019-06-26 16:20:01140}
141
142void GCMDriverBaseTest::PumpIOLoop() {
143 base::RunLoop run_loop;
144 io_thread_.task_runner()->PostTaskAndReply(
145 FROM_HERE, base::BindOnce(&PumpCurrentLoop), run_loop.QuitClosure());
146 run_loop.Run();
147}
148
149void GCMDriverBaseTest::CreateDriver() {
150 scoped_refptr<net::URLRequestContextGetter> request_context =
151 new net::TestURLRequestContextGetter(io_thread_.task_runner());
152 GCMClient::ChromeBuildInfo chrome_build_info;
153 chrome_build_info.product_category_for_subtypes = "com.chrome.macosx";
154 driver_ = std::make_unique<GCMDriverDesktop>(
155 std::make_unique<FakeGCMClientFactory>(
156 base::ThreadTaskRunnerHandle::Get(), io_thread_.task_runner()),
Marc Treibae8cac692020-01-28 12:10:12157 chrome_build_info, "user-agent-string", &prefs_, temp_dir_.GetPath(),
Mihai Sardarescud260bd262019-12-10 16:40:25158 /*remove_account_mappings_with_email_key=*/true, base::DoNothing(),
Alex Chaua76a6e32019-06-26 16:20:01159 base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
160 &test_url_loader_factory_),
161 network::TestNetworkConnectionTracker::GetInstance(),
162 base::ThreadTaskRunnerHandle::Get(), io_thread_.task_runner(),
163 task_environment_.GetMainThreadTaskRunner());
164}
165
166void GCMDriverBaseTest::ShutdownDriver() {
167 driver()->Shutdown();
168}
169
Alex Chaua76a6e32019-06-26 16:20:01170void GCMDriverBaseTest::GetEncryptionInfo(const std::string& app_id,
171 WaitToFinish wait_to_finish) {
172 base::RunLoop run_loop;
173 async_operation_completed_callback_ = run_loop.QuitClosure();
174 driver_->GetEncryptionInfo(
Peter Beverloo9635b662019-07-10 19:05:18175 app_id, base::BindOnce(&GCMDriverBaseTest::GetEncryptionInfoCompleted,
176 base::Unretained(this)));
Alex Chaua76a6e32019-06-26 16:20:01177 if (wait_to_finish == WAIT)
178 run_loop.Run();
179}
180
Alex Chauda2073d62020-01-29 11:26:08181void GCMDriverBaseTest::EncryptMessage(const std::string& app_id,
182 const std::string& authorized_entity,
183 const std::string& p256dh,
184 const std::string& auth_secret,
185 const std::string& message,
Alex Chau1fe6bab92019-06-28 12:33:02186 WaitToFinish wait_to_finish) {
187 base::RunLoop run_loop;
188 async_operation_completed_callback_ = run_loop.QuitClosure();
Alex Chauda2073d62020-01-29 11:26:08189
190 driver()->EncryptMessage(
191 app_id, authorized_entity, p256dh, auth_secret, message,
192 base::BindOnce(&GCMDriverBaseTest::EncryptMessageCompleted,
193 base::Unretained(this)));
Alex Chau1fe6bab92019-06-28 12:33:02194
195 if (wait_to_finish == WAIT)
196 run_loop.Run();
197}
198
Alex Chauda2073d62020-01-29 11:26:08199void GCMDriverBaseTest::DecryptMessage(const std::string& app_id,
200 const std::string& authorized_entity,
201 const std::string& message,
202 WaitToFinish wait_to_finish) {
203 base::RunLoop run_loop;
204 async_operation_completed_callback_ = run_loop.QuitClosure();
205
206 driver()->DecryptMessage(
207 app_id, authorized_entity, message,
208 base::BindOnce(&GCMDriverBaseTest::DecryptMessageCompleted,
209 base::Unretained(this)));
210
211 if (wait_to_finish == WAIT)
212 run_loop.Run();
Alex Chaua76a6e32019-06-26 16:20:01213}
214
Peter Beverloo9635b662019-07-10 19:05:18215void GCMDriverBaseTest::GetEncryptionInfoCompleted(std::string p256dh,
216 std::string auth_secret) {
217 p256dh_ = std::move(p256dh);
218 auth_secret_ = std::move(auth_secret);
Alex Chaua76a6e32019-06-26 16:20:01219 if (!async_operation_completed_callback_.is_null())
Reilly Grantaa7bc2f2020-01-31 11:49:29220 std::move(async_operation_completed_callback_).Run();
Alex Chaua76a6e32019-06-26 16:20:01221}
222
Alex Chauda2073d62020-01-29 11:26:08223void GCMDriverBaseTest::EncryptMessageCompleted(GCMEncryptionResult result,
224 std::string message) {
225 encryption_result_ = result;
226 encrypted_message_ = std::move(message);
Alex Chau1fe6bab92019-06-28 12:33:02227 if (!async_operation_completed_callback_.is_null())
Reilly Grantaa7bc2f2020-01-31 11:49:29228 std::move(async_operation_completed_callback_).Run();
Alex Chau1fe6bab92019-06-28 12:33:02229}
230
Alex Chauda2073d62020-01-29 11:26:08231void GCMDriverBaseTest::DecryptMessageCompleted(GCMDecryptionResult result,
232 std::string message) {
233 decryption_result_ = result;
234 decrypted_message_ = std::move(message);
235 if (!async_operation_completed_callback_.is_null())
Reilly Grantaa7bc2f2020-01-31 11:49:29236 std::move(async_operation_completed_callback_).Run();
Alex Chauda2073d62020-01-29 11:26:08237}
238
239TEST_F(GCMDriverBaseTest, EncryptionDecryptionRoundTrip) {
Alex Chaua76a6e32019-06-26 16:20:01240 GetEncryptionInfo(kTestAppID1, GCMDriverBaseTest::WAIT);
241
Alex Chauda2073d62020-01-29 11:26:08242 std::string message = "payload";
243 ASSERT_NO_FATAL_FAILURE(
244 EncryptMessage(kTestAppID1, /* authorized_entity= */ "", p256dh(),
245 auth_secret(), message, GCMDriverBaseTest::WAIT));
Alex Chaua76a6e32019-06-26 16:20:01246
Alex Chauda2073d62020-01-29 11:26:08247 EXPECT_EQ(GCMEncryptionResult::ENCRYPTED_DRAFT_08, encryption_result());
Alex Chau1fe6bab92019-06-28 12:33:02248
Alex Chauda2073d62020-01-29 11:26:08249 ASSERT_NO_FATAL_FAILURE(
250 DecryptMessage(kTestAppID1, /* authorized_entity= */ "",
251 encrypted_message(), GCMDriverBaseTest::WAIT));
Alex Chau1fe6bab92019-06-28 12:33:02252
253 EXPECT_EQ(GCMDecryptionResult::DECRYPTED_DRAFT_08, decryption_result());
Alex Chauda2073d62020-01-29 11:26:08254 EXPECT_EQ(message, decrypted_message());
Alex Chaua76a6e32019-06-26 16:20:01255}
256
Alex Chauda2073d62020-01-29 11:26:08257TEST_F(GCMDriverBaseTest, EncryptionError) {
Alex Chaua76a6e32019-06-26 16:20:01258 // Intentionally not creating encryption info.
259
Alex Chauda2073d62020-01-29 11:26:08260 std::string message = "payload";
Alex Chaua76a6e32019-06-26 16:20:01261 ASSERT_NO_FATAL_FAILURE(
Alex Chauda2073d62020-01-29 11:26:08262 EncryptMessage(kTestAppID1, /* authorized_entity= */ "", p256dh(),
263 auth_secret(), message, GCMDriverBaseTest::WAIT));
Alex Chaua76a6e32019-06-26 16:20:01264
Alex Chauda2073d62020-01-29 11:26:08265 EXPECT_EQ(GCMEncryptionResult::NO_KEYS, encryption_result());
Alex Chaua76a6e32019-06-26 16:20:01266}
267
268} // namespace gcm