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 5 #ifndef CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_KEY_BUNDLE_H_ 6 #define CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_KEY_BUNDLE_H_ 7 8 #include "base/containers/flat_map.h" 9 #include "base/containers/flat_set.h" 10 #include "base/optional.h" 11 #include "base/values.h" 12 #include "chromeos/services/device_sync/cryptauth_key.h" 13 #include "chromeos/services/device_sync/proto/cryptauth_directive.pb.h" 14 15 namespace chromeos { 16 17 namespace device_sync { 18 19 // A group of related CryptAuthKeys, uniquely identified by their handles. 20 // 21 // No more than one key in the bundle can be active at a time, and only the 22 // active key should be used for encryption, signing, etc. Inactive keys are 23 // retained and can be activated in the future, for example, due to a 24 // SyncSingleKeyResponse::KeyAction sent by CryptAuth. 25 // 26 // All key bundles used in Chrome OS are enumerated in the Name enum class. The 27 // name string corresponding to each enum value can be retrieved via 28 // KeyBundleNameEnumToString(). For key bundles that enroll with CryptAuth, this 29 // string is used to populate the SyncSingleKeysRequest::key_name protobuf 30 // field. 31 class CryptAuthKeyBundle { 32 public: 33 // Names that uniquely define a CryptAuthKeyBundle. 34 enum class Name { 35 // A non-rotated asymmetric key associated with a user on the device. It is 36 // used for encrypting device-to-device communications, for example, and it 37 // has historically been used as a device identifier. 38 kUserKeyPair, 39 // Currently unused but required for CryptAuth v2 Enrollment. 40 kLegacyAuthzenKey, 41 // Enrolling this asymmetric key adds the device to the user's DeviceSync v2 42 // "DeviceSync:BetterTogether" group. This key is not to be confused with 43 // the unenrolled kDeviceSyncBetterTogetherGroupKey. 44 kDeviceSyncBetterTogether, 45 // A key pair that does *not* enroll with CryptAuth, used to encrypt and 46 // decrypt the metadata of all devices in the user's 47 // "DeviceSync:BetterTogether" group. This metadata is passed in an 48 // end-to-end encrypted fashion via DeviceSync v2 SyncMetadata calls . 49 kDeviceSyncBetterTogetherGroupKey 50 }; 51 52 // Returns all Name enum values as a set. 53 static const base::flat_set<CryptAuthKeyBundle::Name>& AllNames(); 54 55 // Returns the Name enum value of all key bundles that enroll with CryptAuth. 56 static const base::flat_set<CryptAuthKeyBundle::Name>& AllEnrollableNames(); 57 58 static std::string KeyBundleNameEnumToString(CryptAuthKeyBundle::Name name); 59 static base::Optional<CryptAuthKeyBundle::Name> KeyBundleNameStringToEnum( 60 const std::string& name); 61 62 static base::Optional<CryptAuthKeyBundle> FromDictionary( 63 const base::Value& dict); 64 65 CryptAuthKeyBundle(Name name); 66 67 CryptAuthKeyBundle(const CryptAuthKeyBundle&); 68 69 ~CryptAuthKeyBundle(); 70 name()71 Name name() const { return name_; } 72 handle_to_key_map()73 const base::flat_map<std::string, CryptAuthKey>& handle_to_key_map() const { 74 return handle_to_key_map_; 75 } 76 key_directive()77 const base::Optional<cryptauthv2::KeyDirective>& key_directive() const { 78 return key_directive_; 79 } 80 set_key_directive(const cryptauthv2::KeyDirective & key_directive)81 void set_key_directive(const cryptauthv2::KeyDirective& key_directive) { 82 key_directive_ = key_directive; 83 } 84 85 // Returns nullptr if there is no active key. 86 const CryptAuthKey* GetActiveKey() const; 87 88 // If the key being added is active, all other keys in the bundle will be 89 // deactivated. If the handle of the input key matches one in the bundle, the 90 // existing key will be overwritten. 91 // Note: All keys added to the bundle kUserKeyPair must have the handle 92 // kCryptAuthFixedUserKeyPairHandle. 93 void AddKey(const CryptAuthKey& key); 94 95 // Activates the key corresponding to |handle| in the bundle and deactivates 96 // the other keys. 97 void SetActiveKey(const std::string& handle); 98 99 // Sets all key statuses to kInactive. 100 void DeactivateKeys(); 101 102 // Remove the key corresponding to |handle| from the bundle. 103 void DeleteKey(const std::string& handle); 104 105 base::Value AsDictionary() const; 106 107 bool operator==(const CryptAuthKeyBundle& other) const; 108 bool operator!=(const CryptAuthKeyBundle& other) const; 109 110 private: 111 Name name_; 112 base::flat_map<std::string, CryptAuthKey> handle_to_key_map_; 113 base::Optional<cryptauthv2::KeyDirective> key_directive_; 114 }; 115 116 } // namespace device_sync 117 118 } // namespace chromeos 119 120 #endif // CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_KEY_BUNDLE_H_ 121