PageRenderTime 137ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/ash/services/device_sync/cryptauth_metadata_syncer_impl.h

https://github.com/chromium/chromium
C Header | 199 lines | 118 code | 36 blank | 45 comment | 0 complexity | ebd2f8dda1a20faf83c971dbc443d295 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause
  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. #ifndef ASH_SERVICES_DEVICE_SYNC_CRYPTAUTH_METADATA_SYNCER_IMPL_H_
  5. #define ASH_SERVICES_DEVICE_SYNC_CRYPTAUTH_METADATA_SYNCER_IMPL_H_
  6. #include <memory>
  7. #include <ostream>
  8. #include <string>
  9. #include "ash/services/device_sync/cryptauth_device_sync_result.h"
  10. #include "ash/services/device_sync/cryptauth_key.h"
  11. #include "ash/services/device_sync/cryptauth_key_bundle.h"
  12. #include "ash/services/device_sync/cryptauth_metadata_syncer.h"
  13. #include "ash/services/device_sync/network_request_error.h"
  14. #include "ash/services/device_sync/proto/cryptauth_better_together_device_metadata.pb.h"
  15. #include "ash/services/device_sync/proto/cryptauth_devicesync.pb.h"
  16. #include "ash/services/device_sync/proto/cryptauth_directive.pb.h"
  17. #include "base/containers/flat_map.h"
  18. #include "base/time/time.h"
  19. #include "base/timer/timer.h"
  20. #include "third_party/abseil-cpp/absl/types/optional.h"
  21. class PrefRegistrySimple;
  22. class PrefService;
  23. namespace ash {
  24. namespace device_sync {
  25. class CryptAuthClient;
  26. class CryptAuthClientFactory;
  27. class CryptAuthEciesEncryptor;
  28. class CryptAuthKeyCreator;
  29. // An implementation of CryptAuthMetadataSyncer, using instances of
  30. // CryptAuthClient to make the SyncMetadata API calls to CryptAuth. Timeouts are
  31. // handled internally, so ShareGroupPrivateKey() is always guaranteed to return.
  32. //
  33. // All returned DeviceMetadataPackets are guaranteed to have a nontrivial device
  34. // ID, device name, and device public key.
  35. class CryptAuthMetadataSyncerImpl : public CryptAuthMetadataSyncer {
  36. public:
  37. class Factory {
  38. public:
  39. static std::unique_ptr<CryptAuthMetadataSyncer> Create(
  40. CryptAuthClientFactory* client_factory,
  41. PrefService* pref_service,
  42. std::unique_ptr<base::OneShotTimer> timer =
  43. std::make_unique<base::OneShotTimer>());
  44. static void SetFactoryForTesting(Factory* test_factory);
  45. protected:
  46. virtual ~Factory();
  47. virtual std::unique_ptr<CryptAuthMetadataSyncer> CreateInstance(
  48. CryptAuthClientFactory* client_factory,
  49. PrefService* pref_service,
  50. std::unique_ptr<base::OneShotTimer> timer) = 0;
  51. private:
  52. static Factory* test_factory_;
  53. };
  54. // Registers the prefs used by this class to the given |registry|.
  55. static void RegisterPrefs(PrefRegistrySimple* registry);
  56. CryptAuthMetadataSyncerImpl(const CryptAuthMetadataSyncerImpl&) = delete;
  57. CryptAuthMetadataSyncerImpl& operator=(const CryptAuthMetadataSyncerImpl&) =
  58. delete;
  59. ~CryptAuthMetadataSyncerImpl() override;
  60. private:
  61. enum class State {
  62. kNotStarted,
  63. kWaitingForGroupKeyCreation,
  64. kWaitingForLocalDeviceMetadataEncryption,
  65. kWaitingForFirstSyncMetadataResponse,
  66. kWaitingForSecondSyncMetadataResponse,
  67. kFinished
  68. };
  69. friend std::ostream& operator<<(std::ostream& stream, const State& state);
  70. // kKeyExistsButNotConfirmedWithCryptAuth: A local group public key exists but
  71. // CryptAuth has yet to confirm or deny that it is the correct group key.
  72. // kNewKeyNeedsToBeCreate: Either a local group public key does not exist or
  73. // an empty group_public_key field in the first SyncMetadataResponse is a
  74. // signal from CryptAuth that we should generate a new group key pair and
  75. // make another SyncMetadataRequest.
  76. // kNewKeyReceivedFromCryptAuth: If our local group public key differs from
  77. // the one received from CryptAuth, replace the local key and make another
  78. // SyncMetadataRequest. The group private key will be provided in the next
  79. // SyncMetadataResponse if available.
  80. // kEstablished: Our local group public key agrees with the group_public_key
  81. // field sent in the latest SyncMetadataResponse. It should take at most
  82. // two SyncMetadata calls to establish the group public key.
  83. enum class GroupPublicKeyState {
  84. kUndetermined,
  85. kKeyExistsButNotConfirmedWithCryptAuth,
  86. kNewKeyNeedsToBeCreated,
  87. kNewKeyReceivedFromCryptAuth,
  88. kEstablished
  89. };
  90. friend std::ostream& operator<<(std::ostream& stream,
  91. const GroupPublicKeyState& state);
  92. static absl::optional<base::TimeDelta> GetTimeoutForState(State state);
  93. static absl::optional<CryptAuthDeviceSyncResult::ResultCode>
  94. ResultCodeErrorFromTimeoutDuringState(State state);
  95. // CryptAuthMetadataSyncer:
  96. void OnAttemptStarted(
  97. const cryptauthv2::RequestContext& request_context,
  98. const cryptauthv2::BetterTogetherDeviceMetadata& local_device_metadata,
  99. const CryptAuthKey* initial_group_key) override;
  100. CryptAuthMetadataSyncerImpl(CryptAuthClientFactory* client_factory,
  101. PrefService* pref_service,
  102. std::unique_ptr<base::OneShotTimer> timer);
  103. void SetState(State state);
  104. void OnTimeout();
  105. const CryptAuthKey* GetGroupKey();
  106. GroupPublicKeyState GetGroupPublicKeyState();
  107. void AttemptNextStep();
  108. // If the local device metadata and the encrypting group public key have not
  109. // changed since they were last cached, reuse the cached encrypted local
  110. // device metadata. Because the ECIES encryptor uses a different session key
  111. // for each encryption, the blob could change even if the underlying metadata
  112. // and group public key have not changed. We do not want the CryptAuth server
  113. // to act as though device metadata has changed if the underlying data and
  114. // encrypting key remain the same.
  115. bool ShouldUseCachedEncryptedLocalDeviceMetadata();
  116. void EncryptLocalDeviceMetadata();
  117. void OnLocalDeviceMetadataEncrypted(
  118. const absl::optional<std::string>& encrypted_metadata);
  119. void CreateGroupKey();
  120. void OnGroupKeyCreated(
  121. const base::flat_map<CryptAuthKeyBundle::Name,
  122. absl::optional<CryptAuthKey>>& new_keys,
  123. const absl::optional<CryptAuthKey>& client_ephemeral_dh);
  124. void MakeSyncMetadataCall();
  125. void OnSyncMetadataSuccess(const cryptauthv2::SyncMetadataResponse& response);
  126. void OnSyncMetadataFailure(NetworkRequestError error);
  127. void FilterMetadataAndFinishAttempt();
  128. void FinishAttempt(CryptAuthDeviceSyncResult::ResultCode result_code);
  129. size_t num_sync_metadata_calls_ = 0;
  130. cryptauthv2::RequestContext request_context_;
  131. cryptauthv2::BetterTogetherDeviceMetadata local_device_metadata_;
  132. absl::optional<std::string> encrypted_local_device_metadata_;
  133. absl::optional<cryptauthv2::SyncMetadataResponse> sync_metadata_response_;
  134. // The filtered map of DeviceMetadataPackets from the SyncMetadataResponse,
  135. // keyed by device ID. All DeviceMetadataPackets are guaranteed to have a
  136. // nontrivial device ID, device name, and device public key.
  137. base::flat_map<std::string, cryptauthv2::DeviceMetadataPacket>
  138. id_to_device_metadata_packet_map_;
  139. // Non-null if a new group key is created or if CryptAuth sends a new group
  140. // public key during the SyncMetadata flow. This value is returned in a
  141. // callback when the attempt finishes.
  142. std::unique_ptr<CryptAuthKey> new_group_key_;
  143. // The CryptAuthClient for the latest CryptAuth request. The client can only
  144. // be used for one call; therefore, for each API call, a new client needs to
  145. // be generated from |client_factory_|.
  146. std::unique_ptr<CryptAuthClient> cryptauth_client_;
  147. // Used to generate the group key pair if necessary.
  148. std::unique_ptr<CryptAuthKeyCreator> key_creator_;
  149. // The CryptAuthEciesEncryptor for the latest encryption/decryption. An
  150. // instance can only be used for one method call; therefore, for each
  151. // encryption/decryption, a new encryptor needs to be generated.
  152. std::unique_ptr<CryptAuthEciesEncryptor> encryptor_;
  153. // The time of the last state change. Used for execution time metrics.
  154. base::TimeTicks last_state_change_timestamp_;
  155. State state_ = State::kNotStarted;
  156. const CryptAuthKey* initial_group_key_;
  157. CryptAuthClientFactory* client_factory_ = nullptr;
  158. PrefService* pref_service_ = nullptr;
  159. std::unique_ptr<base::OneShotTimer> timer_;
  160. };
  161. } // namespace device_sync
  162. } // namespace ash
  163. #endif // ASH_SERVICES_DEVICE_SYNC_CRYPTAUTH_METADATA_SYNCER_IMPL_H_