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 #include "tink/internal/registry_impl.h"
18*e7b1675dSTing-Kang Chang
19*e7b1675dSTing-Kang Chang #include <stdint.h>
20*e7b1675dSTing-Kang Chang
21*e7b1675dSTing-Kang Chang #include <memory>
22*e7b1675dSTing-Kang Chang #include <sstream>
23*e7b1675dSTing-Kang Chang #include <string>
24*e7b1675dSTing-Kang Chang #include <thread> // NOLINT(build/c++11)
25*e7b1675dSTing-Kang Chang #include <typeinfo>
26*e7b1675dSTing-Kang Chang #include <utility>
27*e7b1675dSTing-Kang Chang
28*e7b1675dSTing-Kang Chang #include "gmock/gmock.h"
29*e7b1675dSTing-Kang Chang #include "gtest/gtest.h"
30*e7b1675dSTing-Kang Chang #include "absl/memory/memory.h"
31*e7b1675dSTing-Kang Chang #include "absl/status/status.h"
32*e7b1675dSTing-Kang Chang #include "absl/status/statusor.h"
33*e7b1675dSTing-Kang Chang #include "absl/strings/string_view.h"
34*e7b1675dSTing-Kang Chang #include "openssl/crypto.h"
35*e7b1675dSTing-Kang Chang #include "tink/aead.h"
36*e7b1675dSTing-Kang Chang #include "tink/aead/aead_wrapper.h"
37*e7b1675dSTing-Kang Chang #include "tink/aead/aes_gcm_key_manager.h"
38*e7b1675dSTing-Kang Chang #include "tink/core/key_manager_impl.h"
39*e7b1675dSTing-Kang Chang #include "tink/core/key_type_manager.h"
40*e7b1675dSTing-Kang Chang #include "tink/core/private_key_manager_impl.h"
41*e7b1675dSTing-Kang Chang #include "tink/core/private_key_type_manager.h"
42*e7b1675dSTing-Kang Chang #include "tink/core/template_util.h"
43*e7b1675dSTing-Kang Chang #include "tink/hybrid/ecies_aead_hkdf_private_key_manager.h"
44*e7b1675dSTing-Kang Chang #include "tink/hybrid/ecies_aead_hkdf_public_key_manager.h"
45*e7b1675dSTing-Kang Chang #include "tink/hybrid_decrypt.h"
46*e7b1675dSTing-Kang Chang #include "tink/input_stream.h"
47*e7b1675dSTing-Kang Chang #include "tink/internal/fips_utils.h"
48*e7b1675dSTing-Kang Chang #include "tink/key_manager.h"
49*e7b1675dSTing-Kang Chang #include "tink/mac.h"
50*e7b1675dSTing-Kang Chang #include "tink/monitoring/monitoring_client_mocks.h"
51*e7b1675dSTing-Kang Chang #include "tink/primitive_set.h"
52*e7b1675dSTing-Kang Chang #include "tink/primitive_wrapper.h"
53*e7b1675dSTing-Kang Chang #include "tink/registry.h"
54*e7b1675dSTing-Kang Chang #include "tink/subtle/aes_gcm_boringssl.h"
55*e7b1675dSTing-Kang Chang #include "tink/subtle/random.h"
56*e7b1675dSTing-Kang Chang #include "tink/util/input_stream_util.h"
57*e7b1675dSTing-Kang Chang #include "tink/util/istream_input_stream.h"
58*e7b1675dSTing-Kang Chang #include "tink/util/protobuf_helper.h"
59*e7b1675dSTing-Kang Chang #include "tink/util/secret_data.h"
60*e7b1675dSTing-Kang Chang #include "tink/util/status.h"
61*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h"
62*e7b1675dSTing-Kang Chang #include "tink/util/test_matchers.h"
63*e7b1675dSTing-Kang Chang #include "tink/util/test_util.h"
64*e7b1675dSTing-Kang Chang #include "proto/aes_ctr_hmac_aead.pb.h"
65*e7b1675dSTing-Kang Chang #include "proto/aes_gcm.pb.h"
66*e7b1675dSTing-Kang Chang #include "proto/common.pb.h"
67*e7b1675dSTing-Kang Chang #include "proto/ecdsa.pb.h"
68*e7b1675dSTing-Kang Chang #include "proto/ecies_aead_hkdf.pb.h"
69*e7b1675dSTing-Kang Chang #include "proto/tink.pb.h"
70*e7b1675dSTing-Kang Chang
71*e7b1675dSTing-Kang Chang namespace crypto {
72*e7b1675dSTing-Kang Chang namespace tink {
73*e7b1675dSTing-Kang Chang namespace internal {
74*e7b1675dSTing-Kang Chang
75*e7b1675dSTing-Kang Chang namespace {
76*e7b1675dSTing-Kang Chang
77*e7b1675dSTing-Kang Chang using ::crypto::tink::test::AddLegacyKey;
78*e7b1675dSTing-Kang Chang using ::crypto::tink::test::AddRawKey;
79*e7b1675dSTing-Kang Chang using ::crypto::tink::test::AddTinkKey;
80*e7b1675dSTing-Kang Chang using ::crypto::tink::test::DummyAead;
81*e7b1675dSTing-Kang Chang using ::crypto::tink::test::IsOk;
82*e7b1675dSTing-Kang Chang using ::crypto::tink::test::StatusIs;
83*e7b1675dSTing-Kang Chang using ::crypto::tink::util::Status;
84*e7b1675dSTing-Kang Chang using ::google::crypto::tink::AesCtrHmacAeadKey;
85*e7b1675dSTing-Kang Chang using ::google::crypto::tink::AesGcmKey;
86*e7b1675dSTing-Kang Chang using ::google::crypto::tink::AesGcmKeyFormat;
87*e7b1675dSTing-Kang Chang using ::google::crypto::tink::EcdsaKeyFormat;
88*e7b1675dSTing-Kang Chang using ::google::crypto::tink::EcdsaPrivateKey;
89*e7b1675dSTing-Kang Chang using ::google::crypto::tink::EcdsaPublicKey;
90*e7b1675dSTing-Kang Chang using ::google::crypto::tink::EcdsaSignatureEncoding;
91*e7b1675dSTing-Kang Chang using ::google::crypto::tink::EcPointFormat;
92*e7b1675dSTing-Kang Chang using ::google::crypto::tink::EllipticCurveType;
93*e7b1675dSTing-Kang Chang using ::google::crypto::tink::HashType;
94*e7b1675dSTing-Kang Chang using ::google::crypto::tink::KeyData;
95*e7b1675dSTing-Kang Chang using ::google::crypto::tink::Keyset;
96*e7b1675dSTing-Kang Chang using ::google::crypto::tink::KeysetInfo;
97*e7b1675dSTing-Kang Chang using ::google::crypto::tink::KeyStatusType;
98*e7b1675dSTing-Kang Chang using ::google::crypto::tink::KeyTemplate;
99*e7b1675dSTing-Kang Chang using ::google::crypto::tink::OutputPrefixType;
100*e7b1675dSTing-Kang Chang using ::portable_proto::MessageLite;
101*e7b1675dSTing-Kang Chang using ::testing::Eq;
102*e7b1675dSTing-Kang Chang using ::testing::HasSubstr;
103*e7b1675dSTing-Kang Chang using ::testing::IsNull;
104*e7b1675dSTing-Kang Chang using ::testing::Not;
105*e7b1675dSTing-Kang Chang using ::testing::SizeIs;
106*e7b1675dSTing-Kang Chang
107*e7b1675dSTing-Kang Chang class RegistryTest : public ::testing::Test {
108*e7b1675dSTing-Kang Chang protected:
SetUp()109*e7b1675dSTing-Kang Chang void SetUp() override { Registry::Reset(); }
110*e7b1675dSTing-Kang Chang
TearDown()111*e7b1675dSTing-Kang Chang void TearDown() override {
112*e7b1675dSTing-Kang Chang // Reset is needed here to ensure Mock objects get deleted and do not leak.
113*e7b1675dSTing-Kang Chang Registry::Reset();
114*e7b1675dSTing-Kang Chang }
115*e7b1675dSTing-Kang Chang };
116*e7b1675dSTing-Kang Chang
117*e7b1675dSTing-Kang Chang class TestKeyFactory : public KeyFactory {
118*e7b1675dSTing-Kang Chang public:
TestKeyFactory(const std::string & key_type)119*e7b1675dSTing-Kang Chang explicit TestKeyFactory(const std::string& key_type) : key_type_(key_type) {}
120*e7b1675dSTing-Kang Chang
NewKey(const MessageLite & key_format) const121*e7b1675dSTing-Kang Chang util::StatusOr<std::unique_ptr<portable_proto::MessageLite>> NewKey(
122*e7b1675dSTing-Kang Chang const MessageLite& key_format) const override {
123*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kUnknown,
124*e7b1675dSTing-Kang Chang "TestKeyFactory cannot produce a key");
125*e7b1675dSTing-Kang Chang }
126*e7b1675dSTing-Kang Chang
NewKey(absl::string_view serialized_key_format) const127*e7b1675dSTing-Kang Chang util::StatusOr<std::unique_ptr<portable_proto::MessageLite>> NewKey(
128*e7b1675dSTing-Kang Chang absl::string_view serialized_key_format) const override {
129*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kUnknown,
130*e7b1675dSTing-Kang Chang "TestKeyFactory cannot produce a key");
131*e7b1675dSTing-Kang Chang }
132*e7b1675dSTing-Kang Chang
NewKeyData(absl::string_view serialized_key_format) const133*e7b1675dSTing-Kang Chang util::StatusOr<std::unique_ptr<KeyData>> NewKeyData(
134*e7b1675dSTing-Kang Chang absl::string_view serialized_key_format) const override {
135*e7b1675dSTing-Kang Chang auto key_data = absl::make_unique<KeyData>();
136*e7b1675dSTing-Kang Chang key_data->set_type_url(key_type_);
137*e7b1675dSTing-Kang Chang key_data->set_value(std::string(serialized_key_format));
138*e7b1675dSTing-Kang Chang return std::move(key_data);
139*e7b1675dSTing-Kang Chang }
140*e7b1675dSTing-Kang Chang
141*e7b1675dSTing-Kang Chang private:
142*e7b1675dSTing-Kang Chang std::string key_type_;
143*e7b1675dSTing-Kang Chang };
144*e7b1675dSTing-Kang Chang
145*e7b1675dSTing-Kang Chang class TestAeadKeyManager : public KeyManager<Aead> {
146*e7b1675dSTing-Kang Chang public:
TestAeadKeyManager(const std::string & key_type)147*e7b1675dSTing-Kang Chang explicit TestAeadKeyManager(const std::string& key_type)
148*e7b1675dSTing-Kang Chang : key_type_(key_type), key_factory_(key_type) {}
149*e7b1675dSTing-Kang Chang
GetPrimitive(const KeyData & key) const150*e7b1675dSTing-Kang Chang util::StatusOr<std::unique_ptr<Aead>> GetPrimitive(
151*e7b1675dSTing-Kang Chang const KeyData& key) const override {
152*e7b1675dSTing-Kang Chang std::unique_ptr<Aead> aead(new DummyAead(key_type_));
153*e7b1675dSTing-Kang Chang return std::move(aead);
154*e7b1675dSTing-Kang Chang }
155*e7b1675dSTing-Kang Chang
GetPrimitive(const MessageLite & key) const156*e7b1675dSTing-Kang Chang util::StatusOr<std::unique_ptr<Aead>> GetPrimitive(
157*e7b1675dSTing-Kang Chang const MessageLite& key) const override {
158*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kUnknown,
159*e7b1675dSTing-Kang Chang "TestKeyFactory cannot construct an aead");
160*e7b1675dSTing-Kang Chang }
161*e7b1675dSTing-Kang Chang
get_version() const162*e7b1675dSTing-Kang Chang uint32_t get_version() const override { return 0; }
163*e7b1675dSTing-Kang Chang
get_key_type() const164*e7b1675dSTing-Kang Chang const std::string& get_key_type() const override { return key_type_; }
165*e7b1675dSTing-Kang Chang
get_key_factory() const166*e7b1675dSTing-Kang Chang const KeyFactory& get_key_factory() const override { return key_factory_; }
167*e7b1675dSTing-Kang Chang
168*e7b1675dSTing-Kang Chang private:
169*e7b1675dSTing-Kang Chang std::string key_type_;
170*e7b1675dSTing-Kang Chang TestKeyFactory key_factory_;
171*e7b1675dSTing-Kang Chang };
172*e7b1675dSTing-Kang Chang
173*e7b1675dSTing-Kang Chang // A class for testing. We will construct objects from an aead key, so that we
174*e7b1675dSTing-Kang Chang // can check that a keymanager can handle multiple primitives. It is really
175*e7b1675dSTing-Kang Chang // insecure, as it does nothing except provide access to the key.
176*e7b1675dSTing-Kang Chang class AeadVariant {
177*e7b1675dSTing-Kang Chang public:
AeadVariant(std::string s)178*e7b1675dSTing-Kang Chang explicit AeadVariant(std::string s) : s_(s) {}
179*e7b1675dSTing-Kang Chang
get()180*e7b1675dSTing-Kang Chang std::string get() { return s_; }
181*e7b1675dSTing-Kang Chang
182*e7b1675dSTing-Kang Chang private:
183*e7b1675dSTing-Kang Chang std::string s_;
184*e7b1675dSTing-Kang Chang };
185*e7b1675dSTing-Kang Chang
186*e7b1675dSTing-Kang Chang class ExampleKeyTypeManager : public KeyTypeManager<AesGcmKey, AesGcmKeyFormat,
187*e7b1675dSTing-Kang Chang List<Aead, AeadVariant>> {
188*e7b1675dSTing-Kang Chang public:
189*e7b1675dSTing-Kang Chang class AeadFactory : public PrimitiveFactory<Aead> {
190*e7b1675dSTing-Kang Chang public:
Create(const AesGcmKey & key) const191*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<Aead>> Create(
192*e7b1675dSTing-Kang Chang const AesGcmKey& key) const override {
193*e7b1675dSTing-Kang Chang // Ignore the key and returned one with a fixed size for this test.
194*e7b1675dSTing-Kang Chang return {subtle::AesGcmBoringSsl::New(
195*e7b1675dSTing-Kang Chang util::SecretDataFromStringView(key.key_value()))};
196*e7b1675dSTing-Kang Chang }
197*e7b1675dSTing-Kang Chang };
198*e7b1675dSTing-Kang Chang
199*e7b1675dSTing-Kang Chang class AeadVariantFactory : public PrimitiveFactory<AeadVariant> {
200*e7b1675dSTing-Kang Chang public:
Create(const AesGcmKey & key) const201*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<AeadVariant>> Create(
202*e7b1675dSTing-Kang Chang const AesGcmKey& key) const override {
203*e7b1675dSTing-Kang Chang return absl::make_unique<AeadVariant>(key.key_value());
204*e7b1675dSTing-Kang Chang }
205*e7b1675dSTing-Kang Chang };
206*e7b1675dSTing-Kang Chang
ExampleKeyTypeManager()207*e7b1675dSTing-Kang Chang ExampleKeyTypeManager()
208*e7b1675dSTing-Kang Chang : KeyTypeManager(absl::make_unique<AeadFactory>(),
209*e7b1675dSTing-Kang Chang absl::make_unique<AeadVariantFactory>()) {}
210*e7b1675dSTing-Kang Chang
key_material_type() const211*e7b1675dSTing-Kang Chang google::crypto::tink::KeyData::KeyMaterialType key_material_type()
212*e7b1675dSTing-Kang Chang const override {
213*e7b1675dSTing-Kang Chang return google::crypto::tink::KeyData::SYMMETRIC;
214*e7b1675dSTing-Kang Chang }
215*e7b1675dSTing-Kang Chang
get_version() const216*e7b1675dSTing-Kang Chang uint32_t get_version() const override { return kVersion; }
217*e7b1675dSTing-Kang Chang
get_key_type() const218*e7b1675dSTing-Kang Chang const std::string& get_key_type() const override { return kKeyType; }
219*e7b1675dSTing-Kang Chang
ValidateKey(const AesGcmKey & key) const220*e7b1675dSTing-Kang Chang crypto::tink::util::Status ValidateKey(const AesGcmKey& key) const override {
221*e7b1675dSTing-Kang Chang return util::OkStatus();
222*e7b1675dSTing-Kang Chang }
223*e7b1675dSTing-Kang Chang
ValidateKeyFormat(const AesGcmKeyFormat & key_format) const224*e7b1675dSTing-Kang Chang crypto::tink::util::Status ValidateKeyFormat(
225*e7b1675dSTing-Kang Chang const AesGcmKeyFormat& key_format) const override {
226*e7b1675dSTing-Kang Chang return util::OkStatus();
227*e7b1675dSTing-Kang Chang }
228*e7b1675dSTing-Kang Chang
CreateKey(const AesGcmKeyFormat & key_format) const229*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<AesGcmKey> CreateKey(
230*e7b1675dSTing-Kang Chang const AesGcmKeyFormat& key_format) const override {
231*e7b1675dSTing-Kang Chang AesGcmKey result;
232*e7b1675dSTing-Kang Chang result.set_key_value(subtle::Random::GetRandomBytes(key_format.key_size()));
233*e7b1675dSTing-Kang Chang return result;
234*e7b1675dSTing-Kang Chang }
235*e7b1675dSTing-Kang Chang
DeriveKey(const AesGcmKeyFormat & key_format,InputStream * input_stream) const236*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<AesGcmKey> DeriveKey(
237*e7b1675dSTing-Kang Chang const AesGcmKeyFormat& key_format,
238*e7b1675dSTing-Kang Chang InputStream* input_stream) const override {
239*e7b1675dSTing-Kang Chang // Note: in an actual key type manager we need to do more work, e.g., test
240*e7b1675dSTing-Kang Chang // that the generated key is long enough.
241*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::string> randomness =
242*e7b1675dSTing-Kang Chang ReadBytesFromStream(key_format.key_size(), input_stream);
243*e7b1675dSTing-Kang Chang if (!randomness.status().ok()) {
244*e7b1675dSTing-Kang Chang return randomness.status();
245*e7b1675dSTing-Kang Chang }
246*e7b1675dSTing-Kang Chang AesGcmKey key;
247*e7b1675dSTing-Kang Chang key.set_key_value(randomness.value());
248*e7b1675dSTing-Kang Chang return key;
249*e7b1675dSTing-Kang Chang }
250*e7b1675dSTing-Kang Chang
251*e7b1675dSTing-Kang Chang MOCK_METHOD(FipsCompatibility, FipsStatus, (), (const, override));
252*e7b1675dSTing-Kang Chang
253*e7b1675dSTing-Kang Chang private:
254*e7b1675dSTing-Kang Chang static constexpr int kVersion = 0;
255*e7b1675dSTing-Kang Chang const std::string kKeyType =
256*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.AesGcmKey";
257*e7b1675dSTing-Kang Chang };
258*e7b1675dSTing-Kang Chang
259*e7b1675dSTing-Kang Chang template <typename P, typename Q = P>
260*e7b1675dSTing-Kang Chang class TestWrapper : public PrimitiveWrapper<P, Q> {
261*e7b1675dSTing-Kang Chang public:
262*e7b1675dSTing-Kang Chang TestWrapper() = default;
Wrap(std::unique_ptr<PrimitiveSet<P>> primitive_set) const263*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<Q>> Wrap(
264*e7b1675dSTing-Kang Chang std::unique_ptr<PrimitiveSet<P>> primitive_set) const override {
265*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kUnimplemented,
266*e7b1675dSTing-Kang Chang "This is a test wrapper.");
267*e7b1675dSTing-Kang Chang }
268*e7b1675dSTing-Kang Chang };
269*e7b1675dSTing-Kang Chang
270*e7b1675dSTing-Kang Chang class AeadVariantWrapper : public PrimitiveWrapper<AeadVariant, AeadVariant> {
271*e7b1675dSTing-Kang Chang public:
Wrap(std::unique_ptr<PrimitiveSet<AeadVariant>> primitive_set) const272*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<AeadVariant>> Wrap(
273*e7b1675dSTing-Kang Chang std::unique_ptr<PrimitiveSet<AeadVariant>> primitive_set) const override {
274*e7b1675dSTing-Kang Chang return absl::make_unique<AeadVariant>(
275*e7b1675dSTing-Kang Chang primitive_set->get_primary()->get_primitive().get());
276*e7b1675dSTing-Kang Chang }
277*e7b1675dSTing-Kang Chang };
278*e7b1675dSTing-Kang Chang
279*e7b1675dSTing-Kang Chang class AeadVariantToStringWrapper
280*e7b1675dSTing-Kang Chang : public PrimitiveWrapper<AeadVariant, std::string> {
281*e7b1675dSTing-Kang Chang public:
Wrap(std::unique_ptr<PrimitiveSet<AeadVariant>> primitive_set) const282*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<std::string>> Wrap(
283*e7b1675dSTing-Kang Chang std::unique_ptr<PrimitiveSet<AeadVariant>> primitive_set) const override {
284*e7b1675dSTing-Kang Chang return absl::make_unique<std::string>(
285*e7b1675dSTing-Kang Chang primitive_set->get_primary()->get_primitive().get());
286*e7b1675dSTing-Kang Chang }
287*e7b1675dSTing-Kang Chang };
288*e7b1675dSTing-Kang Chang
register_test_managers(const std::string & key_type_prefix,int manager_count)289*e7b1675dSTing-Kang Chang void register_test_managers(const std::string& key_type_prefix,
290*e7b1675dSTing-Kang Chang int manager_count) {
291*e7b1675dSTing-Kang Chang for (int i = 0; i < manager_count; i++) {
292*e7b1675dSTing-Kang Chang std::string key_type = key_type_prefix + std::to_string(i);
293*e7b1675dSTing-Kang Chang util::Status status = Registry::RegisterKeyManager(
294*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type),
295*e7b1675dSTing-Kang Chang /* new_key_allowed= */ true);
296*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
297*e7b1675dSTing-Kang Chang }
298*e7b1675dSTing-Kang Chang }
299*e7b1675dSTing-Kang Chang
verify_test_managers(const std::string & key_type_prefix,int manager_count)300*e7b1675dSTing-Kang Chang void verify_test_managers(const std::string& key_type_prefix,
301*e7b1675dSTing-Kang Chang int manager_count) {
302*e7b1675dSTing-Kang Chang for (int i = 0; i < manager_count; i++) {
303*e7b1675dSTing-Kang Chang std::string key_type = key_type_prefix + std::to_string(i);
304*e7b1675dSTing-Kang Chang auto manager_result = Registry::get_key_manager<Aead>(key_type);
305*e7b1675dSTing-Kang Chang EXPECT_TRUE(manager_result.ok()) << manager_result.status();
306*e7b1675dSTing-Kang Chang auto manager = manager_result.value();
307*e7b1675dSTing-Kang Chang EXPECT_EQ(key_type, manager->get_key_type());
308*e7b1675dSTing-Kang Chang }
309*e7b1675dSTing-Kang Chang }
310*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,testRegisterKeyManagerMoreRestrictiveNewKeyAllowed)311*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, testRegisterKeyManagerMoreRestrictiveNewKeyAllowed) {
312*e7b1675dSTing-Kang Chang std::string key_type = "some_key_type";
313*e7b1675dSTing-Kang Chang KeyTemplate key_template;
314*e7b1675dSTing-Kang Chang key_template.set_type_url(key_type);
315*e7b1675dSTing-Kang Chang
316*e7b1675dSTing-Kang Chang // Register the key manager with new_key_allowed == true and verify that
317*e7b1675dSTing-Kang Chang // new key data can be created.
318*e7b1675dSTing-Kang Chang util::Status status = Registry::RegisterKeyManager(
319*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type),
320*e7b1675dSTing-Kang Chang /* new_key_allowed= */ true);
321*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
322*e7b1675dSTing-Kang Chang
323*e7b1675dSTing-Kang Chang auto result_before = Registry::NewKeyData(key_template);
324*e7b1675dSTing-Kang Chang EXPECT_TRUE(result_before.ok()) << result_before.status();
325*e7b1675dSTing-Kang Chang
326*e7b1675dSTing-Kang Chang // Re-register the key manager with new_key_allowed == false and check the
327*e7b1675dSTing-Kang Chang // restriction (i.e. new key data cannot be created).
328*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
329*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type),
330*e7b1675dSTing-Kang Chang /* new_key_allowed= */ false);
331*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
332*e7b1675dSTing-Kang Chang
333*e7b1675dSTing-Kang Chang auto result_after = Registry::NewKeyData(key_template);
334*e7b1675dSTing-Kang Chang EXPECT_FALSE(result_after.ok());
335*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kInvalidArgument, result_after.status().code());
336*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, key_type,
337*e7b1675dSTing-Kang Chang std::string(result_after.status().message()));
338*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, "does not allow",
339*e7b1675dSTing-Kang Chang std::string(result_after.status().message()));
340*e7b1675dSTing-Kang Chang }
341*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,testRegisterKeyManagerLessRestrictiveNewKeyAllowed)342*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, testRegisterKeyManagerLessRestrictiveNewKeyAllowed) {
343*e7b1675dSTing-Kang Chang std::string key_type = "some_key_type";
344*e7b1675dSTing-Kang Chang KeyTemplate key_template;
345*e7b1675dSTing-Kang Chang key_template.set_type_url(key_type);
346*e7b1675dSTing-Kang Chang
347*e7b1675dSTing-Kang Chang // Register the key manager with new_key_allowed == false.
348*e7b1675dSTing-Kang Chang util::Status status = Registry::RegisterKeyManager(
349*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type),
350*e7b1675dSTing-Kang Chang /* new_key_allowed= */ false);
351*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
352*e7b1675dSTing-Kang Chang
353*e7b1675dSTing-Kang Chang // Verify that re-registering the key manager with new_key_allowed == true is
354*e7b1675dSTing-Kang Chang // not possible and that the restriction still holds after that operation
355*e7b1675dSTing-Kang Chang // (i.e. new key data cannot be created).
356*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
357*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type),
358*e7b1675dSTing-Kang Chang /* new_key_allowed= */ true);
359*e7b1675dSTing-Kang Chang EXPECT_FALSE(status.ok());
360*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kAlreadyExists, status.code()) << status;
361*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, key_type,
362*e7b1675dSTing-Kang Chang std::string(status.message()))
363*e7b1675dSTing-Kang Chang << status;
364*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, "forbidden new key operation",
365*e7b1675dSTing-Kang Chang std::string(status.message()))
366*e7b1675dSTing-Kang Chang << status;
367*e7b1675dSTing-Kang Chang
368*e7b1675dSTing-Kang Chang auto result_after = Registry::NewKeyData(key_template);
369*e7b1675dSTing-Kang Chang EXPECT_FALSE(result_after.ok());
370*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kInvalidArgument, result_after.status().code());
371*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, key_type,
372*e7b1675dSTing-Kang Chang std::string(result_after.status().message()));
373*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, "does not allow",
374*e7b1675dSTing-Kang Chang std::string(result_after.status().message()));
375*e7b1675dSTing-Kang Chang }
376*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,testConcurrentRegistration)377*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, testConcurrentRegistration) {
378*e7b1675dSTing-Kang Chang std::string key_type_prefix_a = "key_type_a_";
379*e7b1675dSTing-Kang Chang std::string key_type_prefix_b = "key_type_b_";
380*e7b1675dSTing-Kang Chang int count_a = 42;
381*e7b1675dSTing-Kang Chang int count_b = 72;
382*e7b1675dSTing-Kang Chang
383*e7b1675dSTing-Kang Chang // Register some managers.
384*e7b1675dSTing-Kang Chang std::thread register_a(register_test_managers, key_type_prefix_a, count_a);
385*e7b1675dSTing-Kang Chang std::thread register_b(register_test_managers, key_type_prefix_b, count_b);
386*e7b1675dSTing-Kang Chang register_a.join();
387*e7b1675dSTing-Kang Chang register_b.join();
388*e7b1675dSTing-Kang Chang
389*e7b1675dSTing-Kang Chang // Check that the managers were registered. Also, keep registering new
390*e7b1675dSTing-Kang Chang // versions while we check.
391*e7b1675dSTing-Kang Chang std::thread register_more_a(register_test_managers, key_type_prefix_a,
392*e7b1675dSTing-Kang Chang count_a);
393*e7b1675dSTing-Kang Chang std::thread register_more_b(register_test_managers, key_type_prefix_b,
394*e7b1675dSTing-Kang Chang count_b);
395*e7b1675dSTing-Kang Chang std::thread verify_a(verify_test_managers, key_type_prefix_a, count_a);
396*e7b1675dSTing-Kang Chang std::thread verify_b(verify_test_managers, key_type_prefix_b, count_b);
397*e7b1675dSTing-Kang Chang verify_a.join();
398*e7b1675dSTing-Kang Chang verify_b.join();
399*e7b1675dSTing-Kang Chang register_more_a.join();
400*e7b1675dSTing-Kang Chang register_more_b.join();
401*e7b1675dSTing-Kang Chang
402*e7b1675dSTing-Kang Chang // Check that there are no extra managers.
403*e7b1675dSTing-Kang Chang std::string key_type = key_type_prefix_a + std::to_string(count_a - 1);
404*e7b1675dSTing-Kang Chang auto manager_result = Registry::get_key_manager<Aead>(key_type);
405*e7b1675dSTing-Kang Chang EXPECT_TRUE(manager_result.ok()) << manager_result.status();
406*e7b1675dSTing-Kang Chang EXPECT_EQ(key_type, manager_result.value()->get_key_type());
407*e7b1675dSTing-Kang Chang
408*e7b1675dSTing-Kang Chang key_type = key_type_prefix_a + std::to_string(count_a);
409*e7b1675dSTing-Kang Chang manager_result = Registry::get_key_manager<Aead>(key_type);
410*e7b1675dSTing-Kang Chang EXPECT_FALSE(manager_result.ok());
411*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kNotFound, manager_result.status().code());
412*e7b1675dSTing-Kang Chang }
413*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,testBasic)414*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, testBasic) {
415*e7b1675dSTing-Kang Chang std::string key_type_1 = "google.crypto.tink.AesCtrHmacAeadKey";
416*e7b1675dSTing-Kang Chang std::string key_type_2 = "google.crypto.tink.AesGcmKey";
417*e7b1675dSTing-Kang Chang auto manager_result = Registry::get_key_manager<Aead>(key_type_1);
418*e7b1675dSTing-Kang Chang EXPECT_FALSE(manager_result.ok());
419*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kNotFound, manager_result.status().code());
420*e7b1675dSTing-Kang Chang
421*e7b1675dSTing-Kang Chang auto status = Registry::RegisterKeyManager(
422*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type_1), true);
423*e7b1675dSTing-Kang Chang
424*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
425*e7b1675dSTing-Kang Chang
426*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
427*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type_2), true);
428*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
429*e7b1675dSTing-Kang Chang
430*e7b1675dSTing-Kang Chang manager_result = Registry::get_key_manager<Aead>(key_type_1);
431*e7b1675dSTing-Kang Chang EXPECT_TRUE(manager_result.ok()) << manager_result.status();
432*e7b1675dSTing-Kang Chang auto manager = manager_result.value();
433*e7b1675dSTing-Kang Chang EXPECT_TRUE(manager->DoesSupport(key_type_1));
434*e7b1675dSTing-Kang Chang EXPECT_FALSE(manager->DoesSupport(key_type_2));
435*e7b1675dSTing-Kang Chang
436*e7b1675dSTing-Kang Chang manager_result = Registry::get_key_manager<Aead>(key_type_2);
437*e7b1675dSTing-Kang Chang EXPECT_TRUE(manager_result.ok()) << manager_result.status();
438*e7b1675dSTing-Kang Chang manager = manager_result.value();
439*e7b1675dSTing-Kang Chang EXPECT_TRUE(manager->DoesSupport(key_type_2));
440*e7b1675dSTing-Kang Chang EXPECT_FALSE(manager->DoesSupport(key_type_1));
441*e7b1675dSTing-Kang Chang }
442*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,testRegisterKeyManager)443*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, testRegisterKeyManager) {
444*e7b1675dSTing-Kang Chang std::string key_type_1 = AesGcmKeyManager().get_key_type();
445*e7b1675dSTing-Kang Chang
446*e7b1675dSTing-Kang Chang std::unique_ptr<TestAeadKeyManager> null_key_manager = nullptr;
447*e7b1675dSTing-Kang Chang auto status = Registry::RegisterKeyManager(std::move(null_key_manager), true);
448*e7b1675dSTing-Kang Chang EXPECT_FALSE(status.ok());
449*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kInvalidArgument, status.code()) << status;
450*e7b1675dSTing-Kang Chang
451*e7b1675dSTing-Kang Chang // Register a key manager.
452*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
453*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type_1), true);
454*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
455*e7b1675dSTing-Kang Chang
456*e7b1675dSTing-Kang Chang // Register the same key manager again, it should work (idempotence).
457*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
458*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type_1), true);
459*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
460*e7b1675dSTing-Kang Chang
461*e7b1675dSTing-Kang Chang // Try overriding a key manager.
462*e7b1675dSTing-Kang Chang AesGcmKeyManager key_type_manager;
463*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
464*e7b1675dSTing-Kang Chang crypto::tink::internal::MakeKeyManager<Aead>(&key_type_manager), true);
465*e7b1675dSTing-Kang Chang EXPECT_FALSE(status.ok());
466*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kAlreadyExists, status.code()) << status;
467*e7b1675dSTing-Kang Chang
468*e7b1675dSTing-Kang Chang // Check the key manager is still registered.
469*e7b1675dSTing-Kang Chang auto manager_result = Registry::get_key_manager<Aead>(key_type_1);
470*e7b1675dSTing-Kang Chang EXPECT_TRUE(manager_result.ok()) << manager_result.status();
471*e7b1675dSTing-Kang Chang auto manager = manager_result.value();
472*e7b1675dSTing-Kang Chang EXPECT_TRUE(manager->DoesSupport(key_type_1));
473*e7b1675dSTing-Kang Chang }
474*e7b1675dSTing-Kang Chang
475*e7b1675dSTing-Kang Chang // Tests that if we register a key manager once more after a call to
476*e7b1675dSTing-Kang Chang // get_key_manager, the key manager previously obtained with "get_key_manager()"
477*e7b1675dSTing-Kang Chang // remains valid.
TEST_F(RegistryTest,GetKeyManagerRemainsValid)478*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, GetKeyManagerRemainsValid) {
479*e7b1675dSTing-Kang Chang std::string key_type = AesGcmKeyManager().get_key_type();
480*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyManager(
481*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type), true),
482*e7b1675dSTing-Kang Chang IsOk());
483*e7b1675dSTing-Kang Chang
484*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<const KeyManager<Aead>*> key_manager =
485*e7b1675dSTing-Kang Chang Registry::get_key_manager<Aead>(key_type);
486*e7b1675dSTing-Kang Chang ASSERT_THAT(key_manager, IsOk());
487*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyManager(
488*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type), true),
489*e7b1675dSTing-Kang Chang IsOk());
490*e7b1675dSTing-Kang Chang EXPECT_THAT(key_manager.value()->get_key_type(), Eq(key_type));
491*e7b1675dSTing-Kang Chang }
492*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,testGettingPrimitives)493*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, testGettingPrimitives) {
494*e7b1675dSTing-Kang Chang std::string key_type_1 = "google.crypto.tink.AesCtrHmacAeadKey";
495*e7b1675dSTing-Kang Chang std::string key_type_2 = "google.crypto.tink.AesGcmKey";
496*e7b1675dSTing-Kang Chang AesCtrHmacAeadKey dummy_key_1;
497*e7b1675dSTing-Kang Chang AesGcmKey dummy_key_2;
498*e7b1675dSTing-Kang Chang
499*e7b1675dSTing-Kang Chang // Prepare keyset.
500*e7b1675dSTing-Kang Chang Keyset keyset;
501*e7b1675dSTing-Kang Chang
502*e7b1675dSTing-Kang Chang uint32_t key_id_1 = 1234543;
503*e7b1675dSTing-Kang Chang AddTinkKey(key_type_1, key_id_1, dummy_key_1, KeyStatusType::ENABLED,
504*e7b1675dSTing-Kang Chang KeyData::SYMMETRIC, &keyset);
505*e7b1675dSTing-Kang Chang
506*e7b1675dSTing-Kang Chang uint32_t key_id_2 = 726329;
507*e7b1675dSTing-Kang Chang AddTinkKey(key_type_2, key_id_2, dummy_key_2, KeyStatusType::DISABLED,
508*e7b1675dSTing-Kang Chang KeyData::SYMMETRIC, &keyset);
509*e7b1675dSTing-Kang Chang
510*e7b1675dSTing-Kang Chang uint32_t key_id_3 = 7213743;
511*e7b1675dSTing-Kang Chang AddLegacyKey(key_type_2, key_id_3, dummy_key_2, KeyStatusType::ENABLED,
512*e7b1675dSTing-Kang Chang KeyData::SYMMETRIC, &keyset);
513*e7b1675dSTing-Kang Chang
514*e7b1675dSTing-Kang Chang uint32_t key_id_4 = 6268492;
515*e7b1675dSTing-Kang Chang AddRawKey(key_type_1, key_id_4, dummy_key_1, KeyStatusType::ENABLED,
516*e7b1675dSTing-Kang Chang KeyData::SYMMETRIC, &keyset);
517*e7b1675dSTing-Kang Chang
518*e7b1675dSTing-Kang Chang uint32_t key_id_5 = 42;
519*e7b1675dSTing-Kang Chang AddRawKey(key_type_2, key_id_5, dummy_key_2, KeyStatusType::ENABLED,
520*e7b1675dSTing-Kang Chang KeyData::SYMMETRIC, &keyset);
521*e7b1675dSTing-Kang Chang
522*e7b1675dSTing-Kang Chang keyset.set_primary_key_id(key_id_3);
523*e7b1675dSTing-Kang Chang
524*e7b1675dSTing-Kang Chang // Register key managers.
525*e7b1675dSTing-Kang Chang util::Status status;
526*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
527*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type_1), true);
528*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
529*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
530*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type_2), true);
531*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
532*e7b1675dSTing-Kang Chang
533*e7b1675dSTing-Kang Chang // Get and use primitives.
534*e7b1675dSTing-Kang Chang std::string plaintext = "some data";
535*e7b1675dSTing-Kang Chang std::string aad = "aad";
536*e7b1675dSTing-Kang Chang
537*e7b1675dSTing-Kang Chang // Key #1.
538*e7b1675dSTing-Kang Chang {
539*e7b1675dSTing-Kang Chang auto result = Registry::GetPrimitive<Aead>(keyset.key(0).key_data());
540*e7b1675dSTing-Kang Chang EXPECT_TRUE(result.ok()) << result.status();
541*e7b1675dSTing-Kang Chang auto aead = std::move(result.value());
542*e7b1675dSTing-Kang Chang EXPECT_EQ(DummyAead(key_type_1).Encrypt(plaintext, aad).value(),
543*e7b1675dSTing-Kang Chang aead->Encrypt(plaintext, aad).value());
544*e7b1675dSTing-Kang Chang }
545*e7b1675dSTing-Kang Chang
546*e7b1675dSTing-Kang Chang // Key #3.
547*e7b1675dSTing-Kang Chang {
548*e7b1675dSTing-Kang Chang auto result = Registry::GetPrimitive<Aead>(keyset.key(2).key_data());
549*e7b1675dSTing-Kang Chang EXPECT_TRUE(result.ok()) << result.status();
550*e7b1675dSTing-Kang Chang auto aead = std::move(result.value());
551*e7b1675dSTing-Kang Chang EXPECT_EQ(DummyAead(key_type_2).Encrypt(plaintext, aad).value(),
552*e7b1675dSTing-Kang Chang aead->Encrypt(plaintext, aad).value());
553*e7b1675dSTing-Kang Chang }
554*e7b1675dSTing-Kang Chang }
555*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,testNewKeyData)556*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, testNewKeyData) {
557*e7b1675dSTing-Kang Chang std::string key_type_1 = "google.crypto.tink.AesCtrHmacAeadKey";
558*e7b1675dSTing-Kang Chang std::string key_type_2 = "google.crypto.tink.AesGcmKey";
559*e7b1675dSTing-Kang Chang std::string key_type_3 = "yet/another/keytype";
560*e7b1675dSTing-Kang Chang
561*e7b1675dSTing-Kang Chang // Register key managers.
562*e7b1675dSTing-Kang Chang util::Status status;
563*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
564*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type_1),
565*e7b1675dSTing-Kang Chang /*new_key_allowed=*/true);
566*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
567*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
568*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type_2),
569*e7b1675dSTing-Kang Chang /*new_key_allowed=*/true);
570*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
571*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
572*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type_3),
573*e7b1675dSTing-Kang Chang /*new_key_allowed=*/false);
574*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok()) << status;
575*e7b1675dSTing-Kang Chang
576*e7b1675dSTing-Kang Chang { // A supported key type.
577*e7b1675dSTing-Kang Chang KeyTemplate key_template;
578*e7b1675dSTing-Kang Chang key_template.set_type_url(key_type_1);
579*e7b1675dSTing-Kang Chang key_template.set_value("test value 42");
580*e7b1675dSTing-Kang Chang auto new_key_data_result = Registry::NewKeyData(key_template);
581*e7b1675dSTing-Kang Chang EXPECT_TRUE(new_key_data_result.ok()) << new_key_data_result.status();
582*e7b1675dSTing-Kang Chang EXPECT_EQ(key_type_1, new_key_data_result.value()->type_url());
583*e7b1675dSTing-Kang Chang EXPECT_EQ(key_template.value(), new_key_data_result.value()->value());
584*e7b1675dSTing-Kang Chang }
585*e7b1675dSTing-Kang Chang
586*e7b1675dSTing-Kang Chang { // Another supported key type.
587*e7b1675dSTing-Kang Chang KeyTemplate key_template;
588*e7b1675dSTing-Kang Chang key_template.set_type_url(key_type_2);
589*e7b1675dSTing-Kang Chang key_template.set_value("yet another test value 42");
590*e7b1675dSTing-Kang Chang auto new_key_data_result = Registry::NewKeyData(key_template);
591*e7b1675dSTing-Kang Chang EXPECT_TRUE(new_key_data_result.ok()) << new_key_data_result.status();
592*e7b1675dSTing-Kang Chang EXPECT_EQ(key_type_2, new_key_data_result.value()->type_url());
593*e7b1675dSTing-Kang Chang EXPECT_EQ(key_template.value(), new_key_data_result.value()->value());
594*e7b1675dSTing-Kang Chang }
595*e7b1675dSTing-Kang Chang
596*e7b1675dSTing-Kang Chang { // A key type that does not allow NewKey-operations.
597*e7b1675dSTing-Kang Chang KeyTemplate key_template;
598*e7b1675dSTing-Kang Chang key_template.set_type_url(key_type_3);
599*e7b1675dSTing-Kang Chang key_template.set_value("some other value 72");
600*e7b1675dSTing-Kang Chang auto new_key_data_result = Registry::NewKeyData(key_template);
601*e7b1675dSTing-Kang Chang EXPECT_FALSE(new_key_data_result.ok());
602*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kInvalidArgument,
603*e7b1675dSTing-Kang Chang new_key_data_result.status().code());
604*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, key_type_3,
605*e7b1675dSTing-Kang Chang std::string(new_key_data_result.status().message()));
606*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, "does not allow",
607*e7b1675dSTing-Kang Chang std::string(new_key_data_result.status().message()));
608*e7b1675dSTing-Kang Chang }
609*e7b1675dSTing-Kang Chang
610*e7b1675dSTing-Kang Chang { // A key type that is not supported.
611*e7b1675dSTing-Kang Chang KeyTemplate key_template;
612*e7b1675dSTing-Kang Chang std::string bad_type_url = "some key type that is not supported";
613*e7b1675dSTing-Kang Chang key_template.set_type_url(bad_type_url);
614*e7b1675dSTing-Kang Chang key_template.set_value("some totally other value 42");
615*e7b1675dSTing-Kang Chang auto new_key_data_result = Registry::NewKeyData(key_template);
616*e7b1675dSTing-Kang Chang EXPECT_FALSE(new_key_data_result.ok());
617*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kNotFound, new_key_data_result.status().code());
618*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, bad_type_url,
619*e7b1675dSTing-Kang Chang std::string(new_key_data_result.status().message()));
620*e7b1675dSTing-Kang Chang }
621*e7b1675dSTing-Kang Chang }
622*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,testGetPublicKeyData)623*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, testGetPublicKeyData) {
624*e7b1675dSTing-Kang Chang // Setup the registry.
625*e7b1675dSTing-Kang Chang Registry::Reset();
626*e7b1675dSTing-Kang Chang auto private_key_type_manager =
627*e7b1675dSTing-Kang Chang absl::make_unique<EciesAeadHkdfPrivateKeyManager>();
628*e7b1675dSTing-Kang Chang auto public_key_type_manager =
629*e7b1675dSTing-Kang Chang absl::make_unique<EciesAeadHkdfPublicKeyManager>();
630*e7b1675dSTing-Kang Chang
631*e7b1675dSTing-Kang Chang auto status = Registry::RegisterKeyManager(
632*e7b1675dSTing-Kang Chang internal::MakePrivateKeyManager<HybridDecrypt>(
633*e7b1675dSTing-Kang Chang private_key_type_manager.get(), public_key_type_manager.get()),
634*e7b1675dSTing-Kang Chang true);
635*e7b1675dSTing-Kang Chang ASSERT_TRUE(status.ok()) << status;
636*e7b1675dSTing-Kang Chang AesGcmKeyManager key_type_manager;
637*e7b1675dSTing-Kang Chang status = Registry::RegisterKeyManager(
638*e7b1675dSTing-Kang Chang crypto::tink::internal::MakeKeyManager<Aead>(&key_type_manager), true);
639*e7b1675dSTing-Kang Chang ASSERT_TRUE(status.ok()) << status;
640*e7b1675dSTing-Kang Chang
641*e7b1675dSTing-Kang Chang // Get a test private key.
642*e7b1675dSTing-Kang Chang auto ecies_key = test::GetEciesAesGcmHkdfTestKey(
643*e7b1675dSTing-Kang Chang EllipticCurveType::NIST_P256, EcPointFormat::UNCOMPRESSED,
644*e7b1675dSTing-Kang Chang HashType::SHA256, /* aes_gcm_key_size= */ 24);
645*e7b1675dSTing-Kang Chang
646*e7b1675dSTing-Kang Chang // Extract public key data and check.
647*e7b1675dSTing-Kang Chang auto public_key_data_result = Registry::GetPublicKeyData(
648*e7b1675dSTing-Kang Chang EciesAeadHkdfPrivateKeyManager().get_key_type(),
649*e7b1675dSTing-Kang Chang ecies_key.SerializeAsString());
650*e7b1675dSTing-Kang Chang EXPECT_TRUE(public_key_data_result.ok()) << public_key_data_result.status();
651*e7b1675dSTing-Kang Chang auto public_key_data = std::move(public_key_data_result.value());
652*e7b1675dSTing-Kang Chang EXPECT_EQ(EciesAeadHkdfPublicKeyManager().get_key_type(),
653*e7b1675dSTing-Kang Chang public_key_data->type_url());
654*e7b1675dSTing-Kang Chang EXPECT_EQ(KeyData::ASYMMETRIC_PUBLIC, public_key_data->key_material_type());
655*e7b1675dSTing-Kang Chang EXPECT_EQ(ecies_key.public_key().SerializeAsString(),
656*e7b1675dSTing-Kang Chang public_key_data->value());
657*e7b1675dSTing-Kang Chang
658*e7b1675dSTing-Kang Chang // Try with a wrong key type.
659*e7b1675dSTing-Kang Chang auto wrong_key_type_result = Registry::GetPublicKeyData(
660*e7b1675dSTing-Kang Chang AesGcmKeyManager().get_key_type(), ecies_key.SerializeAsString());
661*e7b1675dSTing-Kang Chang EXPECT_FALSE(wrong_key_type_result.ok());
662*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kInvalidArgument,
663*e7b1675dSTing-Kang Chang wrong_key_type_result.status().code());
664*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, "PrivateKeyFactory",
665*e7b1675dSTing-Kang Chang std::string(wrong_key_type_result.status().message()));
666*e7b1675dSTing-Kang Chang
667*e7b1675dSTing-Kang Chang // Try with a bad serialized key.
668*e7b1675dSTing-Kang Chang auto bad_key_result = Registry::GetPublicKeyData(
669*e7b1675dSTing-Kang Chang EciesAeadHkdfPrivateKeyManager().get_key_type(),
670*e7b1675dSTing-Kang Chang "some bad serialized key");
671*e7b1675dSTing-Kang Chang EXPECT_FALSE(bad_key_result.ok());
672*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kInvalidArgument, bad_key_result.status().code());
673*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, "Could not parse",
674*e7b1675dSTing-Kang Chang std::string(bad_key_result.status().message()));
675*e7b1675dSTing-Kang Chang }
676*e7b1675dSTing-Kang Chang
677*e7b1675dSTing-Kang Chang // Tests that if we register the same type of wrapper twice, the second call
678*e7b1675dSTing-Kang Chang // succeeds.
TEST_F(RegistryTest,RegisterWrapperTwice)679*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterWrapperTwice) {
680*e7b1675dSTing-Kang Chang EXPECT_TRUE(
681*e7b1675dSTing-Kang Chang Registry::RegisterPrimitiveWrapper(absl::make_unique<AeadWrapper>())
682*e7b1675dSTing-Kang Chang .ok());
683*e7b1675dSTing-Kang Chang EXPECT_TRUE(
684*e7b1675dSTing-Kang Chang Registry::RegisterPrimitiveWrapper(absl::make_unique<AeadWrapper>())
685*e7b1675dSTing-Kang Chang .ok());
686*e7b1675dSTing-Kang Chang }
687*e7b1675dSTing-Kang Chang
688*e7b1675dSTing-Kang Chang // Tests that if we register the same type of wrapper twice, the second call
689*e7b1675dSTing-Kang Chang // succeeds.
TEST_F(RegistryTest,RegisterTransformingWrapperTwice)690*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterTransformingWrapperTwice) {
691*e7b1675dSTing-Kang Chang EXPECT_TRUE(Registry::RegisterPrimitiveWrapper(
692*e7b1675dSTing-Kang Chang absl::make_unique<AeadVariantToStringWrapper>())
693*e7b1675dSTing-Kang Chang .ok());
694*e7b1675dSTing-Kang Chang EXPECT_TRUE(Registry::RegisterPrimitiveWrapper(
695*e7b1675dSTing-Kang Chang absl::make_unique<AeadVariantToStringWrapper>())
696*e7b1675dSTing-Kang Chang .ok());
697*e7b1675dSTing-Kang Chang }
698*e7b1675dSTing-Kang Chang
699*e7b1675dSTing-Kang Chang // Test that if we register a second wrapper, wrapping to the same type as a
700*e7b1675dSTing-Kang Chang // previous wrapper it will fail.
TEST_F(RegistryTest,RegisterTransformingWrapperTwiceMixing)701*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterTransformingWrapperTwiceMixing) {
702*e7b1675dSTing-Kang Chang EXPECT_TRUE(Registry::RegisterPrimitiveWrapper(
703*e7b1675dSTing-Kang Chang absl::make_unique<AeadVariantToStringWrapper>())
704*e7b1675dSTing-Kang Chang .ok());
705*e7b1675dSTing-Kang Chang // We cannot register a different wrapper creating a std::string.
706*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterPrimitiveWrapper(
707*e7b1675dSTing-Kang Chang absl::make_unique<TestWrapper<std::string>>()),
708*e7b1675dSTing-Kang Chang Not(IsOk()));
709*e7b1675dSTing-Kang Chang // But one creating an Aead.
710*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterPrimitiveWrapper(
711*e7b1675dSTing-Kang Chang absl::make_unique<TestWrapper<AeadVariant>>()),
712*e7b1675dSTing-Kang Chang IsOk());
713*e7b1675dSTing-Kang Chang }
714*e7b1675dSTing-Kang Chang
715*e7b1675dSTing-Kang Chang // Test that if we register a second wrapper, wrapping to the same type as a
716*e7b1675dSTing-Kang Chang // previous wrapper it will fail (order swapped).
TEST_F(RegistryTest,RegisterTransformingWrapperTwiceMixingBackwards)717*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterTransformingWrapperTwiceMixingBackwards) {
718*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterPrimitiveWrapper(
719*e7b1675dSTing-Kang Chang absl::make_unique<TestWrapper<std::string>>()),
720*e7b1675dSTing-Kang Chang IsOk());
721*e7b1675dSTing-Kang Chang // We cannot register another wrapper producing strings.
722*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterPrimitiveWrapper(
723*e7b1675dSTing-Kang Chang absl::make_unique<AeadVariantToStringWrapper>()),
724*e7b1675dSTing-Kang Chang Not(IsOk()));
725*e7b1675dSTing-Kang Chang }
726*e7b1675dSTing-Kang Chang
727*e7b1675dSTing-Kang Chang // Tests that if we register different wrappers for the same primitive twice,
728*e7b1675dSTing-Kang Chang // the second call fails.
TEST_F(RegistryTest,RegisterDifferentWrappers)729*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterDifferentWrappers) {
730*e7b1675dSTing-Kang Chang EXPECT_TRUE(
731*e7b1675dSTing-Kang Chang Registry::RegisterPrimitiveWrapper(absl::make_unique<AeadWrapper>())
732*e7b1675dSTing-Kang Chang .ok());
733*e7b1675dSTing-Kang Chang util::Status result = Registry::RegisterPrimitiveWrapper(
734*e7b1675dSTing-Kang Chang absl::make_unique<TestWrapper<Aead>>());
735*e7b1675dSTing-Kang Chang EXPECT_FALSE(result.ok());
736*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kAlreadyExists, result.code());
737*e7b1675dSTing-Kang Chang }
738*e7b1675dSTing-Kang Chang
739*e7b1675dSTing-Kang Chang // Tests that if we register different wrappers for different primitives, this
740*e7b1675dSTing-Kang Chang // returns ok.
TEST_F(RegistryTest,RegisterDifferentWrappersDifferentPrimitives)741*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterDifferentWrappersDifferentPrimitives) {
742*e7b1675dSTing-Kang Chang EXPECT_TRUE(
743*e7b1675dSTing-Kang Chang Registry::RegisterPrimitiveWrapper(absl::make_unique<TestWrapper<Aead>>())
744*e7b1675dSTing-Kang Chang .ok());
745*e7b1675dSTing-Kang Chang EXPECT_TRUE(
746*e7b1675dSTing-Kang Chang Registry::RegisterPrimitiveWrapper(absl::make_unique<TestWrapper<Mac>>())
747*e7b1675dSTing-Kang Chang .ok());
748*e7b1675dSTing-Kang Chang }
749*e7b1675dSTing-Kang Chang
750*e7b1675dSTing-Kang Chang // Tests that if we do not register a wrapper, then calls to Wrap
751*e7b1675dSTing-Kang Chang // fail with "No wrapper registered" -- even if there is a wrapper for a
752*e7b1675dSTing-Kang Chang // different primitive registered.
TEST_F(RegistryTest,NoWrapperRegistered)753*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, NoWrapperRegistered) {
754*e7b1675dSTing-Kang Chang EXPECT_TRUE(
755*e7b1675dSTing-Kang Chang Registry::RegisterPrimitiveWrapper(absl::make_unique<TestWrapper<Mac>>())
756*e7b1675dSTing-Kang Chang .ok());
757*e7b1675dSTing-Kang Chang
758*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<Aead>> result =
759*e7b1675dSTing-Kang Chang Registry::Wrap<Aead>(absl::make_unique<PrimitiveSet<Aead>>());
760*e7b1675dSTing-Kang Chang EXPECT_FALSE(result.ok());
761*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kNotFound, result.status().code());
762*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, "No wrapper registered",
763*e7b1675dSTing-Kang Chang std::string(result.status().message()));
764*e7b1675dSTing-Kang Chang }
765*e7b1675dSTing-Kang Chang
766*e7b1675dSTing-Kang Chang // Tests that if the wrapper fails, the error of the wrapped is forwarded
767*e7b1675dSTing-Kang Chang // in GetWrappedPrimitive.
TEST_F(RegistryTest,WrapperFails)768*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, WrapperFails) {
769*e7b1675dSTing-Kang Chang EXPECT_TRUE(
770*e7b1675dSTing-Kang Chang Registry::RegisterPrimitiveWrapper(absl::make_unique<TestWrapper<Aead>>())
771*e7b1675dSTing-Kang Chang .ok());
772*e7b1675dSTing-Kang Chang
773*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<Aead>> result =
774*e7b1675dSTing-Kang Chang Registry::Wrap<Aead>(absl::make_unique<PrimitiveSet<Aead>>());
775*e7b1675dSTing-Kang Chang EXPECT_FALSE(result.ok());
776*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, "This is a test wrapper",
777*e7b1675dSTing-Kang Chang std::string(result.status().message()));
778*e7b1675dSTing-Kang Chang }
779*e7b1675dSTing-Kang Chang
780*e7b1675dSTing-Kang Chang // Tests that wrapping works as expected in the usual case.
TEST_F(RegistryTest,UsualWrappingTest)781*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, UsualWrappingTest) {
782*e7b1675dSTing-Kang Chang KeysetInfo keyset_info;
783*e7b1675dSTing-Kang Chang
784*e7b1675dSTing-Kang Chang keyset_info.add_key_info();
785*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(0)->set_output_prefix_type(
786*e7b1675dSTing-Kang Chang OutputPrefixType::TINK);
787*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(0)->set_key_id(1234543);
788*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(0)->set_status(KeyStatusType::ENABLED);
789*e7b1675dSTing-Kang Chang keyset_info.add_key_info();
790*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(1)->set_output_prefix_type(
791*e7b1675dSTing-Kang Chang OutputPrefixType::LEGACY);
792*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(1)->set_key_id(726329);
793*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(1)->set_status(KeyStatusType::ENABLED);
794*e7b1675dSTing-Kang Chang keyset_info.add_key_info();
795*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(2)->set_output_prefix_type(
796*e7b1675dSTing-Kang Chang OutputPrefixType::TINK);
797*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(2)->set_key_id(7213743);
798*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(2)->set_status(KeyStatusType::ENABLED);
799*e7b1675dSTing-Kang Chang
800*e7b1675dSTing-Kang Chang auto primitive_set = absl::make_unique<PrimitiveSet<Aead>>();
801*e7b1675dSTing-Kang Chang ASSERT_TRUE(primitive_set
802*e7b1675dSTing-Kang Chang ->AddPrimitive(absl::make_unique<DummyAead>("aead0"),
803*e7b1675dSTing-Kang Chang keyset_info.key_info(0))
804*e7b1675dSTing-Kang Chang .ok());
805*e7b1675dSTing-Kang Chang ASSERT_TRUE(primitive_set
806*e7b1675dSTing-Kang Chang ->AddPrimitive(absl::make_unique<DummyAead>("aead1"),
807*e7b1675dSTing-Kang Chang keyset_info.key_info(1))
808*e7b1675dSTing-Kang Chang .ok());
809*e7b1675dSTing-Kang Chang auto entry_result = primitive_set->AddPrimitive(
810*e7b1675dSTing-Kang Chang absl::make_unique<DummyAead>("primary_aead"), keyset_info.key_info(2));
811*e7b1675dSTing-Kang Chang ASSERT_THAT(primitive_set->set_primary(entry_result.value()), IsOk());
812*e7b1675dSTing-Kang Chang
813*e7b1675dSTing-Kang Chang EXPECT_TRUE(
814*e7b1675dSTing-Kang Chang Registry::RegisterPrimitiveWrapper(absl::make_unique<AeadWrapper>())
815*e7b1675dSTing-Kang Chang .ok());
816*e7b1675dSTing-Kang Chang
817*e7b1675dSTing-Kang Chang auto aead_result = Registry::Wrap<Aead>(std::move(primitive_set));
818*e7b1675dSTing-Kang Chang EXPECT_TRUE(aead_result.ok()) << aead_result.status();
819*e7b1675dSTing-Kang Chang std::unique_ptr<Aead> aead = std::move(aead_result.value());
820*e7b1675dSTing-Kang Chang std::string plaintext = "some_plaintext";
821*e7b1675dSTing-Kang Chang std::string aad = "some_aad";
822*e7b1675dSTing-Kang Chang
823*e7b1675dSTing-Kang Chang auto encrypt_result = aead->Encrypt(plaintext, aad);
824*e7b1675dSTing-Kang Chang EXPECT_TRUE(encrypt_result.ok()) << encrypt_result.status();
825*e7b1675dSTing-Kang Chang std::string ciphertext = encrypt_result.value();
826*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, "primary_aead", ciphertext);
827*e7b1675dSTing-Kang Chang
828*e7b1675dSTing-Kang Chang auto decrypt_result = aead->Decrypt(ciphertext, aad);
829*e7b1675dSTing-Kang Chang EXPECT_TRUE(decrypt_result.ok()) << decrypt_result.status();
830*e7b1675dSTing-Kang Chang EXPECT_EQ(plaintext, decrypt_result.value());
831*e7b1675dSTing-Kang Chang
832*e7b1675dSTing-Kang Chang decrypt_result = aead->Decrypt("some bad ciphertext", aad);
833*e7b1675dSTing-Kang Chang EXPECT_FALSE(decrypt_result.ok());
834*e7b1675dSTing-Kang Chang EXPECT_EQ(absl::StatusCode::kInvalidArgument, decrypt_result.status().code());
835*e7b1675dSTing-Kang Chang EXPECT_PRED_FORMAT2(testing::IsSubstring, "decryption failed",
836*e7b1675dSTing-Kang Chang std::string(decrypt_result.status().message()));
837*e7b1675dSTing-Kang Chang }
838*e7b1675dSTing-Kang Chang
AddAesGcmKey(uint32_t key_id,OutputPrefixType output_prefix_type,KeyStatusType key_status_type,Keyset & modified_keyset)839*e7b1675dSTing-Kang Chang std::string AddAesGcmKey(uint32_t key_id, OutputPrefixType output_prefix_type,
840*e7b1675dSTing-Kang Chang KeyStatusType key_status_type,
841*e7b1675dSTing-Kang Chang Keyset& modified_keyset) {
842*e7b1675dSTing-Kang Chang AesGcmKey key;
843*e7b1675dSTing-Kang Chang key.set_version(0);
844*e7b1675dSTing-Kang Chang key.set_key_value(subtle::Random::GetRandomBytes(16));
845*e7b1675dSTing-Kang Chang KeyData key_data;
846*e7b1675dSTing-Kang Chang key_data.set_value(key.SerializeAsString());
847*e7b1675dSTing-Kang Chang key_data.set_type_url("type.googleapis.com/google.crypto.tink.AesGcmKey");
848*e7b1675dSTing-Kang Chang test::AddKeyData(key_data, key_id, output_prefix_type, key_status_type,
849*e7b1675dSTing-Kang Chang &modified_keyset);
850*e7b1675dSTing-Kang Chang return key.key_value();
851*e7b1675dSTing-Kang Chang }
852*e7b1675dSTing-Kang Chang
853*e7b1675dSTing-Kang Chang // Tests that wrapping of a keyset works in the usual case.
TEST_F(RegistryTest,KeysetWrappingTest)854*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, KeysetWrappingTest) {
855*e7b1675dSTing-Kang Chang if (!IsFipsEnabledInSsl()) {
856*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported when BoringSSL is not built in FIPS-mode.";
857*e7b1675dSTing-Kang Chang }
858*e7b1675dSTing-Kang Chang
859*e7b1675dSTing-Kang Chang Keyset keyset;
860*e7b1675dSTing-Kang Chang std::string raw_key =
861*e7b1675dSTing-Kang Chang AddAesGcmKey(13, OutputPrefixType::TINK, KeyStatusType::ENABLED, keyset);
862*e7b1675dSTing-Kang Chang keyset.set_primary_key_id(13);
863*e7b1675dSTing-Kang Chang
864*e7b1675dSTing-Kang Chang auto fips_key_manager = absl::make_unique<ExampleKeyTypeManager>();
865*e7b1675dSTing-Kang Chang
866*e7b1675dSTing-Kang Chang ON_CALL(*fips_key_manager, FipsStatus())
867*e7b1675dSTing-Kang Chang .WillByDefault(testing::Return(FipsCompatibility::kRequiresBoringCrypto));
868*e7b1675dSTing-Kang Chang
869*e7b1675dSTing-Kang Chang ASSERT_THAT(
870*e7b1675dSTing-Kang Chang Registry::RegisterKeyTypeManager(std::move(fips_key_manager), true),
871*e7b1675dSTing-Kang Chang IsOk());
872*e7b1675dSTing-Kang Chang ASSERT_THAT(Registry::RegisterPrimitiveWrapper(
873*e7b1675dSTing-Kang Chang absl::make_unique<AeadVariantWrapper>()),
874*e7b1675dSTing-Kang Chang IsOk());
875*e7b1675dSTing-Kang Chang
876*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<AeadVariant>> aead_variant =
877*e7b1675dSTing-Kang Chang RegistryImpl::GlobalInstance().WrapKeyset<AeadVariant>(
878*e7b1675dSTing-Kang Chang keyset, /*annotations=*/{});
879*e7b1675dSTing-Kang Chang EXPECT_THAT(aead_variant, IsOk());
880*e7b1675dSTing-Kang Chang EXPECT_THAT(aead_variant.value()->get(), Eq(raw_key));
881*e7b1675dSTing-Kang Chang }
882*e7b1675dSTing-Kang Chang
883*e7b1675dSTing-Kang Chang // Tests that wrapping of a keyset works.
TEST_F(RegistryTest,TransformingKeysetWrappingTest)884*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, TransformingKeysetWrappingTest) {
885*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
886*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
887*e7b1675dSTing-Kang Chang }
888*e7b1675dSTing-Kang Chang
889*e7b1675dSTing-Kang Chang Keyset keyset;
890*e7b1675dSTing-Kang Chang std::string raw_key =
891*e7b1675dSTing-Kang Chang AddAesGcmKey(13, OutputPrefixType::TINK, KeyStatusType::ENABLED, keyset);
892*e7b1675dSTing-Kang Chang keyset.set_primary_key_id(13);
893*e7b1675dSTing-Kang Chang
894*e7b1675dSTing-Kang Chang ASSERT_THAT(Registry::RegisterKeyTypeManager(
895*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
896*e7b1675dSTing-Kang Chang IsOk());
897*e7b1675dSTing-Kang Chang ASSERT_THAT(Registry::RegisterPrimitiveWrapper(
898*e7b1675dSTing-Kang Chang absl::make_unique<AeadVariantToStringWrapper>()),
899*e7b1675dSTing-Kang Chang IsOk());
900*e7b1675dSTing-Kang Chang
901*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<std::string>> string_primitive =
902*e7b1675dSTing-Kang Chang RegistryImpl::GlobalInstance().WrapKeyset<std::string>(
903*e7b1675dSTing-Kang Chang keyset, /*annotations=*/{});
904*e7b1675dSTing-Kang Chang EXPECT_THAT(string_primitive, IsOk());
905*e7b1675dSTing-Kang Chang EXPECT_THAT(*string_primitive.value(), Eq(raw_key));
906*e7b1675dSTing-Kang Chang }
907*e7b1675dSTing-Kang Chang
908*e7b1675dSTing-Kang Chang // Tests that when we ask the registry to wrap a PrimitiveSet<Aead> into an
909*e7b1675dSTing-Kang Chang // Aead, but the wrapper is in fact from something else into Aead, we give a
910*e7b1675dSTing-Kang Chang // correct error message.
TEST_F(RegistryTest,TransformingPrimitiveWrapperCustomKeyManager)911*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, TransformingPrimitiveWrapperCustomKeyManager) {
912*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
913*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
914*e7b1675dSTing-Kang Chang }
915*e7b1675dSTing-Kang Chang
916*e7b1675dSTing-Kang Chang ASSERT_THAT(Registry::RegisterKeyTypeManager(
917*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
918*e7b1675dSTing-Kang Chang IsOk());
919*e7b1675dSTing-Kang Chang // Register a transforming wrapper taking strings and making Aeads.
920*e7b1675dSTing-Kang Chang ASSERT_THAT(Registry::RegisterPrimitiveWrapper(
921*e7b1675dSTing-Kang Chang absl::make_unique<TestWrapper<std::string, Aead>>()),
922*e7b1675dSTing-Kang Chang IsOk());
923*e7b1675dSTing-Kang Chang
924*e7b1675dSTing-Kang Chang KeysetInfo keyset_info;
925*e7b1675dSTing-Kang Chang keyset_info.add_key_info();
926*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(0)->set_output_prefix_type(
927*e7b1675dSTing-Kang Chang OutputPrefixType::TINK);
928*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(0)->set_key_id(1234543);
929*e7b1675dSTing-Kang Chang keyset_info.mutable_key_info(0)->set_status(KeyStatusType::ENABLED);
930*e7b1675dSTing-Kang Chang keyset_info.set_primary_key_id(1234543);
931*e7b1675dSTing-Kang Chang
932*e7b1675dSTing-Kang Chang auto primitive_set = absl::make_unique<PrimitiveSet<Aead>>();
933*e7b1675dSTing-Kang Chang ASSERT_TRUE(primitive_set
934*e7b1675dSTing-Kang Chang ->AddPrimitive(absl::make_unique<DummyAead>("aead0"),
935*e7b1675dSTing-Kang Chang keyset_info.key_info(0))
936*e7b1675dSTing-Kang Chang .ok());
937*e7b1675dSTing-Kang Chang
938*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::Wrap<Aead>(std::move(primitive_set)).status(),
939*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kFailedPrecondition,
940*e7b1675dSTing-Kang Chang HasSubstr("custom key manager")));
941*e7b1675dSTing-Kang Chang }
942*e7b1675dSTing-Kang Chang
943*e7b1675dSTing-Kang Chang // Tests that the error message in GetKeyManager contains the type_id.name() of
944*e7b1675dSTing-Kang Chang // the primitive for which the key manager was actually registered.
TEST_F(RegistryTest,GetKeyManagerErrorMessage)945*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, GetKeyManagerErrorMessage) {
946*e7b1675dSTing-Kang Chang AesGcmKeyManager key_type_manager;
947*e7b1675dSTing-Kang Chang EXPECT_TRUE(
948*e7b1675dSTing-Kang Chang Registry::RegisterKeyManager(
949*e7b1675dSTing-Kang Chang crypto::tink::internal::MakeKeyManager<Aead>(&key_type_manager), true)
950*e7b1675dSTing-Kang Chang .ok());
951*e7b1675dSTing-Kang Chang auto result =
952*e7b1675dSTing-Kang Chang Registry::get_key_manager<int>(AesGcmKeyManager().get_key_type());
953*e7b1675dSTing-Kang Chang EXPECT_FALSE(result.ok());
954*e7b1675dSTing-Kang Chang EXPECT_THAT(std::string(result.status().message()),
955*e7b1675dSTing-Kang Chang HasSubstr(AesGcmKeyManager().get_key_type()));
956*e7b1675dSTing-Kang Chang // Note: The C++ standard does not guarantee the next line. If some toolchain
957*e7b1675dSTing-Kang Chang // update fails it, one can delete it.
958*e7b1675dSTing-Kang Chang EXPECT_THAT(std::string(result.status().message()),
959*e7b1675dSTing-Kang Chang HasSubstr(typeid(Aead).name()));
960*e7b1675dSTing-Kang Chang }
961*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterKeyTypeManager)962*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterKeyTypeManager) {
963*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
964*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
965*e7b1675dSTing-Kang Chang }
966*e7b1675dSTing-Kang Chang
967*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
968*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
969*e7b1675dSTing-Kang Chang IsOk());
970*e7b1675dSTing-Kang Chang }
971*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterFipsKeyTypeManager)972*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterFipsKeyTypeManager) {
973*e7b1675dSTing-Kang Chang if (!kUseOnlyFips || !IsFipsEnabledInSsl()) {
974*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Only supported in FIPS-mode with BoringCrypto available.";
975*e7b1675dSTing-Kang Chang }
976*e7b1675dSTing-Kang Chang
977*e7b1675dSTing-Kang Chang auto fips_key_manager = absl::make_unique<ExampleKeyTypeManager>();
978*e7b1675dSTing-Kang Chang
979*e7b1675dSTing-Kang Chang ON_CALL(*fips_key_manager, FipsStatus())
980*e7b1675dSTing-Kang Chang .WillByDefault(testing::Return(FipsCompatibility::kRequiresBoringCrypto));
981*e7b1675dSTing-Kang Chang
982*e7b1675dSTing-Kang Chang EXPECT_THAT(
983*e7b1675dSTing-Kang Chang Registry::RegisterKeyTypeManager(std::move(fips_key_manager), true),
984*e7b1675dSTing-Kang Chang IsOk());
985*e7b1675dSTing-Kang Chang }
986*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterFipsKeyTypeManagerNoBoringCrypto)987*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterFipsKeyTypeManagerNoBoringCrypto) {
988*e7b1675dSTing-Kang Chang if (!kUseOnlyFips || IsFipsEnabledInSsl()) {
989*e7b1675dSTing-Kang Chang GTEST_SKIP()
990*e7b1675dSTing-Kang Chang << "Only supported in FIPS-mode with BoringCrypto not available.";
991*e7b1675dSTing-Kang Chang }
992*e7b1675dSTing-Kang Chang
993*e7b1675dSTing-Kang Chang auto fips_key_manager = absl::make_unique<ExampleKeyTypeManager>();
994*e7b1675dSTing-Kang Chang
995*e7b1675dSTing-Kang Chang ON_CALL(*fips_key_manager, FipsStatus())
996*e7b1675dSTing-Kang Chang .WillByDefault(testing::Return(FipsCompatibility::kNotFips));
997*e7b1675dSTing-Kang Chang
998*e7b1675dSTing-Kang Chang EXPECT_THAT(
999*e7b1675dSTing-Kang Chang Registry::RegisterKeyTypeManager(std::move(fips_key_manager), true),
1000*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kInternal));
1001*e7b1675dSTing-Kang Chang }
1002*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,KeyTypeManagerGetFirstKeyManager)1003*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, KeyTypeManagerGetFirstKeyManager) {
1004*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1005*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1006*e7b1675dSTing-Kang Chang }
1007*e7b1675dSTing-Kang Chang
1008*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1009*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1010*e7b1675dSTing-Kang Chang IsOk());
1011*e7b1675dSTing-Kang Chang AesGcmKeyFormat format;
1012*e7b1675dSTing-Kang Chang format.set_key_size(16);
1013*e7b1675dSTing-Kang Chang AesGcmKey key = ExampleKeyTypeManager().CreateKey(format).value();
1014*e7b1675dSTing-Kang Chang auto aead = Registry::get_key_manager<Aead>(
1015*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.AesGcmKey")
1016*e7b1675dSTing-Kang Chang .value()
1017*e7b1675dSTing-Kang Chang ->GetPrimitive(key)
1018*e7b1675dSTing-Kang Chang .value();
1019*e7b1675dSTing-Kang Chang std::string encryption = aead->Encrypt("TESTMESSAGE", "").value();
1020*e7b1675dSTing-Kang Chang std::string decryption = aead->Decrypt(encryption, "").value();
1021*e7b1675dSTing-Kang Chang EXPECT_THAT(decryption, Eq("TESTMESSAGE"));
1022*e7b1675dSTing-Kang Chang }
1023*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,KeyTypeManagerGetSecondKeyManager)1024*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, KeyTypeManagerGetSecondKeyManager) {
1025*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1026*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1027*e7b1675dSTing-Kang Chang }
1028*e7b1675dSTing-Kang Chang
1029*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1030*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1031*e7b1675dSTing-Kang Chang IsOk());
1032*e7b1675dSTing-Kang Chang AesGcmKeyFormat format;
1033*e7b1675dSTing-Kang Chang format.set_key_size(16);
1034*e7b1675dSTing-Kang Chang AesGcmKey key = ExampleKeyTypeManager().CreateKey(format).value();
1035*e7b1675dSTing-Kang Chang auto aead_variant = Registry::get_key_manager<AeadVariant>(
1036*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.AesGcmKey")
1037*e7b1675dSTing-Kang Chang .value()
1038*e7b1675dSTing-Kang Chang ->GetPrimitive(key)
1039*e7b1675dSTing-Kang Chang .value();
1040*e7b1675dSTing-Kang Chang EXPECT_THAT(aead_variant->get(), Eq(key.key_value()));
1041*e7b1675dSTing-Kang Chang }
1042*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,KeyTypeManagerNotSupportedPrimitive)1043*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, KeyTypeManagerNotSupportedPrimitive) {
1044*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1045*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1046*e7b1675dSTing-Kang Chang }
1047*e7b1675dSTing-Kang Chang
1048*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1049*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1050*e7b1675dSTing-Kang Chang IsOk());
1051*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::get_key_manager<Mac>(
1052*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.AesGcmKey")
1053*e7b1675dSTing-Kang Chang .status(),
1054*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kInvalidArgument,
1055*e7b1675dSTing-Kang Chang HasSubstr("not among supported primitives")));
1056*e7b1675dSTing-Kang Chang }
1057*e7b1675dSTing-Kang Chang
1058*e7b1675dSTing-Kang Chang // Tests that if we register a key manager once more after a call to
1059*e7b1675dSTing-Kang Chang // get_key_manager, the key manager previously obtained with "get_key_manager()"
1060*e7b1675dSTing-Kang Chang // remains valid.
TEST_F(RegistryTest,GetKeyManagerRemainsValidForKeyTypeManagers)1061*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, GetKeyManagerRemainsValidForKeyTypeManagers) {
1062*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1063*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1064*e7b1675dSTing-Kang Chang }
1065*e7b1675dSTing-Kang Chang
1066*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1067*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1068*e7b1675dSTing-Kang Chang IsOk());
1069*e7b1675dSTing-Kang Chang
1070*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<const KeyManager<Aead>*> key_manager =
1071*e7b1675dSTing-Kang Chang Registry::get_key_manager<Aead>(ExampleKeyTypeManager().get_key_type());
1072*e7b1675dSTing-Kang Chang ASSERT_THAT(key_manager, IsOk());
1073*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1074*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1075*e7b1675dSTing-Kang Chang IsOk());
1076*e7b1675dSTing-Kang Chang EXPECT_THAT(key_manager.value()->get_key_type(),
1077*e7b1675dSTing-Kang Chang Eq(ExampleKeyTypeManager().get_key_type()));
1078*e7b1675dSTing-Kang Chang }
1079*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,KeyTypeManagerNewKey)1080*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, KeyTypeManagerNewKey) {
1081*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1082*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1083*e7b1675dSTing-Kang Chang }
1084*e7b1675dSTing-Kang Chang
1085*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1086*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1087*e7b1675dSTing-Kang Chang IsOk());
1088*e7b1675dSTing-Kang Chang
1089*e7b1675dSTing-Kang Chang AesGcmKeyFormat format;
1090*e7b1675dSTing-Kang Chang format.set_key_size(32);
1091*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1092*e7b1675dSTing-Kang Chang key_template.set_type_url("type.googleapis.com/google.crypto.tink.AesGcmKey");
1093*e7b1675dSTing-Kang Chang key_template.set_value(format.SerializeAsString());
1094*e7b1675dSTing-Kang Chang
1095*e7b1675dSTing-Kang Chang KeyData key_data = *Registry::NewKeyData(key_template).value();
1096*e7b1675dSTing-Kang Chang EXPECT_THAT(key_data.type_url(),
1097*e7b1675dSTing-Kang Chang Eq("type.googleapis.com/google.crypto.tink.AesGcmKey"));
1098*e7b1675dSTing-Kang Chang EXPECT_THAT(key_data.key_material_type(),
1099*e7b1675dSTing-Kang Chang Eq(google::crypto::tink::KeyData::SYMMETRIC));
1100*e7b1675dSTing-Kang Chang AesGcmKey key;
1101*e7b1675dSTing-Kang Chang key.ParseFromString(key_data.value());
1102*e7b1675dSTing-Kang Chang EXPECT_THAT(key.key_value(), SizeIs(32));
1103*e7b1675dSTing-Kang Chang }
1104*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,KeyTypeManagerNewKeyInvalidSize)1105*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, KeyTypeManagerNewKeyInvalidSize) {
1106*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1107*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1108*e7b1675dSTing-Kang Chang }
1109*e7b1675dSTing-Kang Chang
1110*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1111*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1112*e7b1675dSTing-Kang Chang IsOk());
1113*e7b1675dSTing-Kang Chang
1114*e7b1675dSTing-Kang Chang AesGcmKeyFormat format;
1115*e7b1675dSTing-Kang Chang format.set_key_size(33);
1116*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1117*e7b1675dSTing-Kang Chang key_template.set_type_url("type.googleapis.com/google.crypto.tink.AesGcmKey");
1118*e7b1675dSTing-Kang Chang key_template.set_value(format.SerializeAsString());
1119*e7b1675dSTing-Kang Chang
1120*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::NewKeyData(key_template), IsOk());
1121*e7b1675dSTing-Kang Chang }
1122*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,KeyTypeManagerDeriveKey)1123*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, KeyTypeManagerDeriveKey) {
1124*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1125*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1126*e7b1675dSTing-Kang Chang }
1127*e7b1675dSTing-Kang Chang
1128*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1129*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1130*e7b1675dSTing-Kang Chang IsOk());
1131*e7b1675dSTing-Kang Chang
1132*e7b1675dSTing-Kang Chang AesGcmKeyFormat format;
1133*e7b1675dSTing-Kang Chang format.set_key_size(32);
1134*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1135*e7b1675dSTing-Kang Chang key_template.set_type_url("type.googleapis.com/google.crypto.tink.AesGcmKey");
1136*e7b1675dSTing-Kang Chang key_template.set_value(format.SerializeAsString());
1137*e7b1675dSTing-Kang Chang
1138*e7b1675dSTing-Kang Chang crypto::tink::util::IstreamInputStream input_stream{
1139*e7b1675dSTing-Kang Chang absl::make_unique<std::stringstream>(
1140*e7b1675dSTing-Kang Chang "0123456789012345678901234567890123456789")};
1141*e7b1675dSTing-Kang Chang
1142*e7b1675dSTing-Kang Chang auto key_data_or =
1143*e7b1675dSTing-Kang Chang RegistryImpl::GlobalInstance().DeriveKey(key_template, &input_stream);
1144*e7b1675dSTing-Kang Chang ASSERT_THAT(key_data_or, IsOk());
1145*e7b1675dSTing-Kang Chang EXPECT_THAT(key_data_or.value().type_url(), Eq(key_template.type_url()));
1146*e7b1675dSTing-Kang Chang AesGcmKey key;
1147*e7b1675dSTing-Kang Chang EXPECT_TRUE(key.ParseFromString(key_data_or.value().value()));
1148*e7b1675dSTing-Kang Chang // 32 byte prefix of above string.
1149*e7b1675dSTing-Kang Chang EXPECT_THAT(key.key_value(), Eq("01234567890123456789012345678901"));
1150*e7b1675dSTing-Kang Chang }
1151*e7b1675dSTing-Kang Chang
1152*e7b1675dSTing-Kang Chang // The same, but we register the key manager twice. This should catch some of
1153*e7b1675dSTing-Kang Chang // the possible lifetime issues.
TEST_F(RegistryTest,KeyTypeManagerDeriveKeyRegisterTwice)1154*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, KeyTypeManagerDeriveKeyRegisterTwice) {
1155*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1156*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1157*e7b1675dSTing-Kang Chang }
1158*e7b1675dSTing-Kang Chang
1159*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1160*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1161*e7b1675dSTing-Kang Chang IsOk());
1162*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1163*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1164*e7b1675dSTing-Kang Chang IsOk());
1165*e7b1675dSTing-Kang Chang
1166*e7b1675dSTing-Kang Chang AesGcmKeyFormat format;
1167*e7b1675dSTing-Kang Chang format.set_key_size(32);
1168*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1169*e7b1675dSTing-Kang Chang key_template.set_type_url("type.googleapis.com/google.crypto.tink.AesGcmKey");
1170*e7b1675dSTing-Kang Chang key_template.set_value(format.SerializeAsString());
1171*e7b1675dSTing-Kang Chang
1172*e7b1675dSTing-Kang Chang crypto::tink::util::IstreamInputStream input_stream{
1173*e7b1675dSTing-Kang Chang absl::make_unique<std::stringstream>(
1174*e7b1675dSTing-Kang Chang "0123456789012345678901234567890123456789")};
1175*e7b1675dSTing-Kang Chang
1176*e7b1675dSTing-Kang Chang auto key_data_or =
1177*e7b1675dSTing-Kang Chang RegistryImpl::GlobalInstance().DeriveKey(key_template, &input_stream);
1178*e7b1675dSTing-Kang Chang ASSERT_THAT(key_data_or, IsOk());
1179*e7b1675dSTing-Kang Chang EXPECT_THAT(key_data_or.value().type_url(), Eq(key_template.type_url()));
1180*e7b1675dSTing-Kang Chang AesGcmKey key;
1181*e7b1675dSTing-Kang Chang EXPECT_TRUE(key.ParseFromString(key_data_or.value().value()));
1182*e7b1675dSTing-Kang Chang // 32 byte prefix of above string.
1183*e7b1675dSTing-Kang Chang EXPECT_THAT(key.key_value(), Eq("01234567890123456789012345678901"));
1184*e7b1675dSTing-Kang Chang }
1185*e7b1675dSTing-Kang Chang
1186*e7b1675dSTing-Kang Chang // Tests that if we register a KeyManager instead of a KeyTypeManager, DeriveKey
1187*e7b1675dSTing-Kang Chang // fails properly.
TEST_F(RegistryTest,KeyManagerDeriveKeyFail)1188*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, KeyManagerDeriveKeyFail) {
1189*e7b1675dSTing-Kang Chang std::string key_type = "type.googleapis.com/google.crypto.tink.AesGcmKey";
1190*e7b1675dSTing-Kang Chang ASSERT_THAT(Registry::RegisterKeyManager(
1191*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(key_type),
1192*e7b1675dSTing-Kang Chang /* new_key_allowed= */ true),
1193*e7b1675dSTing-Kang Chang IsOk());
1194*e7b1675dSTing-Kang Chang
1195*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1196*e7b1675dSTing-Kang Chang key_template.set_type_url("type.googleapis.com/google.crypto.tink.AesGcmKey");
1197*e7b1675dSTing-Kang Chang
1198*e7b1675dSTing-Kang Chang EXPECT_THAT(
1199*e7b1675dSTing-Kang Chang RegistryImpl::GlobalInstance().DeriveKey(key_template, nullptr).status(),
1200*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("cannot derive")));
1201*e7b1675dSTing-Kang Chang }
1202*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,KeyManagerDeriveNotRegistered)1203*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, KeyManagerDeriveNotRegistered) {
1204*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1205*e7b1675dSTing-Kang Chang key_template.set_type_url("some_inexistent_keytype");
1206*e7b1675dSTing-Kang Chang
1207*e7b1675dSTing-Kang Chang EXPECT_THAT(
1208*e7b1675dSTing-Kang Chang RegistryImpl::GlobalInstance().DeriveKey(key_template, nullptr).status(),
1209*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kNotFound, HasSubstr("No manager")));
1210*e7b1675dSTing-Kang Chang }
1211*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterKeyTypeManagerTwiceMoreRestrictive)1212*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterKeyTypeManagerTwiceMoreRestrictive) {
1213*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1214*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1215*e7b1675dSTing-Kang Chang }
1216*e7b1675dSTing-Kang Chang
1217*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1218*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1219*e7b1675dSTing-Kang Chang IsOk());
1220*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1221*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), false),
1222*e7b1675dSTing-Kang Chang IsOk());
1223*e7b1675dSTing-Kang Chang }
1224*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterKeyTypeManagerTwice)1225*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterKeyTypeManagerTwice) {
1226*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1227*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1228*e7b1675dSTing-Kang Chang }
1229*e7b1675dSTing-Kang Chang
1230*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1231*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1232*e7b1675dSTing-Kang Chang IsOk());
1233*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1234*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1235*e7b1675dSTing-Kang Chang IsOk());
1236*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1237*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), false),
1238*e7b1675dSTing-Kang Chang IsOk());
1239*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1240*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), false),
1241*e7b1675dSTing-Kang Chang IsOk());
1242*e7b1675dSTing-Kang Chang }
1243*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterKeyTypeManagerLessRestrictive)1244*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterKeyTypeManagerLessRestrictive) {
1245*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1246*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1247*e7b1675dSTing-Kang Chang }
1248*e7b1675dSTing-Kang Chang
1249*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1250*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), false),
1251*e7b1675dSTing-Kang Chang IsOk());
1252*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1253*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1254*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kAlreadyExists));
1255*e7b1675dSTing-Kang Chang }
1256*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterKeyTypeManagerBeforeKeyManager)1257*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterKeyTypeManagerBeforeKeyManager) {
1258*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1259*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1260*e7b1675dSTing-Kang Chang }
1261*e7b1675dSTing-Kang Chang
1262*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1263*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1264*e7b1675dSTing-Kang Chang IsOk());
1265*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyManager(
1266*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(
1267*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.AesGcmKey"),
1268*e7b1675dSTing-Kang Chang true),
1269*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kAlreadyExists));
1270*e7b1675dSTing-Kang Chang }
1271*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterKeyTypeManagerAfterKeyManager)1272*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterKeyTypeManagerAfterKeyManager) {
1273*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1274*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1275*e7b1675dSTing-Kang Chang }
1276*e7b1675dSTing-Kang Chang
1277*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyManager(
1278*e7b1675dSTing-Kang Chang absl::make_unique<TestAeadKeyManager>(
1279*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.AesGcmKey"),
1280*e7b1675dSTing-Kang Chang true),
1281*e7b1675dSTing-Kang Chang IsOk());
1282*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1283*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true),
1284*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kAlreadyExists));
1285*e7b1675dSTing-Kang Chang }
1286*e7b1675dSTing-Kang Chang
1287*e7b1675dSTing-Kang Chang } // namespace
1288*e7b1675dSTing-Kang Chang
1289*e7b1675dSTing-Kang Chang // NOTE: These are outside of the anonymous namespace to allow compiling with
1290*e7b1675dSTing-Kang Chang // MSVC.
1291*e7b1675dSTing-Kang Chang class PrivatePrimitiveA {};
1292*e7b1675dSTing-Kang Chang class PrivatePrimitiveB {};
1293*e7b1675dSTing-Kang Chang
1294*e7b1675dSTing-Kang Chang namespace {
1295*e7b1675dSTing-Kang Chang
1296*e7b1675dSTing-Kang Chang class TestPrivateKeyTypeManager
1297*e7b1675dSTing-Kang Chang : public PrivateKeyTypeManager<EcdsaPrivateKey, EcdsaKeyFormat,
1298*e7b1675dSTing-Kang Chang EcdsaPublicKey,
1299*e7b1675dSTing-Kang Chang List<PrivatePrimitiveA, PrivatePrimitiveB>> {
1300*e7b1675dSTing-Kang Chang public:
1301*e7b1675dSTing-Kang Chang class PrivatePrimitiveAFactory : public PrimitiveFactory<PrivatePrimitiveA> {
1302*e7b1675dSTing-Kang Chang public:
Create(const EcdsaPrivateKey & key) const1303*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<PrivatePrimitiveA>> Create(
1304*e7b1675dSTing-Kang Chang const EcdsaPrivateKey& key) const override {
1305*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kUnimplemented, "Not implemented");
1306*e7b1675dSTing-Kang Chang }
1307*e7b1675dSTing-Kang Chang };
1308*e7b1675dSTing-Kang Chang class PrivatePrimitiveBFactory : public PrimitiveFactory<PrivatePrimitiveB> {
1309*e7b1675dSTing-Kang Chang public:
Create(const EcdsaPrivateKey & key) const1310*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<PrivatePrimitiveB>> Create(
1311*e7b1675dSTing-Kang Chang const EcdsaPrivateKey& key) const override {
1312*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kUnimplemented, "Not implemented");
1313*e7b1675dSTing-Kang Chang }
1314*e7b1675dSTing-Kang Chang };
1315*e7b1675dSTing-Kang Chang
TestPrivateKeyTypeManager()1316*e7b1675dSTing-Kang Chang TestPrivateKeyTypeManager()
1317*e7b1675dSTing-Kang Chang : PrivateKeyTypeManager(absl::make_unique<PrivatePrimitiveAFactory>(),
1318*e7b1675dSTing-Kang Chang absl::make_unique<PrivatePrimitiveBFactory>()) {}
1319*e7b1675dSTing-Kang Chang
key_material_type() const1320*e7b1675dSTing-Kang Chang google::crypto::tink::KeyData::KeyMaterialType key_material_type()
1321*e7b1675dSTing-Kang Chang const override {
1322*e7b1675dSTing-Kang Chang return google::crypto::tink::KeyData::ASYMMETRIC_PRIVATE;
1323*e7b1675dSTing-Kang Chang }
1324*e7b1675dSTing-Kang Chang
get_version() const1325*e7b1675dSTing-Kang Chang uint32_t get_version() const override { return 0; }
ValidateKey(const EcdsaPrivateKey & key) const1326*e7b1675dSTing-Kang Chang crypto::tink::util::Status ValidateKey(
1327*e7b1675dSTing-Kang Chang const EcdsaPrivateKey& key) const override {
1328*e7b1675dSTing-Kang Chang return crypto::tink::util::OkStatus();
1329*e7b1675dSTing-Kang Chang }
ValidateKeyFormat(const EcdsaKeyFormat & key) const1330*e7b1675dSTing-Kang Chang crypto::tink::util::Status ValidateKeyFormat(
1331*e7b1675dSTing-Kang Chang const EcdsaKeyFormat& key) const override {
1332*e7b1675dSTing-Kang Chang return crypto::tink::util::OkStatus();
1333*e7b1675dSTing-Kang Chang }
1334*e7b1675dSTing-Kang Chang
get_key_type() const1335*e7b1675dSTing-Kang Chang const std::string& get_key_type() const override { return kKeyType; }
1336*e7b1675dSTing-Kang Chang
CreateKey(const EcdsaKeyFormat & key_format) const1337*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<EcdsaPrivateKey> CreateKey(
1338*e7b1675dSTing-Kang Chang const EcdsaKeyFormat& key_format) const override {
1339*e7b1675dSTing-Kang Chang EcdsaPublicKey public_key;
1340*e7b1675dSTing-Kang Chang *public_key.mutable_params() = key_format.params();
1341*e7b1675dSTing-Kang Chang EcdsaPrivateKey result;
1342*e7b1675dSTing-Kang Chang *result.mutable_public_key() = public_key;
1343*e7b1675dSTing-Kang Chang return result;
1344*e7b1675dSTing-Kang Chang }
1345*e7b1675dSTing-Kang Chang
GetPublicKey(const EcdsaPrivateKey & private_key) const1346*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<EcdsaPublicKey> GetPublicKey(
1347*e7b1675dSTing-Kang Chang const EcdsaPrivateKey& private_key) const override {
1348*e7b1675dSTing-Kang Chang return private_key.public_key();
1349*e7b1675dSTing-Kang Chang }
1350*e7b1675dSTing-Kang Chang
1351*e7b1675dSTing-Kang Chang MOCK_METHOD(FipsCompatibility, FipsStatus, (), (const, override));
1352*e7b1675dSTing-Kang Chang
1353*e7b1675dSTing-Kang Chang private:
1354*e7b1675dSTing-Kang Chang const std::string kKeyType =
1355*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey";
1356*e7b1675dSTing-Kang Chang };
1357*e7b1675dSTing-Kang Chang
1358*e7b1675dSTing-Kang Chang } // namespace
1359*e7b1675dSTing-Kang Chang
1360*e7b1675dSTing-Kang Chang // NOTE: These are outside of the anonymous namespace to allow compiling with
1361*e7b1675dSTing-Kang Chang // MSVC.
1362*e7b1675dSTing-Kang Chang class PublicPrimitiveA {};
1363*e7b1675dSTing-Kang Chang class PublicPrimitiveB {};
1364*e7b1675dSTing-Kang Chang
1365*e7b1675dSTing-Kang Chang namespace {
1366*e7b1675dSTing-Kang Chang
1367*e7b1675dSTing-Kang Chang class TestPublicKeyTypeManager
1368*e7b1675dSTing-Kang Chang : public KeyTypeManager<EcdsaPublicKey, void,
1369*e7b1675dSTing-Kang Chang List<PublicPrimitiveA, PublicPrimitiveB>> {
1370*e7b1675dSTing-Kang Chang public:
1371*e7b1675dSTing-Kang Chang class PublicPrimitiveAFactory : public PrimitiveFactory<PublicPrimitiveA> {
1372*e7b1675dSTing-Kang Chang public:
Create(const EcdsaPublicKey & key) const1373*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<PublicPrimitiveA>> Create(
1374*e7b1675dSTing-Kang Chang const EcdsaPublicKey& key) const override {
1375*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kUnimplemented, "Not implemented");
1376*e7b1675dSTing-Kang Chang }
1377*e7b1675dSTing-Kang Chang };
1378*e7b1675dSTing-Kang Chang class PublicPrimitiveBFactory : public PrimitiveFactory<PublicPrimitiveB> {
1379*e7b1675dSTing-Kang Chang public:
Create(const EcdsaPublicKey & key) const1380*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<PublicPrimitiveB>> Create(
1381*e7b1675dSTing-Kang Chang const EcdsaPublicKey& key) const override {
1382*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kUnimplemented, "Not implemented");
1383*e7b1675dSTing-Kang Chang }
1384*e7b1675dSTing-Kang Chang };
1385*e7b1675dSTing-Kang Chang
TestPublicKeyTypeManager()1386*e7b1675dSTing-Kang Chang TestPublicKeyTypeManager()
1387*e7b1675dSTing-Kang Chang : KeyTypeManager(absl::make_unique<PublicPrimitiveAFactory>(),
1388*e7b1675dSTing-Kang Chang absl::make_unique<PublicPrimitiveBFactory>()) {}
1389*e7b1675dSTing-Kang Chang
key_material_type() const1390*e7b1675dSTing-Kang Chang google::crypto::tink::KeyData::KeyMaterialType key_material_type()
1391*e7b1675dSTing-Kang Chang const override {
1392*e7b1675dSTing-Kang Chang return google::crypto::tink::KeyData::ASYMMETRIC_PRIVATE;
1393*e7b1675dSTing-Kang Chang }
1394*e7b1675dSTing-Kang Chang
get_version() const1395*e7b1675dSTing-Kang Chang uint32_t get_version() const override { return 0; }
ValidateKey(const EcdsaPublicKey & key) const1396*e7b1675dSTing-Kang Chang crypto::tink::util::Status ValidateKey(
1397*e7b1675dSTing-Kang Chang const EcdsaPublicKey& key) const override {
1398*e7b1675dSTing-Kang Chang return crypto::tink::util::OkStatus();
1399*e7b1675dSTing-Kang Chang }
1400*e7b1675dSTing-Kang Chang
get_key_type() const1401*e7b1675dSTing-Kang Chang const std::string& get_key_type() const override { return kKeyType; }
1402*e7b1675dSTing-Kang Chang
1403*e7b1675dSTing-Kang Chang MOCK_METHOD(FipsCompatibility, FipsStatus, (), (const, override));
1404*e7b1675dSTing-Kang Chang
1405*e7b1675dSTing-Kang Chang private:
1406*e7b1675dSTing-Kang Chang const std::string kKeyType =
1407*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.EcdsaPublicKey";
1408*e7b1675dSTing-Kang Chang };
1409*e7b1675dSTing-Kang Chang
1410*e7b1675dSTing-Kang Chang std::unique_ptr<TestPrivateKeyTypeManager>
CreateTestPrivateKeyManagerFipsCompatible()1411*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible() {
1412*e7b1675dSTing-Kang Chang auto private_key_manager = absl::make_unique<TestPrivateKeyTypeManager>();
1413*e7b1675dSTing-Kang Chang ON_CALL(*private_key_manager, FipsStatus())
1414*e7b1675dSTing-Kang Chang .WillByDefault(testing::Return(FipsCompatibility::kRequiresBoringCrypto));
1415*e7b1675dSTing-Kang Chang return private_key_manager;
1416*e7b1675dSTing-Kang Chang }
1417*e7b1675dSTing-Kang Chang
1418*e7b1675dSTing-Kang Chang std::unique_ptr<TestPublicKeyTypeManager>
CreateTestPublicKeyManagerFipsCompatible()1419*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible() {
1420*e7b1675dSTing-Kang Chang auto public_key_manager = absl::make_unique<TestPublicKeyTypeManager>();
1421*e7b1675dSTing-Kang Chang ON_CALL(*public_key_manager, FipsStatus())
1422*e7b1675dSTing-Kang Chang .WillByDefault(testing::Return(FipsCompatibility::kRequiresBoringCrypto));
1423*e7b1675dSTing-Kang Chang return public_key_manager;
1424*e7b1675dSTing-Kang Chang }
1425*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterAsymmetricKeyManagers)1426*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterAsymmetricKeyManagers) {
1427*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1428*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1429*e7b1675dSTing-Kang Chang "not available";
1430*e7b1675dSTing-Kang Chang }
1431*e7b1675dSTing-Kang Chang
1432*e7b1675dSTing-Kang Chang crypto::tink::util::Status status = Registry::RegisterAsymmetricKeyManagers(
1433*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1434*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true);
1435*e7b1675dSTing-Kang Chang ASSERT_TRUE(status.ok()) << status;
1436*e7b1675dSTing-Kang Chang }
1437*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,AsymmetricMoreRestrictiveNewKey)1438*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, AsymmetricMoreRestrictiveNewKey) {
1439*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1440*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1441*e7b1675dSTing-Kang Chang "not available";
1442*e7b1675dSTing-Kang Chang }
1443*e7b1675dSTing-Kang Chang
1444*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1445*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1446*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1447*e7b1675dSTing-Kang Chang .ok());
1448*e7b1675dSTing-Kang Chang
1449*e7b1675dSTing-Kang Chang crypto::tink::util::Status status = Registry::RegisterAsymmetricKeyManagers(
1450*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1451*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), false);
1452*e7b1675dSTing-Kang Chang ASSERT_TRUE(status.ok()) << status;
1453*e7b1675dSTing-Kang Chang }
1454*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,AsymmetricSameNewKey)1455*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, AsymmetricSameNewKey) {
1456*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1457*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1458*e7b1675dSTing-Kang Chang "not available";
1459*e7b1675dSTing-Kang Chang }
1460*e7b1675dSTing-Kang Chang
1461*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1462*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1463*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1464*e7b1675dSTing-Kang Chang .ok());
1465*e7b1675dSTing-Kang Chang crypto::tink::util::Status status = Registry::RegisterAsymmetricKeyManagers(
1466*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1467*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true);
1468*e7b1675dSTing-Kang Chang ASSERT_TRUE(status.ok()) << status;
1469*e7b1675dSTing-Kang Chang
1470*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1471*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1472*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), false)
1473*e7b1675dSTing-Kang Chang .ok());
1474*e7b1675dSTing-Kang Chang status = Registry::RegisterAsymmetricKeyManagers(
1475*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1476*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), false);
1477*e7b1675dSTing-Kang Chang ASSERT_TRUE(status.ok()) << status;
1478*e7b1675dSTing-Kang Chang }
1479*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,AsymmetricLessRestrictiveGivesError)1480*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, AsymmetricLessRestrictiveGivesError) {
1481*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1482*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1483*e7b1675dSTing-Kang Chang "not available";
1484*e7b1675dSTing-Kang Chang }
1485*e7b1675dSTing-Kang Chang
1486*e7b1675dSTing-Kang Chang crypto::tink::util::Status status = Registry::RegisterAsymmetricKeyManagers(
1487*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1488*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), false);
1489*e7b1675dSTing-Kang Chang ASSERT_TRUE(status.ok()) << status;
1490*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterAsymmetricKeyManagers(
1491*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1492*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true),
1493*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kAlreadyExists,
1494*e7b1675dSTing-Kang Chang HasSubstr("forbidden new key operation")));
1495*e7b1675dSTing-Kang Chang }
1496*e7b1675dSTing-Kang Chang
1497*e7b1675dSTing-Kang Chang // Tests that if we register asymmetric key managers once more after a call to
1498*e7b1675dSTing-Kang Chang // get_key_manager, the key manager previously obtained with "get_key_manager()"
1499*e7b1675dSTing-Kang Chang // remains valid.
1500*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterAsymmetricKeyManagersGetKeyManagerStaysValid)1501*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterAsymmetricKeyManagersGetKeyManagerStaysValid) {
1502*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1503*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1504*e7b1675dSTing-Kang Chang "not available";
1505*e7b1675dSTing-Kang Chang }
1506*e7b1675dSTing-Kang Chang
1507*e7b1675dSTing-Kang Chang ASSERT_THAT(Registry::RegisterAsymmetricKeyManagers(
1508*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1509*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true),
1510*e7b1675dSTing-Kang Chang IsOk());
1511*e7b1675dSTing-Kang Chang
1512*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<const KeyManager<PrivatePrimitiveA>*>
1513*e7b1675dSTing-Kang Chang private_key_manager = Registry::get_key_manager<PrivatePrimitiveA>(
1514*e7b1675dSTing-Kang Chang TestPrivateKeyTypeManager().get_key_type());
1515*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<const KeyManager<PublicPrimitiveA>*>
1516*e7b1675dSTing-Kang Chang public_key_manager = Registry::get_key_manager<PublicPrimitiveA>(
1517*e7b1675dSTing-Kang Chang TestPublicKeyTypeManager().get_key_type());
1518*e7b1675dSTing-Kang Chang
1519*e7b1675dSTing-Kang Chang ASSERT_THAT(Registry::RegisterAsymmetricKeyManagers(
1520*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1521*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true),
1522*e7b1675dSTing-Kang Chang IsOk());
1523*e7b1675dSTing-Kang Chang
1524*e7b1675dSTing-Kang Chang EXPECT_THAT(private_key_manager.value()->get_key_type(),
1525*e7b1675dSTing-Kang Chang Eq(TestPrivateKeyTypeManager().get_key_type()));
1526*e7b1675dSTing-Kang Chang EXPECT_THAT(public_key_manager.value()->get_key_type(),
1527*e7b1675dSTing-Kang Chang Eq(TestPublicKeyTypeManager().get_key_type()));
1528*e7b1675dSTing-Kang Chang }
1529*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,AsymmetricPrivateRegisterAlone)1530*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, AsymmetricPrivateRegisterAlone) {
1531*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1532*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1533*e7b1675dSTing-Kang Chang "not available";
1534*e7b1675dSTing-Kang Chang }
1535*e7b1675dSTing-Kang Chang
1536*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterKeyTypeManager(
1537*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(), true)
1538*e7b1675dSTing-Kang Chang .ok());
1539*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterKeyTypeManager(
1540*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1541*e7b1675dSTing-Kang Chang .ok());
1542*e7b1675dSTing-Kang Chang // Registering the same as asymmetric key managers must fail, because doing so
1543*e7b1675dSTing-Kang Chang // would mean we invalidate key managers previously obtained with
1544*e7b1675dSTing-Kang Chang // get_key_manager().
1545*e7b1675dSTing-Kang Chang ASSERT_FALSE(Registry::RegisterAsymmetricKeyManagers(
1546*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1547*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1548*e7b1675dSTing-Kang Chang .ok());
1549*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterKeyTypeManager(
1550*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(), true)
1551*e7b1675dSTing-Kang Chang .ok());
1552*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterKeyTypeManager(
1553*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1554*e7b1675dSTing-Kang Chang .ok());
1555*e7b1675dSTing-Kang Chang }
1556*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,AsymmetricGetPrimitiveA)1557*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, AsymmetricGetPrimitiveA) {
1558*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1559*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1560*e7b1675dSTing-Kang Chang "not available";
1561*e7b1675dSTing-Kang Chang }
1562*e7b1675dSTing-Kang Chang
1563*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1564*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1565*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1566*e7b1675dSTing-Kang Chang .ok());
1567*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<const KeyManager<PrivatePrimitiveA>*> km =
1568*e7b1675dSTing-Kang Chang Registry::get_key_manager<PrivatePrimitiveA>(
1569*e7b1675dSTing-Kang Chang TestPrivateKeyTypeManager().get_key_type());
1570*e7b1675dSTing-Kang Chang ASSERT_TRUE(km.ok()) << km.status();
1571*e7b1675dSTing-Kang Chang EXPECT_THAT(km.value()->get_key_type(),
1572*e7b1675dSTing-Kang Chang Eq(TestPrivateKeyTypeManager().get_key_type()));
1573*e7b1675dSTing-Kang Chang }
1574*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,AsymmetricGetPrimitiveB)1575*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, AsymmetricGetPrimitiveB) {
1576*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1577*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1578*e7b1675dSTing-Kang Chang "not available";
1579*e7b1675dSTing-Kang Chang }
1580*e7b1675dSTing-Kang Chang
1581*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1582*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1583*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1584*e7b1675dSTing-Kang Chang .ok());
1585*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<const KeyManager<PrivatePrimitiveB>*> km =
1586*e7b1675dSTing-Kang Chang Registry::get_key_manager<PrivatePrimitiveB>(
1587*e7b1675dSTing-Kang Chang TestPrivateKeyTypeManager().get_key_type());
1588*e7b1675dSTing-Kang Chang ASSERT_TRUE(km.ok()) << km.status();
1589*e7b1675dSTing-Kang Chang EXPECT_THAT(km.value()->get_key_type(),
1590*e7b1675dSTing-Kang Chang Eq(TestPrivateKeyTypeManager().get_key_type()));
1591*e7b1675dSTing-Kang Chang }
1592*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,AsymmetricGetPublicPrimitiveA)1593*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, AsymmetricGetPublicPrimitiveA) {
1594*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1595*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1596*e7b1675dSTing-Kang Chang "not available";
1597*e7b1675dSTing-Kang Chang }
1598*e7b1675dSTing-Kang Chang
1599*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1600*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1601*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1602*e7b1675dSTing-Kang Chang .ok());
1603*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<const KeyManager<PublicPrimitiveA>*> km =
1604*e7b1675dSTing-Kang Chang Registry::get_key_manager<PublicPrimitiveA>(
1605*e7b1675dSTing-Kang Chang TestPublicKeyTypeManager().get_key_type());
1606*e7b1675dSTing-Kang Chang ASSERT_TRUE(km.ok()) << km.status();
1607*e7b1675dSTing-Kang Chang EXPECT_THAT(km.value()->get_key_type(),
1608*e7b1675dSTing-Kang Chang Eq(TestPublicKeyTypeManager().get_key_type()));
1609*e7b1675dSTing-Kang Chang }
1610*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,AsymmetricGetPublicPrimitiveB)1611*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, AsymmetricGetPublicPrimitiveB) {
1612*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1613*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1614*e7b1675dSTing-Kang Chang "not available";
1615*e7b1675dSTing-Kang Chang }
1616*e7b1675dSTing-Kang Chang
1617*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1618*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1619*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1620*e7b1675dSTing-Kang Chang .ok());
1621*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<const KeyManager<PublicPrimitiveB>*> km =
1622*e7b1675dSTing-Kang Chang Registry::get_key_manager<PublicPrimitiveB>(
1623*e7b1675dSTing-Kang Chang TestPublicKeyTypeManager().get_key_type());
1624*e7b1675dSTing-Kang Chang ASSERT_TRUE(km.ok()) << km.status();
1625*e7b1675dSTing-Kang Chang EXPECT_THAT(km.value()->get_key_type(),
1626*e7b1675dSTing-Kang Chang Eq(TestPublicKeyTypeManager().get_key_type()));
1627*e7b1675dSTing-Kang Chang }
1628*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,AsymmetricGetWrongPrimitiveError)1629*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, AsymmetricGetWrongPrimitiveError) {
1630*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1631*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1632*e7b1675dSTing-Kang Chang "not available";
1633*e7b1675dSTing-Kang Chang }
1634*e7b1675dSTing-Kang Chang
1635*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1636*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1637*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1638*e7b1675dSTing-Kang Chang .ok());
1639*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<const KeyManager<PublicPrimitiveA>*> km =
1640*e7b1675dSTing-Kang Chang Registry::get_key_manager<PublicPrimitiveA>(
1641*e7b1675dSTing-Kang Chang TestPrivateKeyTypeManager().get_key_type());
1642*e7b1675dSTing-Kang Chang EXPECT_THAT(km.status(),
1643*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kInvalidArgument,
1644*e7b1675dSTing-Kang Chang HasSubstr("not among supported primitives")));
1645*e7b1675dSTing-Kang Chang }
1646*e7b1675dSTing-Kang Chang
1647*e7b1675dSTing-Kang Chang class PrivateKeyManagerImplTest : public testing::Test {
SetUp()1648*e7b1675dSTing-Kang Chang void SetUp() override { Registry::Reset(); }
1649*e7b1675dSTing-Kang Chang
TearDown()1650*e7b1675dSTing-Kang Chang void TearDown() override {
1651*e7b1675dSTing-Kang Chang // Reset is needed here to ensure Mock objects get deleted and do not leak.
1652*e7b1675dSTing-Kang Chang Registry::Reset();
1653*e7b1675dSTing-Kang Chang }
1654*e7b1675dSTing-Kang Chang };
1655*e7b1675dSTing-Kang Chang
TEST_F(PrivateKeyManagerImplTest,AsymmetricFactoryNewKeyFromMessage)1656*e7b1675dSTing-Kang Chang TEST_F(PrivateKeyManagerImplTest, AsymmetricFactoryNewKeyFromMessage) {
1657*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1658*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1659*e7b1675dSTing-Kang Chang "not available";
1660*e7b1675dSTing-Kang Chang }
1661*e7b1675dSTing-Kang Chang
1662*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1663*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1664*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1665*e7b1675dSTing-Kang Chang .ok());
1666*e7b1675dSTing-Kang Chang
1667*e7b1675dSTing-Kang Chang EcdsaKeyFormat key_format;
1668*e7b1675dSTing-Kang Chang key_format.mutable_params()->set_encoding(EcdsaSignatureEncoding::DER);
1669*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1670*e7b1675dSTing-Kang Chang key_template.set_type_url(TestPrivateKeyTypeManager().get_key_type());
1671*e7b1675dSTing-Kang Chang key_template.set_value(key_format.SerializeAsString());
1672*e7b1675dSTing-Kang Chang key_template.set_output_prefix_type(OutputPrefixType::TINK);
1673*e7b1675dSTing-Kang Chang std::unique_ptr<KeyData> key_data =
1674*e7b1675dSTing-Kang Chang Registry::NewKeyData(key_template).value();
1675*e7b1675dSTing-Kang Chang EXPECT_THAT(key_data->type_url(),
1676*e7b1675dSTing-Kang Chang Eq(TestPrivateKeyTypeManager().get_key_type()));
1677*e7b1675dSTing-Kang Chang EcdsaPrivateKey private_key;
1678*e7b1675dSTing-Kang Chang private_key.ParseFromString(key_data->value());
1679*e7b1675dSTing-Kang Chang EXPECT_THAT(private_key.public_key().params().encoding(),
1680*e7b1675dSTing-Kang Chang Eq(EcdsaSignatureEncoding::DER));
1681*e7b1675dSTing-Kang Chang }
1682*e7b1675dSTing-Kang Chang
TEST_F(PrivateKeyManagerImplTest,AsymmetricNewKeyDisallowed)1683*e7b1675dSTing-Kang Chang TEST_F(PrivateKeyManagerImplTest, AsymmetricNewKeyDisallowed) {
1684*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1685*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1686*e7b1675dSTing-Kang Chang "not available";
1687*e7b1675dSTing-Kang Chang }
1688*e7b1675dSTing-Kang Chang
1689*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1690*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1691*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true)
1692*e7b1675dSTing-Kang Chang .ok());
1693*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1694*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1695*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), false)
1696*e7b1675dSTing-Kang Chang .ok());
1697*e7b1675dSTing-Kang Chang
1698*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1699*e7b1675dSTing-Kang Chang key_template.set_type_url(TestPrivateKeyTypeManager().get_key_type());
1700*e7b1675dSTing-Kang Chang EXPECT_THAT(
1701*e7b1675dSTing-Kang Chang Registry::NewKeyData(key_template).status(),
1702*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("not allow")));
1703*e7b1675dSTing-Kang Chang }
1704*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,AsymmetricGetPublicKeyData)1705*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, AsymmetricGetPublicKeyData) {
1706*e7b1675dSTing-Kang Chang if (kUseOnlyFips && !IsFipsEnabledInSsl()) {
1707*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
1708*e7b1675dSTing-Kang Chang "not available";
1709*e7b1675dSTing-Kang Chang }
1710*e7b1675dSTing-Kang Chang
1711*e7b1675dSTing-Kang Chang crypto::tink::util::Status status = Registry::RegisterAsymmetricKeyManagers(
1712*e7b1675dSTing-Kang Chang CreateTestPrivateKeyManagerFipsCompatible(),
1713*e7b1675dSTing-Kang Chang CreateTestPublicKeyManagerFipsCompatible(), true);
1714*e7b1675dSTing-Kang Chang EcdsaPrivateKey private_key;
1715*e7b1675dSTing-Kang Chang private_key.mutable_public_key()->mutable_params()->set_encoding(
1716*e7b1675dSTing-Kang Chang EcdsaSignatureEncoding::DER);
1717*e7b1675dSTing-Kang Chang
1718*e7b1675dSTing-Kang Chang std::unique_ptr<KeyData> key_data =
1719*e7b1675dSTing-Kang Chang Registry::GetPublicKeyData(TestPrivateKeyTypeManager().get_key_type(),
1720*e7b1675dSTing-Kang Chang private_key.SerializeAsString())
1721*e7b1675dSTing-Kang Chang .value();
1722*e7b1675dSTing-Kang Chang ASSERT_THAT(key_data->type_url(),
1723*e7b1675dSTing-Kang Chang Eq(TestPublicKeyTypeManager().get_key_type()));
1724*e7b1675dSTing-Kang Chang EcdsaPublicKey public_key;
1725*e7b1675dSTing-Kang Chang public_key.ParseFromString(key_data->value());
1726*e7b1675dSTing-Kang Chang EXPECT_THAT(public_key.params().encoding(), Eq(EcdsaSignatureEncoding::DER));
1727*e7b1675dSTing-Kang Chang }
1728*e7b1675dSTing-Kang Chang
1729*e7b1675dSTing-Kang Chang class TestPrivateKeyTypeManager2 : public TestPrivateKeyTypeManager {};
1730*e7b1675dSTing-Kang Chang class TestPublicKeyTypeManager2 : public TestPublicKeyTypeManager {};
1731*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterAssymmetricReregistrationWithWrongClasses)1732*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterAssymmetricReregistrationWithWrongClasses) {
1733*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1734*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1735*e7b1675dSTing-Kang Chang }
1736*e7b1675dSTing-Kang Chang
1737*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1738*e7b1675dSTing-Kang Chang absl::make_unique<TestPrivateKeyTypeManager>(),
1739*e7b1675dSTing-Kang Chang absl::make_unique<TestPublicKeyTypeManager>(), true)
1740*e7b1675dSTing-Kang Chang .ok());
1741*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterAsymmetricKeyManagers(
1742*e7b1675dSTing-Kang Chang absl::make_unique<TestPrivateKeyTypeManager2>(),
1743*e7b1675dSTing-Kang Chang absl::make_unique<TestPublicKeyTypeManager>(), true),
1744*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kAlreadyExists,
1745*e7b1675dSTing-Kang Chang HasSubstr("already registered")));
1746*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterAsymmetricKeyManagers(
1747*e7b1675dSTing-Kang Chang absl::make_unique<TestPrivateKeyTypeManager>(),
1748*e7b1675dSTing-Kang Chang absl::make_unique<TestPublicKeyTypeManager2>(), true),
1749*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kAlreadyExists,
1750*e7b1675dSTing-Kang Chang HasSubstr("already registered")));
1751*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterAsymmetricKeyManagers(
1752*e7b1675dSTing-Kang Chang absl::make_unique<TestPrivateKeyTypeManager2>(),
1753*e7b1675dSTing-Kang Chang absl::make_unique<TestPublicKeyTypeManager2>(), true),
1754*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kAlreadyExists,
1755*e7b1675dSTing-Kang Chang HasSubstr("already registered")));
1756*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1757*e7b1675dSTing-Kang Chang absl::make_unique<TestPrivateKeyTypeManager2>(), true),
1758*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kAlreadyExists,
1759*e7b1675dSTing-Kang Chang HasSubstr("already registered")));
1760*e7b1675dSTing-Kang Chang EXPECT_THAT(Registry::RegisterKeyTypeManager(
1761*e7b1675dSTing-Kang Chang absl::make_unique<TestPublicKeyTypeManager2>(), true),
1762*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kAlreadyExists,
1763*e7b1675dSTing-Kang Chang HasSubstr("already registered")));
1764*e7b1675dSTing-Kang Chang }
1765*e7b1675dSTing-Kang Chang
1766*e7b1675dSTing-Kang Chang class TestPublicKeyTypeManagerWithDifferentKeyType
1767*e7b1675dSTing-Kang Chang : public TestPublicKeyTypeManager {
get_key_type() const1768*e7b1675dSTing-Kang Chang const std::string& get_key_type() const override { return kKeyType; }
1769*e7b1675dSTing-Kang Chang
1770*e7b1675dSTing-Kang Chang private:
1771*e7b1675dSTing-Kang Chang const std::string kKeyType = "bla";
1772*e7b1675dSTing-Kang Chang };
1773*e7b1675dSTing-Kang Chang
TEST_F(RegistryTest,RegisterAssymmetricReregistrationWithNewKeyType)1774*e7b1675dSTing-Kang Chang TEST_F(RegistryTest, RegisterAssymmetricReregistrationWithNewKeyType) {
1775*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1776*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1777*e7b1675dSTing-Kang Chang }
1778*e7b1675dSTing-Kang Chang
1779*e7b1675dSTing-Kang Chang ASSERT_TRUE(Registry::RegisterAsymmetricKeyManagers(
1780*e7b1675dSTing-Kang Chang absl::make_unique<TestPrivateKeyTypeManager>(),
1781*e7b1675dSTing-Kang Chang absl::make_unique<TestPublicKeyTypeManager>(), true)
1782*e7b1675dSTing-Kang Chang .ok());
1783*e7b1675dSTing-Kang Chang EXPECT_THAT(
1784*e7b1675dSTing-Kang Chang Registry::RegisterAsymmetricKeyManagers(
1785*e7b1675dSTing-Kang Chang absl::make_unique<TestPrivateKeyTypeManager>(),
1786*e7b1675dSTing-Kang Chang absl::make_unique<TestPublicKeyTypeManagerWithDifferentKeyType>(),
1787*e7b1675dSTing-Kang Chang true),
1788*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kInvalidArgument,
1789*e7b1675dSTing-Kang Chang HasSubstr("impossible to register")));
1790*e7b1675dSTing-Kang Chang }
1791*e7b1675dSTing-Kang Chang
1792*e7b1675dSTing-Kang Chang // The DelegatingKeyTypeManager calls the registry
1793*e7b1675dSTing-Kang Chang class DelegatingKeyTypeManager
1794*e7b1675dSTing-Kang Chang : public PrivateKeyTypeManager<EcdsaPrivateKey, EcdsaKeyFormat,
1795*e7b1675dSTing-Kang Chang EcdsaPublicKey, List<>> {
1796*e7b1675dSTing-Kang Chang public:
DelegatingKeyTypeManager()1797*e7b1675dSTing-Kang Chang DelegatingKeyTypeManager() : PrivateKeyTypeManager() {}
1798*e7b1675dSTing-Kang Chang
set_registry(RegistryImpl * registry)1799*e7b1675dSTing-Kang Chang void set_registry(RegistryImpl* registry) { registry_ = registry; }
1800*e7b1675dSTing-Kang Chang
key_material_type() const1801*e7b1675dSTing-Kang Chang google::crypto::tink::KeyData::KeyMaterialType key_material_type()
1802*e7b1675dSTing-Kang Chang const override {
1803*e7b1675dSTing-Kang Chang return google::crypto::tink::KeyData::SYMMETRIC;
1804*e7b1675dSTing-Kang Chang }
1805*e7b1675dSTing-Kang Chang
get_version() const1806*e7b1675dSTing-Kang Chang uint32_t get_version() const override { return kVersion; }
1807*e7b1675dSTing-Kang Chang
get_key_type() const1808*e7b1675dSTing-Kang Chang const std::string& get_key_type() const override { return kKeyType; }
1809*e7b1675dSTing-Kang Chang
ValidateKey(const EcdsaPrivateKey & key) const1810*e7b1675dSTing-Kang Chang crypto::tink::util::Status ValidateKey(
1811*e7b1675dSTing-Kang Chang const EcdsaPrivateKey& key) const override {
1812*e7b1675dSTing-Kang Chang return util::OkStatus();
1813*e7b1675dSTing-Kang Chang }
1814*e7b1675dSTing-Kang Chang
ValidateKeyFormat(const EcdsaKeyFormat & key_format) const1815*e7b1675dSTing-Kang Chang crypto::tink::util::Status ValidateKeyFormat(
1816*e7b1675dSTing-Kang Chang const EcdsaKeyFormat& key_format) const override {
1817*e7b1675dSTing-Kang Chang return util::OkStatus();
1818*e7b1675dSTing-Kang Chang }
1819*e7b1675dSTing-Kang Chang
CreateKey(const EcdsaKeyFormat & key_format) const1820*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<EcdsaPrivateKey> CreateKey(
1821*e7b1675dSTing-Kang Chang const EcdsaKeyFormat& key_format) const override {
1822*e7b1675dSTing-Kang Chang AesGcmKeyFormat format;
1823*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1824*e7b1675dSTing-Kang Chang key_template.set_type_url(
1825*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.AesGcmKey");
1826*e7b1675dSTing-Kang Chang key_template.set_value(format.SerializeAsString());
1827*e7b1675dSTing-Kang Chang auto result = registry_->NewKeyData(key_template);
1828*e7b1675dSTing-Kang Chang if (!result.ok()) return result.status();
1829*e7b1675dSTing-Kang Chang // Return a string we can check for.
1830*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kDeadlineExceeded,
1831*e7b1675dSTing-Kang Chang "CreateKey worked");
1832*e7b1675dSTing-Kang Chang }
1833*e7b1675dSTing-Kang Chang
DeriveKey(const EcdsaKeyFormat & key_format,InputStream * input_stream) const1834*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<EcdsaPrivateKey> DeriveKey(
1835*e7b1675dSTing-Kang Chang const EcdsaKeyFormat& key_format,
1836*e7b1675dSTing-Kang Chang InputStream* input_stream) const override {
1837*e7b1675dSTing-Kang Chang AesGcmKeyFormat format;
1838*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1839*e7b1675dSTing-Kang Chang key_template.set_type_url(
1840*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.AesGcmKey");
1841*e7b1675dSTing-Kang Chang key_template.set_value(format.SerializeAsString());
1842*e7b1675dSTing-Kang Chang
1843*e7b1675dSTing-Kang Chang auto result = registry_->DeriveKey(key_template, input_stream);
1844*e7b1675dSTing-Kang Chang if (!result.ok()) return result.status();
1845*e7b1675dSTing-Kang Chang // Return a string we can check for.
1846*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kDeadlineExceeded,
1847*e7b1675dSTing-Kang Chang "DeriveKey worked");
1848*e7b1675dSTing-Kang Chang }
1849*e7b1675dSTing-Kang Chang
GetPublicKey(const EcdsaPrivateKey & private_key) const1850*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<EcdsaPublicKey> GetPublicKey(
1851*e7b1675dSTing-Kang Chang const EcdsaPrivateKey& private_key) const override {
1852*e7b1675dSTing-Kang Chang AesGcmKeyFormat format;
1853*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1854*e7b1675dSTing-Kang Chang key_template.set_type_url(
1855*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.AesGcmKey");
1856*e7b1675dSTing-Kang Chang key_template.set_value(format.SerializeAsString());
1857*e7b1675dSTing-Kang Chang auto result = registry_->NewKeyData(key_template);
1858*e7b1675dSTing-Kang Chang if (!result.ok()) return result.status();
1859*e7b1675dSTing-Kang Chang // Return a string we can check for.
1860*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kDeadlineExceeded,
1861*e7b1675dSTing-Kang Chang "GetPublicKey worked");
1862*e7b1675dSTing-Kang Chang }
1863*e7b1675dSTing-Kang Chang
1864*e7b1675dSTing-Kang Chang private:
1865*e7b1675dSTing-Kang Chang RegistryImpl* registry_;
1866*e7b1675dSTing-Kang Chang
1867*e7b1675dSTing-Kang Chang static constexpr int kVersion = 0;
1868*e7b1675dSTing-Kang Chang const std::string kKeyType =
1869*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey";
1870*e7b1675dSTing-Kang Chang };
1871*e7b1675dSTing-Kang Chang
1872*e7b1675dSTing-Kang Chang class RegistryImplTest : public ::testing::Test {
1873*e7b1675dSTing-Kang Chang protected:
TearDown()1874*e7b1675dSTing-Kang Chang void TearDown() override {
1875*e7b1675dSTing-Kang Chang // Calling RestrictToFipsIfEmpty() may call SetFipsRestricted(), which
1876*e7b1675dSTing-Kang Chang // set a global variable to true. We have to reset that after the test.
1877*e7b1675dSTing-Kang Chang UnSetFipsRestricted();
1878*e7b1675dSTing-Kang Chang }
1879*e7b1675dSTing-Kang Chang };
1880*e7b1675dSTing-Kang Chang
1881*e7b1675dSTing-Kang Chang // Check that we can call the registry again from within NewKeyData
TEST_F(RegistryImplTest,CanDelegateCreateKey)1882*e7b1675dSTing-Kang Chang TEST_F(RegistryImplTest, CanDelegateCreateKey) {
1883*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1884*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1885*e7b1675dSTing-Kang Chang }
1886*e7b1675dSTing-Kang Chang
1887*e7b1675dSTing-Kang Chang RegistryImpl registry_impl;
1888*e7b1675dSTing-Kang Chang auto delegating_key_manager = absl::make_unique<DelegatingKeyTypeManager>();
1889*e7b1675dSTing-Kang Chang delegating_key_manager->set_registry(®istry_impl);
1890*e7b1675dSTing-Kang Chang auto status =
1891*e7b1675dSTing-Kang Chang registry_impl
1892*e7b1675dSTing-Kang Chang .RegisterKeyTypeManager<EcdsaPrivateKey, EcdsaKeyFormat, List<>>(
1893*e7b1675dSTing-Kang Chang std::move(delegating_key_manager), true);
1894*e7b1675dSTing-Kang Chang EXPECT_THAT(status, IsOk());
1895*e7b1675dSTing-Kang Chang status = registry_impl.RegisterKeyTypeManager<AesGcmKey, AesGcmKeyFormat,
1896*e7b1675dSTing-Kang Chang List<Aead, AeadVariant>>(
1897*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true);
1898*e7b1675dSTing-Kang Chang EXPECT_THAT(status, IsOk());
1899*e7b1675dSTing-Kang Chang
1900*e7b1675dSTing-Kang Chang EcdsaKeyFormat format;
1901*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1902*e7b1675dSTing-Kang Chang key_template.set_type_url(
1903*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey");
1904*e7b1675dSTing-Kang Chang key_template.set_value(format.SerializeAsString());
1905*e7b1675dSTing-Kang Chang EXPECT_THAT(registry_impl.NewKeyData(key_template).status(),
1906*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kDeadlineExceeded,
1907*e7b1675dSTing-Kang Chang HasSubstr("CreateKey worked")));
1908*e7b1675dSTing-Kang Chang }
1909*e7b1675dSTing-Kang Chang
1910*e7b1675dSTing-Kang Chang // Check that we can call the registry again from within NewKeyData
TEST_F(RegistryImplTest,CanDelegateDeriveKey)1911*e7b1675dSTing-Kang Chang TEST_F(RegistryImplTest, CanDelegateDeriveKey) {
1912*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1913*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1914*e7b1675dSTing-Kang Chang }
1915*e7b1675dSTing-Kang Chang
1916*e7b1675dSTing-Kang Chang RegistryImpl registry_impl;
1917*e7b1675dSTing-Kang Chang auto delegating_key_manager = absl::make_unique<DelegatingKeyTypeManager>();
1918*e7b1675dSTing-Kang Chang delegating_key_manager->set_registry(®istry_impl);
1919*e7b1675dSTing-Kang Chang auto status =
1920*e7b1675dSTing-Kang Chang registry_impl
1921*e7b1675dSTing-Kang Chang .RegisterKeyTypeManager<EcdsaPrivateKey, EcdsaKeyFormat, List<>>(
1922*e7b1675dSTing-Kang Chang std::move(delegating_key_manager), true);
1923*e7b1675dSTing-Kang Chang EXPECT_THAT(status, IsOk());
1924*e7b1675dSTing-Kang Chang status = registry_impl.RegisterKeyTypeManager<AesGcmKey, AesGcmKeyFormat,
1925*e7b1675dSTing-Kang Chang List<Aead, AeadVariant>>(
1926*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true);
1927*e7b1675dSTing-Kang Chang EXPECT_THAT(status, IsOk());
1928*e7b1675dSTing-Kang Chang
1929*e7b1675dSTing-Kang Chang EcdsaKeyFormat format;
1930*e7b1675dSTing-Kang Chang KeyTemplate key_template;
1931*e7b1675dSTing-Kang Chang key_template.set_type_url(
1932*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey");
1933*e7b1675dSTing-Kang Chang key_template.set_value(format.SerializeAsString());
1934*e7b1675dSTing-Kang Chang EXPECT_THAT(registry_impl.DeriveKey(key_template, nullptr).status(),
1935*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kDeadlineExceeded,
1936*e7b1675dSTing-Kang Chang HasSubstr("DeriveKey worked")));
1937*e7b1675dSTing-Kang Chang }
1938*e7b1675dSTing-Kang Chang
TEST_F(RegistryImplTest,CanDelegateGetPublicKey)1939*e7b1675dSTing-Kang Chang TEST_F(RegistryImplTest, CanDelegateGetPublicKey) {
1940*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1941*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1942*e7b1675dSTing-Kang Chang }
1943*e7b1675dSTing-Kang Chang
1944*e7b1675dSTing-Kang Chang RegistryImpl registry_impl;
1945*e7b1675dSTing-Kang Chang auto delegating_key_manager = absl::make_unique<DelegatingKeyTypeManager>();
1946*e7b1675dSTing-Kang Chang delegating_key_manager->set_registry(®istry_impl);
1947*e7b1675dSTing-Kang Chang auto status = registry_impl.RegisterAsymmetricKeyManagers(
1948*e7b1675dSTing-Kang Chang delegating_key_manager.release(),
1949*e7b1675dSTing-Kang Chang absl::make_unique<TestPublicKeyTypeManager>().release(), true);
1950*e7b1675dSTing-Kang Chang EXPECT_THAT(status, IsOk());
1951*e7b1675dSTing-Kang Chang status = registry_impl.RegisterKeyTypeManager<AesGcmKey, AesGcmKeyFormat,
1952*e7b1675dSTing-Kang Chang List<Aead, AeadVariant>>(
1953*e7b1675dSTing-Kang Chang absl::make_unique<ExampleKeyTypeManager>(), true);
1954*e7b1675dSTing-Kang Chang EXPECT_THAT(status, IsOk());
1955*e7b1675dSTing-Kang Chang
1956*e7b1675dSTing-Kang Chang EcdsaPrivateKey private_key;
1957*e7b1675dSTing-Kang Chang private_key.mutable_public_key()->mutable_params()->set_encoding(
1958*e7b1675dSTing-Kang Chang EcdsaSignatureEncoding::DER);
1959*e7b1675dSTing-Kang Chang
1960*e7b1675dSTing-Kang Chang EXPECT_THAT(registry_impl
1961*e7b1675dSTing-Kang Chang .GetPublicKeyData(DelegatingKeyTypeManager().get_key_type(),
1962*e7b1675dSTing-Kang Chang private_key.SerializeAsString())
1963*e7b1675dSTing-Kang Chang .status(),
1964*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kDeadlineExceeded,
1965*e7b1675dSTing-Kang Chang HasSubstr("GetPublicKey worked")));
1966*e7b1675dSTing-Kang Chang }
1967*e7b1675dSTing-Kang Chang
TEST_F(RegistryImplTest,FipsRestrictionSucceedsOnEmptyRegistry)1968*e7b1675dSTing-Kang Chang TEST_F(RegistryImplTest, FipsRestrictionSucceedsOnEmptyRegistry) {
1969*e7b1675dSTing-Kang Chang RegistryImpl registry_impl;
1970*e7b1675dSTing-Kang Chang EXPECT_THAT(registry_impl.RestrictToFipsIfEmpty(), IsOk());
1971*e7b1675dSTing-Kang Chang }
1972*e7b1675dSTing-Kang Chang
TEST_F(RegistryImplTest,FipsRestrictionSucceedsWhenSettingMultipleTimes)1973*e7b1675dSTing-Kang Chang TEST_F(RegistryImplTest, FipsRestrictionSucceedsWhenSettingMultipleTimes) {
1974*e7b1675dSTing-Kang Chang RegistryImpl registry_impl;
1975*e7b1675dSTing-Kang Chang EXPECT_THAT(registry_impl.RestrictToFipsIfEmpty(), IsOk());
1976*e7b1675dSTing-Kang Chang EXPECT_THAT(registry_impl.RestrictToFipsIfEmpty(), IsOk());
1977*e7b1675dSTing-Kang Chang EXPECT_THAT(registry_impl.RestrictToFipsIfEmpty(), IsOk());
1978*e7b1675dSTing-Kang Chang }
1979*e7b1675dSTing-Kang Chang
TEST_F(RegistryImplTest,FipsRestrictionSucceedsIfBuildInFipsMode)1980*e7b1675dSTing-Kang Chang TEST_F(RegistryImplTest, FipsRestrictionSucceedsIfBuildInFipsMode) {
1981*e7b1675dSTing-Kang Chang if (!kUseOnlyFips) {
1982*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported when Tink is not built in FIPS mode.";
1983*e7b1675dSTing-Kang Chang }
1984*e7b1675dSTing-Kang Chang RegistryImpl registry_impl;
1985*e7b1675dSTing-Kang Chang EXPECT_THAT(registry_impl.RestrictToFipsIfEmpty(), IsOk());
1986*e7b1675dSTing-Kang Chang }
1987*e7b1675dSTing-Kang Chang
TEST_F(RegistryImplTest,FipsFailsIfNotEmpty)1988*e7b1675dSTing-Kang Chang TEST_F(RegistryImplTest, FipsFailsIfNotEmpty) {
1989*e7b1675dSTing-Kang Chang if (kUseOnlyFips) {
1990*e7b1675dSTing-Kang Chang GTEST_SKIP() << "Not supported in FIPS-only mode";
1991*e7b1675dSTing-Kang Chang }
1992*e7b1675dSTing-Kang Chang
1993*e7b1675dSTing-Kang Chang auto fips_key_manager = absl::make_unique<ExampleKeyTypeManager>();
1994*e7b1675dSTing-Kang Chang ON_CALL(*fips_key_manager, FipsStatus())
1995*e7b1675dSTing-Kang Chang .WillByDefault(testing::Return(FipsCompatibility::kRequiresBoringCrypto));
1996*e7b1675dSTing-Kang Chang
1997*e7b1675dSTing-Kang Chang RegistryImpl registry_impl;
1998*e7b1675dSTing-Kang Chang auto status = registry_impl.RegisterKeyTypeManager<AesGcmKey, AesGcmKeyFormat,
1999*e7b1675dSTing-Kang Chang List<Aead, AeadVariant>>(
2000*e7b1675dSTing-Kang Chang std::move(fips_key_manager), true);
2001*e7b1675dSTing-Kang Chang EXPECT_THAT(status, IsOk());
2002*e7b1675dSTing-Kang Chang EXPECT_THAT(registry_impl.RestrictToFipsIfEmpty(),
2003*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kInternal));
2004*e7b1675dSTing-Kang Chang }
2005*e7b1675dSTing-Kang Chang
TEST_F(RegistryImplTest,CanRegisterOnlyOneMonitoringFactory)2006*e7b1675dSTing-Kang Chang TEST_F(RegistryImplTest, CanRegisterOnlyOneMonitoringFactory) {
2007*e7b1675dSTing-Kang Chang auto monitoring_client_factory =
2008*e7b1675dSTing-Kang Chang absl::make_unique<MockMonitoringClientFactory>();
2009*e7b1675dSTing-Kang Chang
2010*e7b1675dSTing-Kang Chang RegistryImpl registry_impl;
2011*e7b1675dSTing-Kang Chang EXPECT_THAT(registry_impl.RegisterMonitoringClientFactory(
2012*e7b1675dSTing-Kang Chang std::move(monitoring_client_factory)),
2013*e7b1675dSTing-Kang Chang IsOk());
2014*e7b1675dSTing-Kang Chang ASSERT_THAT(registry_impl.GetMonitoringClientFactory(), Not(IsNull()));
2015*e7b1675dSTing-Kang Chang EXPECT_THAT(registry_impl.RegisterMonitoringClientFactory(
2016*e7b1675dSTing-Kang Chang std::move(monitoring_client_factory)),
2017*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kAlreadyExists));
2018*e7b1675dSTing-Kang Chang }
2019*e7b1675dSTing-Kang Chang
2020*e7b1675dSTing-Kang Chang } // namespace
2021*e7b1675dSTing-Kang Chang } // namespace internal
2022*e7b1675dSTing-Kang Chang } // namespace tink
2023*e7b1675dSTing-Kang Chang } // namespace crypto
2024