1 // Copyright 2021 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/util/secret_proto.h"
18
19 #include <string>
20 #include <utility>
21
22 #include "google/protobuf/util/message_differencer.h"
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "absl/memory/memory.h"
26 #include "proto/test_proto.pb.h"
27
28 namespace crypto {
29 namespace tink {
30 namespace util {
31 namespace {
32
33 using ::google::crypto::tink::NestedTestProto;
34 using ::google::crypto::tink::TestProto;
35 using ::google::protobuf::util::MessageDifferencer;
36
37 template <typename T>
38 class SecretProtoTest : public testing::Test {};
39
40 using MyTypes = ::testing::Types<NestedTestProto, TestProto>;
41 TYPED_TEST_SUITE(SecretProtoTest, MyTypes);
42
43 template <typename T>
44 T CreateProto();
45
46 template <>
CreateProto()47 TestProto CreateProto<TestProto>() {
48 TestProto proto;
49 proto.set_num(123);
50 proto.set_str("Single proto");
51 return proto;
52 }
53
54 template <>
CreateProto()55 NestedTestProto CreateProto<NestedTestProto>() {
56 NestedTestProto proto;
57 proto.mutable_a()->set_num(12);
58 proto.mutable_a()->set_str("A proto");
59 proto.mutable_b()->set_num(14);
60 proto.mutable_b()->set_str("B proto");
61 proto.set_num(42);
62 proto.set_str("Main proto");
63 return proto;
64 }
65
TYPED_TEST(SecretProtoTest,DefaultConstructor)66 TYPED_TEST(SecretProtoTest, DefaultConstructor) {
67 SecretProto<TypeParam> s;
68 EXPECT_TRUE(MessageDifferencer::Equals(*s, TypeParam()));
69 }
70
TYPED_TEST(SecretProtoTest,Constructor)71 TYPED_TEST(SecretProtoTest, Constructor) {
72 TypeParam proto = CreateProto<TypeParam>();
73 SecretProto<TypeParam> s(proto);
74 EXPECT_TRUE(MessageDifferencer::Equals(*s, proto));
75 }
76
TYPED_TEST(SecretProtoTest,CopyConstructor)77 TYPED_TEST(SecretProtoTest, CopyConstructor) {
78 TypeParam proto = CreateProto<TypeParam>();
79 SecretProto<TypeParam> s(proto);
80 SecretProto<TypeParam> t(s);
81 EXPECT_TRUE(MessageDifferencer::Equals(*s, proto));
82 EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
83 }
84
TYPED_TEST(SecretProtoTest,SourceDestroyedAfterCopyConstructor)85 TYPED_TEST(SecretProtoTest, SourceDestroyedAfterCopyConstructor) {
86 TypeParam proto = CreateProto<TypeParam>();
87 auto s = absl::make_unique<SecretProto<TypeParam>>(proto);
88 SecretProto<TypeParam> t(*s);
89 EXPECT_TRUE(MessageDifferencer::Equals(**s, proto));
90 EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
91 // Test with source destroyed after the copy
92 s.reset();
93 EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
94 }
95
TYPED_TEST(SecretProtoTest,AssignmentOperator)96 TYPED_TEST(SecretProtoTest, AssignmentOperator) {
97 TypeParam proto = CreateProto<TypeParam>();
98 SecretProto<TypeParam> t;
99 {
100 SecretProto<TypeParam> s(proto);
101 t = s;
102 EXPECT_TRUE(MessageDifferencer::Equals(*s, proto));
103 EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
104 }
105 // Test with source destroyed after the copy
106 EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
107 }
108
TYPED_TEST(SecretProtoTest,MoveConstructor)109 TYPED_TEST(SecretProtoTest, MoveConstructor) {
110 TypeParam proto = CreateProto<TypeParam>();
111 SecretProto<TypeParam> s(proto);
112 SecretProto<TypeParam> t(std::move(s));
113 EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
114 // NOLINTNEXTLINE: bugprone-use-after-move
115 EXPECT_TRUE(MessageDifferencer::Equals(*s, TypeParam()) ||
116 MessageDifferencer::Equals(*s, proto));
117 }
118
TYPED_TEST(SecretProtoTest,MoveAssignment)119 TYPED_TEST(SecretProtoTest, MoveAssignment) {
120 TypeParam proto = CreateProto<TypeParam>();
121 SecretProto<TypeParam> t;
122 {
123 SecretProto<TypeParam> s(proto);
124 t = std::move(s);
125 EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
126 // NOLINTNEXTLINE: bugprone-use-after-move
127 EXPECT_TRUE(MessageDifferencer::Equals(*s, TypeParam()) ||
128 MessageDifferencer::Equals(*s, proto));
129 }
130 // Test with source destroyed after the move
131 EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
132 }
133
TYPED_TEST(SecretProtoTest,FromSecretData)134 TYPED_TEST(SecretProtoTest, FromSecretData) {
135 TypeParam proto = CreateProto<TypeParam>();
136 SecretData data;
137 data.resize(proto.ByteSizeLong());
138 ASSERT_TRUE(proto.SerializeToArray(data.data(), data.size()));
139 StatusOr<SecretProto<TypeParam>> secret_proto =
140 SecretProto<TypeParam>::ParseFromSecretData(data);
141 ASSERT_TRUE(secret_proto.ok()) << secret_proto.status();
142 EXPECT_TRUE(MessageDifferencer::Equals(**secret_proto, proto));
143 }
144
TYPED_TEST(SecretProtoTest,AsSecretData)145 TYPED_TEST(SecretProtoTest, AsSecretData) {
146 TypeParam proto = CreateProto<TypeParam>();
147 std::string serialized = proto.SerializeAsString();
148 SecretProto<TypeParam> secret_proto(proto);
149 StatusOr<SecretData> secret_serialized = secret_proto.SerializeAsSecretData();
150 ASSERT_TRUE(secret_serialized.ok()) << secret_serialized.status();
151 EXPECT_EQ(serialized, SecretDataAsStringView(*secret_serialized));
152 }
153
154 } // namespace
155 } // namespace util
156 } // namespace tink
157 } // namespace crypto
158