1 // Copyright 2022 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/internal/proto_key_serialization.h"
18
19 #include "gmock/gmock.h"
20 #include "gtest/gtest.h"
21 #include "absl/status/status.h"
22 #include "absl/types/optional.h"
23 #include "tink/insecure_secret_key_access.h"
24 #include "tink/restricted_data.h"
25 #include "tink/util/statusor.h"
26 #include "tink/util/test_matchers.h"
27 #include "proto/tink.pb.h"
28
29 namespace crypto {
30 namespace tink {
31 namespace internal {
32
33 using ::crypto::tink::test::IsOk;
34 using ::crypto::tink::test::StatusIs;
35 using ::google::crypto::tink::KeyData;
36 using ::google::crypto::tink::OutputPrefixType;
37 using ::testing::Eq;
38 using ::testing::IsFalse;
39 using ::testing::IsTrue;
40
41 class ProtoKeySerializationTest : public ::testing::Test {
42 protected:
Equals(ProtoKeySerialization serialization,ProtoKeySerialization other)43 bool Equals(ProtoKeySerialization serialization,
44 ProtoKeySerialization other) {
45 return serialization.EqualsWithPotentialFalseNegatives(other);
46 }
47 };
48
TEST_F(ProtoKeySerializationTest,CreateWithIdRequirement)49 TEST_F(ProtoKeySerializationTest, CreateWithIdRequirement) {
50 RestrictedData serialized_key =
51 RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
52 util::StatusOr<ProtoKeySerialization> serialization =
53 ProtoKeySerialization::Create("type_url", serialized_key,
54 KeyData::SYMMETRIC, OutputPrefixType::TINK,
55 /*id_requirement=*/12345);
56 ASSERT_THAT(serialization.status(), IsOk());
57
58 EXPECT_THAT(serialization->TypeUrl(), Eq("type_url"));
59 EXPECT_THAT(serialization->SerializedKeyProto(), Eq(serialized_key));
60 EXPECT_THAT(serialization->KeyMaterialType(), Eq(KeyData::SYMMETRIC));
61 EXPECT_THAT(serialization->GetOutputPrefixType(), Eq(OutputPrefixType::TINK));
62 EXPECT_THAT(serialization->IdRequirement(), Eq(12345));
63 EXPECT_THAT(serialization->ObjectIdentifier(), Eq("type_url"));
64 }
65
TEST_F(ProtoKeySerializationTest,CreateWithoutIdRequirement)66 TEST_F(ProtoKeySerializationTest, CreateWithoutIdRequirement) {
67 RestrictedData serialized_key =
68 RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
69 util::StatusOr<ProtoKeySerialization> serialization =
70 ProtoKeySerialization::Create("type_url", serialized_key,
71 KeyData::SYMMETRIC, OutputPrefixType::RAW,
72 /*id_requirement=*/absl::nullopt);
73 ASSERT_THAT(serialization.status(), IsOk());
74
75 EXPECT_THAT(serialization->TypeUrl(), Eq("type_url"));
76 EXPECT_THAT(serialization->SerializedKeyProto(), Eq(serialized_key));
77 EXPECT_THAT(serialization->KeyMaterialType(), Eq(KeyData::SYMMETRIC));
78 EXPECT_THAT(serialization->GetOutputPrefixType(), Eq(OutputPrefixType::RAW));
79 EXPECT_THAT(serialization->IdRequirement(), Eq(absl::nullopt));
80 EXPECT_THAT(serialization->ObjectIdentifier(), Eq("type_url"));
81 }
82
TEST_F(ProtoKeySerializationTest,OutputPrefixIncompatibleWithIdRequirement)83 TEST_F(ProtoKeySerializationTest, OutputPrefixIncompatibleWithIdRequirement) {
84 RestrictedData serialized_key =
85 RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
86 util::StatusOr<ProtoKeySerialization> tink_without_id =
87 ProtoKeySerialization::Create("type_url", serialized_key,
88 KeyData::SYMMETRIC, OutputPrefixType::TINK,
89 /*id_requirement=*/absl::nullopt);
90 ASSERT_THAT(tink_without_id.status(),
91 StatusIs(absl::StatusCode::kInvalidArgument));
92
93 util::StatusOr<ProtoKeySerialization> raw_with_id =
94 ProtoKeySerialization::Create("type_url", serialized_key,
95 KeyData::SYMMETRIC, OutputPrefixType::RAW,
96 /*id_requirement=*/12345);
97 ASSERT_THAT(raw_with_id.status(),
98 StatusIs(absl::StatusCode::kInvalidArgument));
99 }
100
TEST_F(ProtoKeySerializationTest,Equals)101 TEST_F(ProtoKeySerializationTest, Equals) {
102 RestrictedData serialized_key =
103 RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
104 util::StatusOr<ProtoKeySerialization> serialization =
105 ProtoKeySerialization::Create("type_url", serialized_key,
106 KeyData::SYMMETRIC, OutputPrefixType::TINK,
107 /*id_requirement=*/12345);
108 ASSERT_THAT(serialization.status(), IsOk());
109
110 util::StatusOr<ProtoKeySerialization> other_serialization =
111 ProtoKeySerialization::Create("type_url", serialized_key,
112 KeyData::SYMMETRIC, OutputPrefixType::TINK,
113 /*id_requirement=*/12345);
114 ASSERT_THAT(other_serialization.status(), IsOk());
115
116 EXPECT_THAT(Equals(*serialization, *other_serialization), IsTrue());
117 }
118
TEST_F(ProtoKeySerializationTest,TypeUrlAndObjectIdentifierNotEqual)119 TEST_F(ProtoKeySerializationTest, TypeUrlAndObjectIdentifierNotEqual) {
120 RestrictedData serialized_key =
121 RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
122 util::StatusOr<ProtoKeySerialization> serialization =
123 ProtoKeySerialization::Create("type_url", serialized_key,
124 KeyData::SYMMETRIC, OutputPrefixType::TINK,
125 /*id_requirement=*/12345);
126 ASSERT_THAT(serialization.status(), IsOk());
127
128 util::StatusOr<ProtoKeySerialization> other_serialization =
129 ProtoKeySerialization::Create("different_url", serialized_key,
130 KeyData::SYMMETRIC, OutputPrefixType::TINK,
131 /*id_requirement=*/12345);
132 ASSERT_THAT(other_serialization.status(), IsOk());
133
134 EXPECT_THAT(Equals(*serialization, *other_serialization), IsFalse());
135 }
136
TEST_F(ProtoKeySerializationTest,SerializedKeyNotEqual)137 TEST_F(ProtoKeySerializationTest, SerializedKeyNotEqual) {
138 util::StatusOr<ProtoKeySerialization> serialization =
139 ProtoKeySerialization::Create(
140 "type_url",
141 RestrictedData("serialized_key", InsecureSecretKeyAccess::Get()),
142 KeyData::SYMMETRIC, OutputPrefixType::TINK,
143 /*id_requirement=*/12345);
144 ASSERT_THAT(serialization.status(), IsOk());
145
146 util::StatusOr<ProtoKeySerialization> other_serialization =
147 ProtoKeySerialization::Create(
148 "type_url",
149 RestrictedData("different_key", InsecureSecretKeyAccess::Get()),
150 KeyData::SYMMETRIC, OutputPrefixType::TINK,
151 /*id_requirement=*/12345);
152 ASSERT_THAT(other_serialization.status(), IsOk());
153
154 EXPECT_THAT(Equals(*serialization, *other_serialization), IsFalse());
155 }
156
TEST_F(ProtoKeySerializationTest,KeyMaterialTypeNotEqual)157 TEST_F(ProtoKeySerializationTest, KeyMaterialTypeNotEqual) {
158 RestrictedData serialized_key =
159 RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
160 util::StatusOr<ProtoKeySerialization> serialization =
161 ProtoKeySerialization::Create("type_url", serialized_key,
162 KeyData::SYMMETRIC, OutputPrefixType::TINK,
163 /*id_requirement=*/12345);
164 ASSERT_THAT(serialization.status(), IsOk());
165
166 util::StatusOr<ProtoKeySerialization> other_serialization =
167 ProtoKeySerialization::Create("type_url", serialized_key, KeyData::REMOTE,
168 OutputPrefixType::TINK,
169 /*id_requirement=*/12345);
170 ASSERT_THAT(other_serialization.status(), IsOk());
171
172 EXPECT_THAT(Equals(*serialization, *other_serialization), IsFalse());
173 }
174
TEST_F(ProtoKeySerializationTest,OutputPrefixTypeNotEqual)175 TEST_F(ProtoKeySerializationTest, OutputPrefixTypeNotEqual) {
176 RestrictedData serialized_key =
177 RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
178 util::StatusOr<ProtoKeySerialization> serialization =
179 ProtoKeySerialization::Create("type_url", serialized_key,
180 KeyData::SYMMETRIC, OutputPrefixType::TINK,
181 /*id_requirement=*/12345);
182 ASSERT_THAT(serialization.status(), IsOk());
183
184 util::StatusOr<ProtoKeySerialization> other_serialization =
185 ProtoKeySerialization::Create("type_url", serialized_key,
186 KeyData::SYMMETRIC,
187 OutputPrefixType::CRUNCHY,
188 /*id_requirement=*/12345);
189
190 EXPECT_THAT(Equals(*serialization, *other_serialization), IsFalse());
191 }
192
TEST_F(ProtoKeySerializationTest,IdRequirementNotEqual)193 TEST_F(ProtoKeySerializationTest, IdRequirementNotEqual) {
194 RestrictedData serialized_key =
195 RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
196 util::StatusOr<ProtoKeySerialization> serialization =
197 ProtoKeySerialization::Create("type_url", serialized_key,
198 KeyData::SYMMETRIC, OutputPrefixType::TINK,
199 /*id_requirement=*/12345);
200 ASSERT_THAT(serialization.status(), IsOk());
201
202 util::StatusOr<ProtoKeySerialization> other_serialization =
203 ProtoKeySerialization::Create("type_url", serialized_key,
204 KeyData::SYMMETRIC, OutputPrefixType::TINK,
205 /*id_requirement=*/6789);
206 ASSERT_THAT(other_serialization.status(), IsOk());
207
208 EXPECT_THAT(Equals(*serialization, *other_serialization), IsFalse());
209 }
210
211 } // namespace internal
212 } // namespace tink
213 } // namespace crypto
214