xref: /aosp_15_r20/external/tink/cc/keyset_handle.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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