1*e7b1675dSTing-Kang Chang // Copyright 2022 Google LLC 2*e7b1675dSTing-Kang Chang // 3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License"); 4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License. 5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at 6*e7b1675dSTing-Kang Chang // 7*e7b1675dSTing-Kang Chang // http://www.apache.org/licenses/LICENSE-2.0 8*e7b1675dSTing-Kang Chang // 9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software 10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS, 11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and 13*e7b1675dSTing-Kang Chang // limitations under the License. 14*e7b1675dSTing-Kang Chang // 15*e7b1675dSTing-Kang Chang //////////////////////////////////////////////////////////////////////////////// 16*e7b1675dSTing-Kang Chang 17*e7b1675dSTing-Kang Chang #ifndef TINK_KEYSET_HANDLE_BUILDER_H_ 18*e7b1675dSTing-Kang Chang #define TINK_KEYSET_HANDLE_BUILDER_H_ 19*e7b1675dSTing-Kang Chang 20*e7b1675dSTing-Kang Chang #include <memory> 21*e7b1675dSTing-Kang Chang #include <set> 22*e7b1675dSTing-Kang Chang #include <string> 23*e7b1675dSTing-Kang Chang #include <utility> 24*e7b1675dSTing-Kang Chang #include <vector> 25*e7b1675dSTing-Kang Chang 26*e7b1675dSTing-Kang Chang #include "tink/internal/keyset_handle_builder_entry.h" 27*e7b1675dSTing-Kang Chang #include "tink/key.h" 28*e7b1675dSTing-Kang Chang #include "tink/key_status.h" 29*e7b1675dSTing-Kang Chang #include "tink/keyset_handle.h" 30*e7b1675dSTing-Kang Chang #include "tink/parameters.h" 31*e7b1675dSTing-Kang Chang 32*e7b1675dSTing-Kang Chang namespace crypto { 33*e7b1675dSTing-Kang Chang namespace tink { 34*e7b1675dSTing-Kang Chang 35*e7b1675dSTing-Kang Chang // Creates new `KeysetHandle` objects. 36*e7b1675dSTing-Kang Chang class KeysetHandleBuilder { 37*e7b1675dSTing-Kang Chang public: 38*e7b1675dSTing-Kang Chang // Movable, but not copyable. 39*e7b1675dSTing-Kang Chang KeysetHandleBuilder(KeysetHandleBuilder&& other) = default; 40*e7b1675dSTing-Kang Chang KeysetHandleBuilder& operator=(KeysetHandleBuilder&& other) = default; 41*e7b1675dSTing-Kang Chang KeysetHandleBuilder(const KeysetHandleBuilder& other) = delete; 42*e7b1675dSTing-Kang Chang KeysetHandleBuilder& operator=(const KeysetHandleBuilder& other) = delete; 43*e7b1675dSTing-Kang Chang 44*e7b1675dSTing-Kang Chang // Creates initially empty keyset handle builder. 45*e7b1675dSTing-Kang Chang KeysetHandleBuilder() = default; 46*e7b1675dSTing-Kang Chang // Creates keyset handle builder by initially moving keys from `handle`. 47*e7b1675dSTing-Kang Chang explicit KeysetHandleBuilder(const KeysetHandle& handle); 48*e7b1675dSTing-Kang Chang 49*e7b1675dSTing-Kang Chang // Represents a single entry in a `KeysetHandleBuilder`. 50*e7b1675dSTing-Kang Chang class Entry { 51*e7b1675dSTing-Kang Chang public: 52*e7b1675dSTing-Kang Chang // Movable, but not copyable. 53*e7b1675dSTing-Kang Chang Entry(Entry&& other) = default; 54*e7b1675dSTing-Kang Chang Entry& operator=(Entry&& other) = default; 55*e7b1675dSTing-Kang Chang Entry(const Entry& other) = delete; 56*e7b1675dSTing-Kang Chang Entry& operator=(const Entry& other) = delete; 57*e7b1675dSTing-Kang Chang 58*e7b1675dSTing-Kang Chang // Creates new KeysetHandleBuilder::Entry from a given `key`. Also, sets 59*e7b1675dSTing-Kang Chang // key `status` and whether or not the key `is_primary`. 60*e7b1675dSTing-Kang Chang static Entry CreateFromKey(std::shared_ptr<const Key> key, KeyStatus status, 61*e7b1675dSTing-Kang Chang bool is_primary); 62*e7b1675dSTing-Kang Chang 63*e7b1675dSTing-Kang Chang template <typename CopyableKey> CreateFromCopyableKey(CopyableKey key,KeyStatus status,bool is_primary)64*e7b1675dSTing-Kang Chang inline static Entry CreateFromCopyableKey(CopyableKey key, KeyStatus status, 65*e7b1675dSTing-Kang Chang bool is_primary) { 66*e7b1675dSTing-Kang Chang auto copyable_key = absl::make_unique<CopyableKey>(std::move(key)); 67*e7b1675dSTing-Kang Chang return CreateFromKey(std::move(copyable_key), status, is_primary); 68*e7b1675dSTing-Kang Chang } 69*e7b1675dSTing-Kang Chang 70*e7b1675dSTing-Kang Chang // Creates new KeysetHandleBuilder::Entry from given `parameters`. Also, 71*e7b1675dSTing-Kang Chang // sets key `status` and whether or not the key `is_primary`. If `id` 72*e7b1675dSTing-Kang Chang // does not have a value, then the key will be assigned a random id. 73*e7b1675dSTing-Kang Chang static Entry CreateFromParams(std::shared_ptr<const Parameters> parameters, 74*e7b1675dSTing-Kang Chang KeyStatus status, bool is_primary, 75*e7b1675dSTing-Kang Chang absl::optional<int> id = absl::nullopt); 76*e7b1675dSTing-Kang Chang 77*e7b1675dSTing-Kang Chang template <typename CopyableParameters> 78*e7b1675dSTing-Kang Chang inline static Entry CreateFromCopyableParams( 79*e7b1675dSTing-Kang Chang CopyableParameters parameters, KeyStatus status, bool is_primary, 80*e7b1675dSTing-Kang Chang absl::optional<int> id = absl::nullopt) { 81*e7b1675dSTing-Kang Chang auto copyable_params = 82*e7b1675dSTing-Kang Chang absl::make_unique<CopyableParameters>(std::move(parameters)); 83*e7b1675dSTing-Kang Chang return CreateFromParams(std::move(copyable_params), status, is_primary, 84*e7b1675dSTing-Kang Chang id); 85*e7b1675dSTing-Kang Chang } 86*e7b1675dSTing-Kang Chang 87*e7b1675dSTing-Kang Chang // Sets the key status of this entry. SetStatus(KeyStatus status)88*e7b1675dSTing-Kang Chang void SetStatus(KeyStatus status) { entry_->SetStatus(status); } 89*e7b1675dSTing-Kang Chang // Returns key status of this entry. GetStatus()90*e7b1675dSTing-Kang Chang KeyStatus GetStatus() const { return entry_->GetStatus(); } 91*e7b1675dSTing-Kang Chang 92*e7b1675dSTing-Kang Chang // Assigns a fixed id when this keyset is built. SetFixedId(int id)93*e7b1675dSTing-Kang Chang void SetFixedId(int id) { entry_->SetFixedId(id); } 94*e7b1675dSTing-Kang Chang // Assigns an unused random id when this keyset is built. SetRandomId()95*e7b1675dSTing-Kang Chang void SetRandomId() { entry_->SetRandomId(); } 96*e7b1675dSTing-Kang Chang 97*e7b1675dSTing-Kang Chang // Sets this entry as the primary key. SetPrimary()98*e7b1675dSTing-Kang Chang void SetPrimary() { entry_->SetPrimary(); } 99*e7b1675dSTing-Kang Chang // Unsets this entry as the primary key. UnsetPrimary()100*e7b1675dSTing-Kang Chang void UnsetPrimary() { entry_->UnsetPrimary(); } 101*e7b1675dSTing-Kang Chang // Returns whether or not this entry has been marked as a primary. IsPrimary()102*e7b1675dSTing-Kang Chang bool IsPrimary() const { return entry_->IsPrimary(); } 103*e7b1675dSTing-Kang Chang 104*e7b1675dSTing-Kang Chang private: 105*e7b1675dSTing-Kang Chang friend class KeysetHandleBuilder; 106*e7b1675dSTing-Kang Chang Entry(std::unique_ptr<internal::KeysetHandleBuilderEntry> entry)107*e7b1675dSTing-Kang Chang explicit Entry(std::unique_ptr<internal::KeysetHandleBuilderEntry> entry) 108*e7b1675dSTing-Kang Chang : entry_(std::move(entry)) {} 109*e7b1675dSTing-Kang Chang 110*e7b1675dSTing-Kang Chang // Returns whether or not this entry has a randomly assigned id. HasRandomId()111*e7b1675dSTing-Kang Chang bool HasRandomId() { 112*e7b1675dSTing-Kang Chang return entry_->GetKeyIdStrategyEnum() == 113*e7b1675dSTing-Kang Chang internal::KeyIdStrategyEnum::kRandomId; 114*e7b1675dSTing-Kang Chang } 115*e7b1675dSTing-Kang Chang GetKeyIdStrategy()116*e7b1675dSTing-Kang Chang internal::KeyIdStrategy GetKeyIdStrategy() { 117*e7b1675dSTing-Kang Chang return entry_->GetKeyIdStrategy(); 118*e7b1675dSTing-Kang Chang } 119*e7b1675dSTing-Kang Chang 120*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<google::crypto::tink::Keyset::Key> CreateKeysetKey(int id)121*e7b1675dSTing-Kang Chang CreateKeysetKey(int id) { 122*e7b1675dSTing-Kang Chang return entry_->CreateKeysetKey(id); 123*e7b1675dSTing-Kang Chang } 124*e7b1675dSTing-Kang Chang 125*e7b1675dSTing-Kang Chang std::unique_ptr<internal::KeysetHandleBuilderEntry> entry_; 126*e7b1675dSTing-Kang Chang bool added_to_builder_ = false; 127*e7b1675dSTing-Kang Chang }; 128*e7b1675dSTing-Kang Chang 129*e7b1675dSTing-Kang Chang // Adds an `entry` to the keyset builder. Crashes if `entry` has already been 130*e7b1675dSTing-Kang Chang // added to a keyset handle builder. 131*e7b1675dSTing-Kang Chang KeysetHandleBuilder& AddEntry(KeysetHandleBuilder::Entry entry); 132*e7b1675dSTing-Kang Chang // Removes an entry at `index` from keyset builder. 133*e7b1675dSTing-Kang Chang KeysetHandleBuilder& RemoveEntry(int index); 134*e7b1675dSTing-Kang Chang 135*e7b1675dSTing-Kang Chang // Returns the number of Entry objects in this keyset builder. size()136*e7b1675dSTing-Kang Chang int size() const { return entries_.size(); } 137*e7b1675dSTing-Kang Chang 138*e7b1675dSTing-Kang Chang // Returns entry from keyset builder at `index`. 139*e7b1675dSTing-Kang Chang KeysetHandleBuilder::Entry& operator[](int index) { return entries_[index]; } 140*e7b1675dSTing-Kang Chang 141*e7b1675dSTing-Kang Chang // Creates a new `KeysetHandle` object. 142*e7b1675dSTing-Kang Chang // 143*e7b1675dSTing-Kang Chang // Note: Since KeysetHandleBuilder::Entry objects might have randomly 144*e7b1675dSTing-Kang Chang // generated IDs, Build() can only be called once on a single 145*e7b1675dSTing-Kang Chang // KeysetHandleBuilder object. Otherwise, the KeysetHandleBuilder::Entry 146*e7b1675dSTing-Kang Chang // IDs would randomly change for each call to Build(), which would result 147*e7b1675dSTing-Kang Chang // in incompatible keysets. 148*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<KeysetHandle> Build(); 149*e7b1675dSTing-Kang Chang 150*e7b1675dSTing-Kang Chang private: 151*e7b1675dSTing-Kang Chang // Select the next key id based on the given strategy. 152*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<int> NextIdFromKeyIdStrategy( 153*e7b1675dSTing-Kang Chang internal::KeyIdStrategy strategy, const std::set<int>& ids_so_far); 154*e7b1675dSTing-Kang Chang 155*e7b1675dSTing-Kang Chang // Unset primary flag on all entries. 156*e7b1675dSTing-Kang Chang void ClearPrimary(); 157*e7b1675dSTing-Kang Chang 158*e7b1675dSTing-Kang Chang // Verify that entries with fixed IDs do not follow entries with random IDs. 159*e7b1675dSTing-Kang Chang crypto::tink::util::Status CheckIdAssignments(); 160*e7b1675dSTing-Kang Chang 161*e7b1675dSTing-Kang Chang std::vector<KeysetHandleBuilder::Entry> entries_; 162*e7b1675dSTing-Kang Chang 163*e7b1675dSTing-Kang Chang bool build_called_ = false; 164*e7b1675dSTing-Kang Chang }; 165*e7b1675dSTing-Kang Chang 166*e7b1675dSTing-Kang Chang } // namespace tink 167*e7b1675dSTing-Kang Chang } // namespace crypto 168*e7b1675dSTing-Kang Chang 169*e7b1675dSTing-Kang Chang #endif // TINK_KEYSET_HANDLE_BUILDER_H_ 170