gcm_driver_unittest.cc 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // 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. #include "components/gcm_driver/gcm_driver_desktop.h"
  5. #include <stdint.h>
  6. #include "base/base64.h"
  7. #include "base/bind.h"
  8. #include "base/files/scoped_temp_dir.h"
  9. #include "base/run_loop.h"
  10. #include "base/task/current_thread.h"
  11. #include "base/test/task_environment.h"
  12. #include "base/test/test_simple_task_runner.h"
  13. #include "base/threading/thread.h"
  14. #include "base/threading/thread_task_runner_handle.h"
  15. #include "components/gcm_driver/crypto/gcm_decryption_result.h"
  16. #include "components/gcm_driver/crypto/gcm_encryption_provider.h"
  17. #include "components/gcm_driver/crypto/gcm_encryption_result.h"
  18. #include "components/gcm_driver/fake_gcm_client_factory.h"
  19. #include "components/gcm_driver/gcm_client_factory.h"
  20. #include "components/prefs/pref_registry_simple.h"
  21. #include "components/prefs/testing_pref_service.h"
  22. #include "crypto/ec_private_key.h"
  23. #include "net/url_request/url_request_test_util.h"
  24. #include "services/network/public/cpp/shared_url_loader_factory.h"
  25. #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
  26. #include "services/network/test/test_network_connection_tracker.h"
  27. #include "services/network/test/test_url_loader_factory.h"
  28. #include "services/network/test/test_utils.h"
  29. #include "testing/gtest/include/gtest/gtest.h"
  30. #include "third_party/abseil-cpp/absl/types/optional.h"
  31. namespace gcm {
  32. namespace {
  33. const char kTestAppID1[] = "TestApp1";
  34. void PumpCurrentLoop() {
  35. base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
  36. }
  37. } // namespace
  38. class GCMDriverBaseTest : public testing::Test {
  39. public:
  40. enum WaitToFinish { DO_NOT_WAIT, WAIT };
  41. GCMDriverBaseTest();
  42. GCMDriverBaseTest(const GCMDriverBaseTest&) = delete;
  43. GCMDriverBaseTest& operator=(const GCMDriverBaseTest&) = delete;
  44. ~GCMDriverBaseTest() override;
  45. // testing::Test:
  46. void SetUp() override;
  47. void TearDown() override;
  48. GCMDriverDesktop* driver() { return driver_.get(); }
  49. const std::string& p256dh() const { return p256dh_; }
  50. const std::string& auth_secret() const { return auth_secret_; }
  51. network::TestURLLoaderFactory& loader() { return test_url_loader_factory_; }
  52. GCMEncryptionResult encryption_result() { return encryption_result_; }
  53. const std::string& encrypted_message() { return encrypted_message_; }
  54. GCMDecryptionResult decryption_result() { return decryption_result_; }
  55. const std::string& decrypted_message() { return decrypted_message_; }
  56. void PumpIOLoop();
  57. void CreateDriver();
  58. void ShutdownDriver();
  59. void GetEncryptionInfo(const std::string& app_id,
  60. WaitToFinish wait_to_finish);
  61. void EncryptMessage(const std::string& app_id,
  62. const std::string& authorized_entity,
  63. const std::string& p256dh,
  64. const std::string& auth_secret,
  65. const std::string& message,
  66. WaitToFinish wait_to_finish);
  67. void DecryptMessage(const std::string& app_id,
  68. const std::string& authorized_entity,
  69. const std::string& message,
  70. WaitToFinish wait_to_finish);
  71. void GetEncryptionInfoCompleted(std::string p256dh, std::string auth_secret);
  72. void EncryptMessageCompleted(GCMEncryptionResult result, std::string message);
  73. void DecryptMessageCompleted(GCMDecryptionResult result, std::string message);
  74. void UnregisterCompleted(GCMClient::Result result);
  75. private:
  76. base::ScopedTempDir temp_dir_;
  77. TestingPrefServiceSimple prefs_;
  78. base::test::TaskEnvironment task_environment_{
  79. base::test::TaskEnvironment::MainThreadType::UI};
  80. base::Thread io_thread_;
  81. network::TestURLLoaderFactory test_url_loader_factory_;
  82. std::unique_ptr<GCMDriverDesktop> driver_;
  83. base::OnceClosure async_operation_completed_callback_;
  84. std::string p256dh_;
  85. std::string auth_secret_;
  86. GCMEncryptionResult encryption_result_ =
  87. GCMEncryptionResult::ENCRYPTION_FAILED;
  88. std::string encrypted_message_;
  89. GCMDecryptionResult decryption_result_ = GCMDecryptionResult::UNENCRYPTED;
  90. std::string decrypted_message_;
  91. };
  92. GCMDriverBaseTest::GCMDriverBaseTest() : io_thread_("IOThread") {}
  93. GCMDriverBaseTest::~GCMDriverBaseTest() = default;
  94. void GCMDriverBaseTest::SetUp() {
  95. io_thread_.Start();
  96. ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  97. CreateDriver();
  98. PumpIOLoop();
  99. PumpCurrentLoop();
  100. }
  101. void GCMDriverBaseTest::TearDown() {
  102. if (!driver_)
  103. return;
  104. ShutdownDriver();
  105. driver_.reset();
  106. PumpIOLoop();
  107. io_thread_.Stop();
  108. task_environment_.RunUntilIdle();
  109. ASSERT_TRUE(temp_dir_.Delete());
  110. }
  111. void GCMDriverBaseTest::PumpIOLoop() {
  112. base::RunLoop run_loop;
  113. io_thread_.task_runner()->PostTaskAndReply(
  114. FROM_HERE, base::BindOnce(&PumpCurrentLoop), run_loop.QuitClosure());
  115. run_loop.Run();
  116. }
  117. void GCMDriverBaseTest::CreateDriver() {
  118. GCMClient::ChromeBuildInfo chrome_build_info;
  119. chrome_build_info.product_category_for_subtypes = "com.chrome.macosx";
  120. driver_ = std::make_unique<GCMDriverDesktop>(
  121. std::make_unique<FakeGCMClientFactory>(
  122. base::ThreadTaskRunnerHandle::Get(), io_thread_.task_runner()),
  123. chrome_build_info, &prefs_, temp_dir_.GetPath(),
  124. /*remove_account_mappings_with_email_key=*/true, base::DoNothing(),
  125. base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
  126. &test_url_loader_factory_),
  127. network::TestNetworkConnectionTracker::GetInstance(),
  128. base::ThreadTaskRunnerHandle::Get(), io_thread_.task_runner(),
  129. task_environment_.GetMainThreadTaskRunner());
  130. }
  131. void GCMDriverBaseTest::ShutdownDriver() {
  132. driver()->Shutdown();
  133. }
  134. void GCMDriverBaseTest::GetEncryptionInfo(const std::string& app_id,
  135. WaitToFinish wait_to_finish) {
  136. base::RunLoop run_loop;
  137. async_operation_completed_callback_ = run_loop.QuitClosure();
  138. driver_->GetEncryptionInfo(
  139. app_id, base::BindOnce(&GCMDriverBaseTest::GetEncryptionInfoCompleted,
  140. base::Unretained(this)));
  141. if (wait_to_finish == WAIT)
  142. run_loop.Run();
  143. }
  144. void GCMDriverBaseTest::EncryptMessage(const std::string& app_id,
  145. const std::string& authorized_entity,
  146. const std::string& p256dh,
  147. const std::string& auth_secret,
  148. const std::string& message,
  149. WaitToFinish wait_to_finish) {
  150. base::RunLoop run_loop;
  151. async_operation_completed_callback_ = run_loop.QuitClosure();
  152. driver()->EncryptMessage(
  153. app_id, authorized_entity, p256dh, auth_secret, message,
  154. base::BindOnce(&GCMDriverBaseTest::EncryptMessageCompleted,
  155. base::Unretained(this)));
  156. if (wait_to_finish == WAIT)
  157. run_loop.Run();
  158. }
  159. void GCMDriverBaseTest::DecryptMessage(const std::string& app_id,
  160. const std::string& authorized_entity,
  161. const std::string& message,
  162. WaitToFinish wait_to_finish) {
  163. base::RunLoop run_loop;
  164. async_operation_completed_callback_ = run_loop.QuitClosure();
  165. driver()->DecryptMessage(
  166. app_id, authorized_entity, message,
  167. base::BindOnce(&GCMDriverBaseTest::DecryptMessageCompleted,
  168. base::Unretained(this)));
  169. if (wait_to_finish == WAIT)
  170. run_loop.Run();
  171. }
  172. void GCMDriverBaseTest::GetEncryptionInfoCompleted(std::string p256dh,
  173. std::string auth_secret) {
  174. p256dh_ = std::move(p256dh);
  175. auth_secret_ = std::move(auth_secret);
  176. if (!async_operation_completed_callback_.is_null())
  177. std::move(async_operation_completed_callback_).Run();
  178. }
  179. void GCMDriverBaseTest::EncryptMessageCompleted(GCMEncryptionResult result,
  180. std::string message) {
  181. encryption_result_ = result;
  182. encrypted_message_ = std::move(message);
  183. if (!async_operation_completed_callback_.is_null())
  184. std::move(async_operation_completed_callback_).Run();
  185. }
  186. void GCMDriverBaseTest::DecryptMessageCompleted(GCMDecryptionResult result,
  187. std::string message) {
  188. decryption_result_ = result;
  189. decrypted_message_ = std::move(message);
  190. if (!async_operation_completed_callback_.is_null())
  191. std::move(async_operation_completed_callback_).Run();
  192. }
  193. TEST_F(GCMDriverBaseTest, EncryptionDecryptionRoundTrip) {
  194. GetEncryptionInfo(kTestAppID1, GCMDriverBaseTest::WAIT);
  195. std::string message = "payload";
  196. ASSERT_NO_FATAL_FAILURE(
  197. EncryptMessage(kTestAppID1, /* authorized_entity= */ "", p256dh(),
  198. auth_secret(), message, GCMDriverBaseTest::WAIT));
  199. EXPECT_EQ(GCMEncryptionResult::ENCRYPTED_DRAFT_08, encryption_result());
  200. ASSERT_NO_FATAL_FAILURE(
  201. DecryptMessage(kTestAppID1, /* authorized_entity= */ "",
  202. encrypted_message(), GCMDriverBaseTest::WAIT));
  203. EXPECT_EQ(GCMDecryptionResult::DECRYPTED_DRAFT_08, decryption_result());
  204. EXPECT_EQ(message, decrypted_message());
  205. }
  206. TEST_F(GCMDriverBaseTest, EncryptionError) {
  207. // Intentionally not creating encryption info.
  208. std::string message = "payload";
  209. ASSERT_NO_FATAL_FAILURE(
  210. EncryptMessage(kTestAppID1, /* authorized_entity= */ "", p256dh(),
  211. auth_secret(), message, GCMDriverBaseTest::WAIT));
  212. EXPECT_EQ(GCMEncryptionResult::NO_KEYS, encryption_result());
  213. }
  214. } // namespace gcm