1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16
17 #include "tink/config/global_registry.h"
18
19 #include <memory>
20 #include <string>
21
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "absl/status/status.h"
25 #include "tink/keyset_handle.h"
26 #include "tink/util/test_matchers.h"
27 #include "proto/aes_gcm.pb.h"
28 #include "proto/tink.pb.h"
29
30 namespace crypto {
31 namespace tink {
32 namespace {
33
34 using ::crypto::tink::test::IsOk;
35 using ::crypto::tink::test::StatusIs;
36 using ::google::crypto::tink::AesGcmKey;
37 using ::google::crypto::tink::AesGcmKeyFormat;
38 using ::google::crypto::tink::KeyData;
39 using ::google::crypto::tink::KeyTemplate;
40 using ::google::crypto::tink::OutputPrefixType;
41
42 class FakePrimitive {
43 public:
FakePrimitive(std::string s)44 explicit FakePrimitive(std::string s) : s_(s) {}
get()45 std::string get() { return s_; }
46
47 private:
48 std::string s_;
49 };
50
51 class FakeKeyTypeManager
52 : public KeyTypeManager<AesGcmKey, AesGcmKeyFormat, List<FakePrimitive>> {
53 public:
54 class FakePrimitiveFactory : public PrimitiveFactory<FakePrimitive> {
55 public:
Create(const AesGcmKey & key) const56 util::StatusOr<std::unique_ptr<FakePrimitive>> Create(
57 const AesGcmKey& key) const override {
58 return absl::make_unique<FakePrimitive>(key.key_value());
59 }
60 };
61
FakeKeyTypeManager()62 FakeKeyTypeManager()
63 : KeyTypeManager(absl::make_unique<FakePrimitiveFactory>()) {}
64
key_material_type() const65 KeyData::KeyMaterialType key_material_type() const override {
66 return KeyData::SYMMETRIC;
67 }
68
get_version() const69 uint32_t get_version() const override { return 0; }
70
get_key_type() const71 const std::string& get_key_type() const override { return key_type_; }
72
ValidateKey(const AesGcmKey & key) const73 util::Status ValidateKey(const AesGcmKey& key) const override {
74 return util::OkStatus();
75 }
76
ValidateKeyFormat(const AesGcmKeyFormat & key_format) const77 util::Status ValidateKeyFormat(
78 const AesGcmKeyFormat& key_format) const override {
79 return util::OkStatus();
80 }
81
CreateKey(const AesGcmKeyFormat & key_format) const82 util::StatusOr<AesGcmKey> CreateKey(
83 const AesGcmKeyFormat& key_format) const override {
84 return AesGcmKey();
85 }
86
DeriveKey(const AesGcmKeyFormat & key_format,InputStream * input_stream) const87 util::StatusOr<AesGcmKey> DeriveKey(
88 const AesGcmKeyFormat& key_format,
89 InputStream* input_stream) const override {
90 return AesGcmKey();
91 }
92
93 private:
94 const std::string key_type_ =
95 "type.googleapis.com/google.crypto.tink.AesGcmKey";
96 };
97
98 class FakePrimitiveWrapper
99 : public PrimitiveWrapper<FakePrimitive, FakePrimitive> {
100 public:
Wrap(std::unique_ptr<PrimitiveSet<FakePrimitive>> primitive_set) const101 util::StatusOr<std::unique_ptr<FakePrimitive>> Wrap(
102 std::unique_ptr<PrimitiveSet<FakePrimitive>> primitive_set)
103 const override {
104 return absl::make_unique<FakePrimitive>(
105 primitive_set->get_primary()->get_primitive().get());
106 }
107 };
108
TEST(GlobalRegistryTest,GenerateNewKeysetHandleFromKeyGenConfig)109 TEST(GlobalRegistryTest, GenerateNewKeysetHandleFromKeyGenConfig) {
110 Registry::Reset();
111
112 KeyTemplate templ;
113 templ.set_type_url("type.googleapis.com/google.crypto.tink.AesGcmKey");
114 templ.set_output_prefix_type(OutputPrefixType::TINK);
115 EXPECT_THAT(
116 KeysetHandle::GenerateNew(templ, KeyGenConfigGlobalRegistry()).status(),
117 StatusIs(absl::StatusCode::kNotFound));
118
119 ASSERT_THAT(
120 Registry::RegisterKeyTypeManager(absl::make_unique<FakeKeyTypeManager>(),
121 /*new_key_allowed=*/true),
122 IsOk());
123
124 EXPECT_THAT(
125 KeysetHandle::GenerateNew(templ, KeyGenConfigGlobalRegistry()).status(),
126 IsOk());
127 }
128
TEST(GlobalRegistryTest,GetPrimitiveFromConfig)129 TEST(GlobalRegistryTest, GetPrimitiveFromConfig) {
130 Registry::Reset();
131 ASSERT_THAT(
132 Registry::RegisterKeyTypeManager(absl::make_unique<FakeKeyTypeManager>(),
133 /*new_key_allowed=*/true),
134 IsOk());
135
136 KeyTemplate templ;
137 templ.set_type_url("type.googleapis.com/google.crypto.tink.AesGcmKey");
138 templ.set_output_prefix_type(OutputPrefixType::TINK);
139 util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
140 KeysetHandle::GenerateNew(templ, KeyGenConfigGlobalRegistry());
141 ASSERT_THAT(handle, IsOk());
142 EXPECT_THAT(
143 (*handle)->GetPrimitive<FakePrimitive>(ConfigGlobalRegistry()).status(),
144 StatusIs(absl::StatusCode::kNotFound));
145
146 Registry::Reset();
147 ASSERT_THAT(
148 Registry::RegisterKeyTypeManager(absl::make_unique<FakeKeyTypeManager>(),
149 /*new_key_allowed=*/true),
150 IsOk());
151 ASSERT_THAT(Registry::RegisterPrimitiveWrapper(
152 absl::make_unique<FakePrimitiveWrapper>()),
153 IsOk());
154
155 EXPECT_THAT((*handle)->GetPrimitive<FakePrimitive>(ConfigGlobalRegistry()),
156 IsOk());
157 }
158
159 } // namespace
160 } // namespace tink
161 } // namespace crypto
162