1*e7b1675dSTing-Kang Chang // Copyright 2017 Google Inc.
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_H_
18*e7b1675dSTing-Kang Chang #define TINK_KEYSET_HANDLE_H_
19*e7b1675dSTing-Kang Chang
20*e7b1675dSTing-Kang Chang #include <cstdint>
21*e7b1675dSTing-Kang Chang #include <memory>
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 "absl/base/attributes.h"
27*e7b1675dSTing-Kang Chang #include "absl/container/flat_hash_map.h"
28*e7b1675dSTing-Kang Chang #include "absl/memory/memory.h"
29*e7b1675dSTing-Kang Chang #include "absl/status/status.h"
30*e7b1675dSTing-Kang Chang #include "tink/aead.h"
31*e7b1675dSTing-Kang Chang #include "tink/configuration.h"
32*e7b1675dSTing-Kang Chang #include "tink/internal/configuration_impl.h"
33*e7b1675dSTing-Kang Chang #include "tink/internal/key_info.h"
34*e7b1675dSTing-Kang Chang #include "tink/key.h"
35*e7b1675dSTing-Kang Chang #include "tink/key_gen_configuration.h"
36*e7b1675dSTing-Kang Chang #include "tink/key_manager.h"
37*e7b1675dSTing-Kang Chang #include "tink/key_status.h"
38*e7b1675dSTing-Kang Chang #include "tink/keyset_reader.h"
39*e7b1675dSTing-Kang Chang #include "tink/keyset_writer.h"
40*e7b1675dSTing-Kang Chang #include "tink/primitive_set.h"
41*e7b1675dSTing-Kang Chang #include "tink/registry.h"
42*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h"
43*e7b1675dSTing-Kang Chang #include "proto/tink.pb.h"
44*e7b1675dSTing-Kang Chang
45*e7b1675dSTing-Kang Chang namespace crypto {
46*e7b1675dSTing-Kang Chang namespace tink {
47*e7b1675dSTing-Kang Chang
48*e7b1675dSTing-Kang Chang // KeysetHandle provides abstracted access to Keysets, to limit
49*e7b1675dSTing-Kang Chang // the exposure of actual protocol buffers that hold sensitive
50*e7b1675dSTing-Kang Chang // key material.
51*e7b1675dSTing-Kang Chang class KeysetHandle {
52*e7b1675dSTing-Kang Chang public:
53*e7b1675dSTing-Kang Chang // Represents a single entry in a `KeysetHandle`. Some current behavior will
54*e7b1675dSTing-Kang Chang // be changed in the future.
55*e7b1675dSTing-Kang Chang class Entry {
56*e7b1675dSTing-Kang Chang public:
57*e7b1675dSTing-Kang Chang // May return an internal class in case there is no implementation of the
58*e7b1675dSTing-Kang Chang // corresponding key class yet. Returned value only valid for lifetime
59*e7b1675dSTing-Kang Chang // of entry object.
GetKey()60*e7b1675dSTing-Kang Chang std::shared_ptr<const Key> GetKey() const { return key_; }
61*e7b1675dSTing-Kang Chang
62*e7b1675dSTing-Kang Chang // Status indicates whether or not a key should still be used.
GetStatus()63*e7b1675dSTing-Kang Chang KeyStatus GetStatus() const { return status_; }
64*e7b1675dSTing-Kang Chang
65*e7b1675dSTing-Kang Chang // ID should be unique (though currently Tink still accepts keysets with
66*e7b1675dSTing-Kang Chang // repeated IDs).
GetId()67*e7b1675dSTing-Kang Chang int GetId() const { return id_; }
68*e7b1675dSTing-Kang Chang
69*e7b1675dSTing-Kang Chang // Should return true for exactly one entry (though currently Tink still
70*e7b1675dSTing-Kang Chang // accepts keysets which have no entry marked as primary).
IsPrimary()71*e7b1675dSTing-Kang Chang bool IsPrimary() const { return is_primary_; }
72*e7b1675dSTing-Kang Chang
73*e7b1675dSTing-Kang Chang private:
74*e7b1675dSTing-Kang Chang friend class KeysetHandle;
75*e7b1675dSTing-Kang Chang friend class KeysetHandleBuilder;
76*e7b1675dSTing-Kang Chang
Entry(std::shared_ptr<const Key> key,KeyStatus status,int id,bool is_primary)77*e7b1675dSTing-Kang Chang Entry(std::shared_ptr<const Key> key, KeyStatus status, int id,
78*e7b1675dSTing-Kang Chang bool is_primary)
79*e7b1675dSTing-Kang Chang : key_(std::move(key)),
80*e7b1675dSTing-Kang Chang status_(status),
81*e7b1675dSTing-Kang Chang id_(id),
82*e7b1675dSTing-Kang Chang is_primary_(is_primary) {}
83*e7b1675dSTing-Kang Chang
84*e7b1675dSTing-Kang Chang std::shared_ptr<const Key> key_;
85*e7b1675dSTing-Kang Chang KeyStatus status_;
86*e7b1675dSTing-Kang Chang int id_;
87*e7b1675dSTing-Kang Chang bool is_primary_;
88*e7b1675dSTing-Kang Chang };
89*e7b1675dSTing-Kang Chang
90*e7b1675dSTing-Kang Chang // Returns the number of entries in this keyset.
size()91*e7b1675dSTing-Kang Chang int size() const { return keyset_.key_size(); }
92*e7b1675dSTing-Kang Chang // Validates single `KeysetHandle::Entry` at `index` by making sure that the
93*e7b1675dSTing-Kang Chang // key entry's type URL is printable and that it has a valid key status.
94*e7b1675dSTing-Kang Chang crypto::tink::util::Status ValidateAt(int index) const;
95*e7b1675dSTing-Kang Chang // Validates each individual `KeysetHandle::Entry` in keyset handle by calling
96*e7b1675dSTing-Kang Chang // `ValidateAt()`. Also, checks that there is a single enabled primary key.
97*e7b1675dSTing-Kang Chang crypto::tink::util::Status Validate() const;
98*e7b1675dSTing-Kang Chang // Returns entry for primary key in this keyset. Crashes if `Validate()`
99*e7b1675dSTing-Kang Chang // does not return an OK status. Call `Validate()` prior to calling this
100*e7b1675dSTing-Kang Chang // method to avoid potentially crashing your program.
101*e7b1675dSTing-Kang Chang Entry GetPrimary() const;
102*e7b1675dSTing-Kang Chang // Returns the `KeysetHandle::Entry` at `index`. Crashes if
103*e7b1675dSTing-Kang Chang // `ValidateAt(index)` does not return an OK status. Call `ValidateAt(index)`
104*e7b1675dSTing-Kang Chang // prior to calling this method to avoid potentially crashing your program.
105*e7b1675dSTing-Kang Chang Entry operator[](int index) const;
106*e7b1675dSTing-Kang Chang
107*e7b1675dSTing-Kang Chang // Creates a KeysetHandle from an encrypted keyset obtained via `reader`
108*e7b1675dSTing-Kang Chang // using `master_key_aead` to decrypt the keyset, with monitoring annotations
109*e7b1675dSTing-Kang Chang // `monitoring_annotations`; by default, `monitoring_annotations` is empty.
110*e7b1675dSTing-Kang Chang static crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>> Read(
111*e7b1675dSTing-Kang Chang std::unique_ptr<KeysetReader> reader, const Aead& master_key_aead,
112*e7b1675dSTing-Kang Chang const absl::flat_hash_map<std::string, std::string>&
113*e7b1675dSTing-Kang Chang monitoring_annotations = {});
114*e7b1675dSTing-Kang Chang
115*e7b1675dSTing-Kang Chang // Creates a KeysetHandle from an encrypted keyset obtained via `reader`
116*e7b1675dSTing-Kang Chang // using `master_key_aead` to decrypt the keyset, expecting `associated_data`.
117*e7b1675dSTing-Kang Chang // The keyset is annotated for monitoring with `monitoring_annotations`; by
118*e7b1675dSTing-Kang Chang // default, `monitoring_annotations` is empty.
119*e7b1675dSTing-Kang Chang static crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
120*e7b1675dSTing-Kang Chang ReadWithAssociatedData(std::unique_ptr<KeysetReader> reader,
121*e7b1675dSTing-Kang Chang const Aead& master_key_aead,
122*e7b1675dSTing-Kang Chang absl::string_view associated_data,
123*e7b1675dSTing-Kang Chang const absl::flat_hash_map<std::string, std::string>&
124*e7b1675dSTing-Kang Chang monitoring_annotations = {});
125*e7b1675dSTing-Kang Chang
126*e7b1675dSTing-Kang Chang // Creates a KeysetHandle from a serialized keyset `serialized_keyset` which
127*e7b1675dSTing-Kang Chang // contains no secret key material, and annotates it with
128*e7b1675dSTing-Kang Chang // `monitoring_annotations` for monitoring; by default,
129*e7b1675dSTing-Kang Chang // `monitoring_annotations` is empty. This can be used to load public keysets
130*e7b1675dSTing-Kang Chang // or envelope encryption keysets.
131*e7b1675dSTing-Kang Chang static crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
132*e7b1675dSTing-Kang Chang ReadNoSecret(const std::string& serialized_keyset,
133*e7b1675dSTing-Kang Chang const absl::flat_hash_map<std::string, std::string>&
134*e7b1675dSTing-Kang Chang monitoring_annotations = {});
135*e7b1675dSTing-Kang Chang
136*e7b1675dSTing-Kang Chang // Returns a KeysetHandle containing a single new key generated according to
137*e7b1675dSTing-Kang Chang // `key_template` and using `config`. The keyset is annotated for monitoring
138*e7b1675dSTing-Kang Chang // with `monitoring_annotations`, which is empty by default.
139*e7b1675dSTing-Kang Chang static crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
140*e7b1675dSTing-Kang Chang GenerateNew(const google::crypto::tink::KeyTemplate& key_template,
141*e7b1675dSTing-Kang Chang const crypto::tink::KeyGenConfiguration& config,
142*e7b1675dSTing-Kang Chang const absl::flat_hash_map<std::string, std::string>&
143*e7b1675dSTing-Kang Chang monitoring_annotations = {});
144*e7b1675dSTing-Kang Chang
145*e7b1675dSTing-Kang Chang // TODO(b/265865177): Deprecate.
146*e7b1675dSTing-Kang Chang // Returns a KeysetHandle containing a single new key generated according to
147*e7b1675dSTing-Kang Chang // `key_template`. The keyset is annotated for monitoring with
148*e7b1675dSTing-Kang Chang // `monitoring_annotations`, which is empty by default.
149*e7b1675dSTing-Kang Chang static crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
150*e7b1675dSTing-Kang Chang GenerateNew(const google::crypto::tink::KeyTemplate& key_template,
151*e7b1675dSTing-Kang Chang const absl::flat_hash_map<std::string, std::string>&
152*e7b1675dSTing-Kang Chang monitoring_annotations = {});
153*e7b1675dSTing-Kang Chang
154*e7b1675dSTing-Kang Chang // Encrypts the underlying keyset with the provided `master_key_aead`
155*e7b1675dSTing-Kang Chang // and writes the resulting EncryptedKeyset to the given `writer`,
156*e7b1675dSTing-Kang Chang // which must be non-null.
157*e7b1675dSTing-Kang Chang crypto::tink::util::Status Write(KeysetWriter* writer,
158*e7b1675dSTing-Kang Chang const Aead& master_key_aead) const;
159*e7b1675dSTing-Kang Chang
160*e7b1675dSTing-Kang Chang // Encrypts the underlying keyset with the provided `master_key_aead`, using
161*e7b1675dSTing-Kang Chang // `associated_data`. and writes the resulting EncryptedKeyset to the given
162*e7b1675dSTing-Kang Chang // `writer`, which must be non-null.
163*e7b1675dSTing-Kang Chang crypto::tink::util::Status WriteWithAssociatedData(
164*e7b1675dSTing-Kang Chang KeysetWriter* writer, const Aead& master_key_aead,
165*e7b1675dSTing-Kang Chang absl::string_view associated_data) const;
166*e7b1675dSTing-Kang Chang
167*e7b1675dSTing-Kang Chang // Returns KeysetInfo, a "safe" Keyset that doesn't contain any actual
168*e7b1675dSTing-Kang Chang // key material, thus can be used for logging or monitoring.
169*e7b1675dSTing-Kang Chang google::crypto::tink::KeysetInfo GetKeysetInfo() const;
170*e7b1675dSTing-Kang Chang
171*e7b1675dSTing-Kang Chang // Writes the underlying keyset to `writer` only if the keyset does not
172*e7b1675dSTing-Kang Chang // contain any secret key material.
173*e7b1675dSTing-Kang Chang // This can be used to persist public keysets or envelope encryption keysets.
174*e7b1675dSTing-Kang Chang // Users that need to persist cleartext keysets can use
175*e7b1675dSTing-Kang Chang // `CleartextKeysetHandle`.
176*e7b1675dSTing-Kang Chang crypto::tink::util::Status WriteNoSecret(KeysetWriter* writer) const;
177*e7b1675dSTing-Kang Chang
178*e7b1675dSTing-Kang Chang // Returns a new KeysetHandle containing public keys corresponding to the
179*e7b1675dSTing-Kang Chang // private keys in this handle. Relies on key type managers stored in `config`
180*e7b1675dSTing-Kang Chang // to do so. Returns an error if this handle contains keys that are not
181*e7b1675dSTing-Kang Chang // private keys.
182*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
183*e7b1675dSTing-Kang Chang GetPublicKeysetHandle(const KeyGenConfiguration& config) const;
184*e7b1675dSTing-Kang Chang
185*e7b1675dSTing-Kang Chang // Returns a new KeysetHandle containing public keys corresponding to the
186*e7b1675dSTing-Kang Chang // private keys in this handle. Relies on key type managers stored in the
187*e7b1675dSTing-Kang Chang // global registry to do so. Returns an error if this handle contains keys
188*e7b1675dSTing-Kang Chang // that are not private keys.
189*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
190*e7b1675dSTing-Kang Chang GetPublicKeysetHandle() const;
191*e7b1675dSTing-Kang Chang
192*e7b1675dSTing-Kang Chang // Creates a wrapped primitive using this keyset handle and config, which
193*e7b1675dSTing-Kang Chang // stores necessary primitive wrappers and key type managers.
194*e7b1675dSTing-Kang Chang template <class P>
195*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<P>> GetPrimitive(
196*e7b1675dSTing-Kang Chang const Configuration& config) const;
197*e7b1675dSTing-Kang Chang
198*e7b1675dSTing-Kang Chang // Creates a wrapped primitive using this keyset handle and the global
199*e7b1675dSTing-Kang Chang // registry, which stores necessary primitive wrappers and key type managers.
200*e7b1675dSTing-Kang Chang template <class P>
201*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<P>> GetPrimitive() const;
202*e7b1675dSTing-Kang Chang
203*e7b1675dSTing-Kang Chang // Creates a wrapped primitive corresponding to this keyset. Uses the given
204*e7b1675dSTing-Kang Chang // KeyManager, as well as the KeyManager and PrimitiveWrapper objects in the
205*e7b1675dSTing-Kang Chang // global registry to create the primitive. The given KeyManager is used for
206*e7b1675dSTing-Kang Chang // keys supported by it. For those, the registry is ignored.
207*e7b1675dSTing-Kang Chang template <class P>
208*e7b1675dSTing-Kang Chang ABSL_DEPRECATED("Register the keymanager and use GetPrimitive")
209*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<P>> GetPrimitive(
210*e7b1675dSTing-Kang Chang const KeyManager<P>* custom_manager) const;
211*e7b1675dSTing-Kang Chang
212*e7b1675dSTing-Kang Chang private:
213*e7b1675dSTing-Kang Chang // The classes below need access to get_keyset();
214*e7b1675dSTing-Kang Chang friend class CleartextKeysetHandle;
215*e7b1675dSTing-Kang Chang friend class KeysetManager;
216*e7b1675dSTing-Kang Chang
217*e7b1675dSTing-Kang Chang // TestKeysetHandle::GetKeyset() provides access to get_keyset().
218*e7b1675dSTing-Kang Chang friend class TestKeysetHandle;
219*e7b1675dSTing-Kang Chang
220*e7b1675dSTing-Kang Chang // KeysetHandleBuilder::Build() needs access to KeysetHandle(Keyset).
221*e7b1675dSTing-Kang Chang friend class KeysetHandleBuilder;
222*e7b1675dSTing-Kang Chang
223*e7b1675dSTing-Kang Chang // Creates a handle that contains the given keyset.
KeysetHandle(google::crypto::tink::Keyset keyset)224*e7b1675dSTing-Kang Chang explicit KeysetHandle(google::crypto::tink::Keyset keyset)
225*e7b1675dSTing-Kang Chang : keyset_(std::move(keyset)) {}
KeysetHandle(std::unique_ptr<google::crypto::tink::Keyset> keyset)226*e7b1675dSTing-Kang Chang explicit KeysetHandle(std::unique_ptr<google::crypto::tink::Keyset> keyset)
227*e7b1675dSTing-Kang Chang : keyset_(std::move(*keyset)) {}
228*e7b1675dSTing-Kang Chang // Creates a handle that contains the given `keyset` and `entries`.
KeysetHandle(google::crypto::tink::Keyset keyset,const std::vector<std::shared_ptr<const Entry>> & entries)229*e7b1675dSTing-Kang Chang explicit KeysetHandle(
230*e7b1675dSTing-Kang Chang google::crypto::tink::Keyset keyset,
231*e7b1675dSTing-Kang Chang const std::vector<std::shared_ptr<const Entry>>& entries)
232*e7b1675dSTing-Kang Chang : keyset_(std::move(keyset)), entries_(entries) {}
KeysetHandle(std::unique_ptr<google::crypto::tink::Keyset> keyset,const std::vector<std::shared_ptr<const Entry>> & entries)233*e7b1675dSTing-Kang Chang explicit KeysetHandle(
234*e7b1675dSTing-Kang Chang std::unique_ptr<google::crypto::tink::Keyset> keyset,
235*e7b1675dSTing-Kang Chang const std::vector<std::shared_ptr<const Entry>>& entries)
236*e7b1675dSTing-Kang Chang : keyset_(std::move(*keyset)), entries_(entries) {}
237*e7b1675dSTing-Kang Chang // Creates a handle that contains the given `keyset` and
238*e7b1675dSTing-Kang Chang // `monitoring_annotations`.
KeysetHandle(google::crypto::tink::Keyset keyset,const absl::flat_hash_map<std::string,std::string> & monitoring_annotations)239*e7b1675dSTing-Kang Chang KeysetHandle(google::crypto::tink::Keyset keyset,
240*e7b1675dSTing-Kang Chang const absl::flat_hash_map<std::string, std::string>&
241*e7b1675dSTing-Kang Chang monitoring_annotations)
242*e7b1675dSTing-Kang Chang : keyset_(std::move(keyset)),
243*e7b1675dSTing-Kang Chang monitoring_annotations_(monitoring_annotations) {}
KeysetHandle(std::unique_ptr<google::crypto::tink::Keyset> keyset,const absl::flat_hash_map<std::string,std::string> & monitoring_annotations)244*e7b1675dSTing-Kang Chang KeysetHandle(std::unique_ptr<google::crypto::tink::Keyset> keyset,
245*e7b1675dSTing-Kang Chang const absl::flat_hash_map<std::string, std::string>&
246*e7b1675dSTing-Kang Chang monitoring_annotations)
247*e7b1675dSTing-Kang Chang : keyset_(std::move(*keyset)),
248*e7b1675dSTing-Kang Chang monitoring_annotations_(monitoring_annotations) {}
249*e7b1675dSTing-Kang Chang // Creates a handle that contains the given `keyset`, `entries`, and
250*e7b1675dSTing-Kang Chang // `monitoring_annotations`.
KeysetHandle(google::crypto::tink::Keyset keyset,const std::vector<std::shared_ptr<const Entry>> & entries,const absl::flat_hash_map<std::string,std::string> & monitoring_annotations)251*e7b1675dSTing-Kang Chang KeysetHandle(google::crypto::tink::Keyset keyset,
252*e7b1675dSTing-Kang Chang const std::vector<std::shared_ptr<const Entry>>& entries,
253*e7b1675dSTing-Kang Chang const absl::flat_hash_map<std::string, std::string>&
254*e7b1675dSTing-Kang Chang monitoring_annotations)
255*e7b1675dSTing-Kang Chang : keyset_(std::move(keyset)),
256*e7b1675dSTing-Kang Chang entries_(entries),
257*e7b1675dSTing-Kang Chang monitoring_annotations_(monitoring_annotations) {}
KeysetHandle(std::unique_ptr<google::crypto::tink::Keyset> keyset,const std::vector<std::shared_ptr<const Entry>> & entries,const absl::flat_hash_map<std::string,std::string> & monitoring_annotations)258*e7b1675dSTing-Kang Chang KeysetHandle(std::unique_ptr<google::crypto::tink::Keyset> keyset,
259*e7b1675dSTing-Kang Chang const std::vector<std::shared_ptr<const Entry>>& entries,
260*e7b1675dSTing-Kang Chang const absl::flat_hash_map<std::string, std::string>&
261*e7b1675dSTing-Kang Chang monitoring_annotations)
262*e7b1675dSTing-Kang Chang : keyset_(std::move(*keyset)),
263*e7b1675dSTing-Kang Chang entries_(entries),
264*e7b1675dSTing-Kang Chang monitoring_annotations_(monitoring_annotations) {}
265*e7b1675dSTing-Kang Chang
266*e7b1675dSTing-Kang Chang // Generates a key from `key_template` and adds it `keyset`.
267*e7b1675dSTing-Kang Chang static crypto::tink::util::StatusOr<uint32_t> AddToKeyset(
268*e7b1675dSTing-Kang Chang const google::crypto::tink::KeyTemplate& key_template, bool as_primary,
269*e7b1675dSTing-Kang Chang const crypto::tink::KeyGenConfiguration& config,
270*e7b1675dSTing-Kang Chang google::crypto::tink::Keyset* keyset);
271*e7b1675dSTing-Kang Chang
272*e7b1675dSTing-Kang Chang // Creates list of KeysetHandle::Entry entries derived from `keyset` in order.
273*e7b1675dSTing-Kang Chang static crypto::tink::util::StatusOr<std::vector<std::shared_ptr<const Entry>>>
274*e7b1675dSTing-Kang Chang GetEntriesFromKeyset(const google::crypto::tink::Keyset& keyset);
275*e7b1675dSTing-Kang Chang
276*e7b1675dSTing-Kang Chang // Creates KeysetHandle::Entry for `key`, which will be set to primary if
277*e7b1675dSTing-Kang Chang // its key id equals `primary_key_id`.
278*e7b1675dSTing-Kang Chang static util::StatusOr<Entry> CreateEntry(
279*e7b1675dSTing-Kang Chang const google::crypto::tink::Keyset::Key& key, uint32_t primary_key_id);
280*e7b1675dSTing-Kang Chang
281*e7b1675dSTing-Kang Chang // Generates a key from `key_template` and adds it to the keyset handle.
282*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<uint32_t> AddKey(
283*e7b1675dSTing-Kang Chang const google::crypto::tink::KeyTemplate& key_template, bool as_primary,
284*e7b1675dSTing-Kang Chang const crypto::tink::KeyGenConfiguration& config);
285*e7b1675dSTing-Kang Chang
286*e7b1675dSTing-Kang Chang // Returns keyset held by this handle.
get_keyset()287*e7b1675dSTing-Kang Chang const google::crypto::tink::Keyset& get_keyset() const { return keyset_; }
288*e7b1675dSTing-Kang Chang
289*e7b1675dSTing-Kang Chang // Creates a set of primitives corresponding to the keys with
290*e7b1675dSTing-Kang Chang // (status == ENABLED) in the keyset given in 'keyset_handle',
291*e7b1675dSTing-Kang Chang // assuming all the corresponding key managers are present (keys
292*e7b1675dSTing-Kang Chang // with (status != ENABLED) are skipped).
293*e7b1675dSTing-Kang Chang //
294*e7b1675dSTing-Kang Chang // The returned set is usually later "wrapped" into a class that
295*e7b1675dSTing-Kang Chang // implements the corresponding Primitive-interface.
296*e7b1675dSTing-Kang Chang template <class P>
297*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<PrimitiveSet<P>>> GetPrimitives(
298*e7b1675dSTing-Kang Chang const KeyManager<P>* custom_manager) const;
299*e7b1675dSTing-Kang Chang
300*e7b1675dSTing-Kang Chang // Creates KeysetHandle::Entry from `keyset_` at `index`.
301*e7b1675dSTing-Kang Chang Entry CreateEntryAt(int index) const;
302*e7b1675dSTing-Kang Chang
303*e7b1675dSTing-Kang Chang google::crypto::tink::Keyset keyset_;
304*e7b1675dSTing-Kang Chang // If this keyset handle has been created with a constructor that does not
305*e7b1675dSTing-Kang Chang // accept an entries argument, then `entries` will be empty and operator[]
306*e7b1675dSTing-Kang Chang // will fall back to creating the key entry on demand from `keyset_`.
307*e7b1675dSTing-Kang Chang //
308*e7b1675dSTing-Kang Chang // If `entries_` is not empty, then it should contain exactly one key entry
309*e7b1675dSTing-Kang Chang // for each key proto in `keyset_`.
310*e7b1675dSTing-Kang Chang std::vector<std::shared_ptr<const Entry>> entries_;
311*e7b1675dSTing-Kang Chang absl::flat_hash_map<std::string, std::string> monitoring_annotations_;
312*e7b1675dSTing-Kang Chang };
313*e7b1675dSTing-Kang Chang
314*e7b1675dSTing-Kang Chang ///////////////////////////////////////////////////////////////////////////////
315*e7b1675dSTing-Kang Chang // Implementation details of templated methods.
316*e7b1675dSTing-Kang Chang
317*e7b1675dSTing-Kang Chang template <class P>
318*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<PrimitiveSet<P>>>
GetPrimitives(const KeyManager<P> * custom_manager)319*e7b1675dSTing-Kang Chang KeysetHandle::GetPrimitives(const KeyManager<P>* custom_manager) const {
320*e7b1675dSTing-Kang Chang crypto::tink::util::Status status = ValidateKeyset(get_keyset());
321*e7b1675dSTing-Kang Chang if (!status.ok()) return status;
322*e7b1675dSTing-Kang Chang typename PrimitiveSet<P>::Builder primitives_builder;
323*e7b1675dSTing-Kang Chang primitives_builder.AddAnnotations(monitoring_annotations_);
324*e7b1675dSTing-Kang Chang for (const google::crypto::tink::Keyset::Key& key : get_keyset().key()) {
325*e7b1675dSTing-Kang Chang if (key.status() == google::crypto::tink::KeyStatusType::ENABLED) {
326*e7b1675dSTing-Kang Chang std::unique_ptr<P> primitive;
327*e7b1675dSTing-Kang Chang if (custom_manager != nullptr &&
328*e7b1675dSTing-Kang Chang custom_manager->DoesSupport(key.key_data().type_url())) {
329*e7b1675dSTing-Kang Chang auto primitive_result = custom_manager->GetPrimitive(key.key_data());
330*e7b1675dSTing-Kang Chang if (!primitive_result.ok()) return primitive_result.status();
331*e7b1675dSTing-Kang Chang primitive = std::move(primitive_result.value());
332*e7b1675dSTing-Kang Chang } else {
333*e7b1675dSTing-Kang Chang auto primitive_result = Registry::GetPrimitive<P>(key.key_data());
334*e7b1675dSTing-Kang Chang if (!primitive_result.ok()) return primitive_result.status();
335*e7b1675dSTing-Kang Chang primitive = std::move(primitive_result.value());
336*e7b1675dSTing-Kang Chang }
337*e7b1675dSTing-Kang Chang if (key.key_id() == get_keyset().primary_key_id()) {
338*e7b1675dSTing-Kang Chang primitives_builder.AddPrimaryPrimitive(std::move(primitive),
339*e7b1675dSTing-Kang Chang KeyInfoFromKey(key));
340*e7b1675dSTing-Kang Chang } else {
341*e7b1675dSTing-Kang Chang primitives_builder.AddPrimitive(std::move(primitive),
342*e7b1675dSTing-Kang Chang KeyInfoFromKey(key));
343*e7b1675dSTing-Kang Chang }
344*e7b1675dSTing-Kang Chang }
345*e7b1675dSTing-Kang Chang }
346*e7b1675dSTing-Kang Chang auto primitives = std::move(primitives_builder).Build();
347*e7b1675dSTing-Kang Chang if (!primitives.ok()) return primitives.status();
348*e7b1675dSTing-Kang Chang return absl::make_unique<PrimitiveSet<P>>(*std::move(primitives));
349*e7b1675dSTing-Kang Chang }
350*e7b1675dSTing-Kang Chang
351*e7b1675dSTing-Kang Chang template <class P>
GetPrimitive(const Configuration & config)352*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<P>> KeysetHandle::GetPrimitive(
353*e7b1675dSTing-Kang Chang const Configuration& config) const {
354*e7b1675dSTing-Kang Chang if (crypto::tink::internal::ConfigurationImpl::IsInGlobalRegistryMode(
355*e7b1675dSTing-Kang Chang config)) {
356*e7b1675dSTing-Kang Chang return crypto::tink::internal::RegistryImpl::GlobalInstance().WrapKeyset<P>(
357*e7b1675dSTing-Kang Chang keyset_, monitoring_annotations_);
358*e7b1675dSTing-Kang Chang }
359*e7b1675dSTing-Kang Chang
360*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<
361*e7b1675dSTing-Kang Chang const crypto::tink::internal::KeysetWrapperStore*>
362*e7b1675dSTing-Kang Chang wrapper_store =
363*e7b1675dSTing-Kang Chang crypto::tink::internal::ConfigurationImpl::GetKeysetWrapperStore(
364*e7b1675dSTing-Kang Chang config);
365*e7b1675dSTing-Kang Chang if (!wrapper_store.ok()) {
366*e7b1675dSTing-Kang Chang return wrapper_store.status();
367*e7b1675dSTing-Kang Chang }
368*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<const crypto::tink::internal::KeysetWrapper<P>*>
369*e7b1675dSTing-Kang Chang wrapper = (*wrapper_store)->Get<P>();
370*e7b1675dSTing-Kang Chang if (!wrapper.ok()) {
371*e7b1675dSTing-Kang Chang return wrapper.status();
372*e7b1675dSTing-Kang Chang }
373*e7b1675dSTing-Kang Chang return (*wrapper)->Wrap(keyset_, monitoring_annotations_);
374*e7b1675dSTing-Kang Chang }
375*e7b1675dSTing-Kang Chang
376*e7b1675dSTing-Kang Chang // TODO(b/265865177): Deprecate.
377*e7b1675dSTing-Kang Chang template <class P>
GetPrimitive()378*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<P>> KeysetHandle::GetPrimitive()
379*e7b1675dSTing-Kang Chang const {
380*e7b1675dSTing-Kang Chang // TODO(b/265705174): Replace with ConfigGlobalRegistry instance.
381*e7b1675dSTing-Kang Chang crypto::tink::Configuration config;
382*e7b1675dSTing-Kang Chang crypto::tink::util::Status status =
383*e7b1675dSTing-Kang Chang crypto::tink::internal::ConfigurationImpl::SetGlobalRegistryMode(config);
384*e7b1675dSTing-Kang Chang if (!status.ok()) {
385*e7b1675dSTing-Kang Chang return status;
386*e7b1675dSTing-Kang Chang }
387*e7b1675dSTing-Kang Chang return GetPrimitive<P>(config);
388*e7b1675dSTing-Kang Chang }
389*e7b1675dSTing-Kang Chang
390*e7b1675dSTing-Kang Chang template <class P>
GetPrimitive(const KeyManager<P> * custom_manager)391*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<P>> KeysetHandle::GetPrimitive(
392*e7b1675dSTing-Kang Chang const KeyManager<P>* custom_manager) const {
393*e7b1675dSTing-Kang Chang if (custom_manager == nullptr) {
394*e7b1675dSTing-Kang Chang return crypto::tink::util::Status(absl::StatusCode::kInvalidArgument,
395*e7b1675dSTing-Kang Chang "custom_manager must not be null");
396*e7b1675dSTing-Kang Chang }
397*e7b1675dSTing-Kang Chang auto primitives_result = this->GetPrimitives<P>(custom_manager);
398*e7b1675dSTing-Kang Chang if (!primitives_result.ok()) {
399*e7b1675dSTing-Kang Chang return primitives_result.status();
400*e7b1675dSTing-Kang Chang }
401*e7b1675dSTing-Kang Chang return Registry::Wrap<P>(std::move(primitives_result.value()));
402*e7b1675dSTing-Kang Chang }
403*e7b1675dSTing-Kang Chang
404*e7b1675dSTing-Kang Chang } // namespace tink
405*e7b1675dSTing-Kang Chang } // namespace crypto
406*e7b1675dSTing-Kang Chang
407*e7b1675dSTing-Kang Chang #endif // TINK_KEYSET_HANDLE_H_
408