1 // Copyright 2019 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/input_stream_util.h"
18
19 #include <sstream>
20 #include <string>
21 #include <utility>
22
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "absl/memory/memory.h"
26 #include "tink/util/istream_input_stream.h"
27 #include "tink/util/secret_data.h"
28 #include "tink/util/status.h"
29 #include "tink/util/test_matchers.h"
30
31 namespace crypto {
32 namespace tink {
33
34 namespace {
35
36 using ::crypto::tink::test::IsOk;
37 using ::crypto::tink::test::StatusIs;
38 using ::crypto::tink::util::IstreamInputStream;
39 using ::testing::Eq;
40
TEST(ReadBytesTest,ReadExact)41 TEST(ReadBytesTest, ReadExact) {
42 const std::string content = "Some content";
43 IstreamInputStream input_stream{
44 absl::make_unique<std::stringstream>(content)};
45 auto text_or = ReadBytesFromStream(content.size(), &input_stream);
46 ASSERT_THAT(text_or, IsOk());
47 std::string text = std::move(text_or).value();
48 EXPECT_THAT(text, Eq(content));
49 }
50
TEST(ReadBytesTest,ShortRead)51 TEST(ReadBytesTest, ShortRead) {
52 IstreamInputStream input_stream{
53 absl::make_unique<std::stringstream>("Some content")};
54 auto text_or = ReadBytesFromStream(100, &input_stream);
55 EXPECT_THAT(text_or.status(), StatusIs(absl::StatusCode::kOutOfRange));
56 }
57
TEST(ReadBytesTest,ReadLess)58 TEST(ReadBytesTest, ReadLess) {
59 IstreamInputStream input_stream{
60 absl::make_unique<std::stringstream>("0123456789abcdefghijklmnop")};
61 auto text_or = ReadBytesFromStream(7, &input_stream);
62 ASSERT_THAT(text_or, IsOk());
63 EXPECT_THAT(text_or.value(), Eq("0123456"));
64 }
65
TEST(ReadBytesTest,ReadTwice)66 TEST(ReadBytesTest, ReadTwice) {
67 IstreamInputStream input_stream{
68 absl::make_unique<std::stringstream>("0123456789abcdefghijklmnop")};
69 auto text_or = ReadBytesFromStream(7, &input_stream);
70 ASSERT_THAT(text_or, IsOk());
71 EXPECT_THAT(text_or.value(), Eq("0123456"));
72
73 text_or = ReadBytesFromStream(5, &input_stream);
74 ASSERT_THAT(text_or, IsOk());
75 EXPECT_THAT(text_or.value(), Eq("789ab"));
76 }
77
TEST(ReadBytesTest,ReadMoreThanBlockSize)78 TEST(ReadBytesTest, ReadMoreThanBlockSize) {
79 // Use a block size of 4 such that ReadAtMost has to call the input multiple
80 // times.
81 IstreamInputStream input_stream{
82 absl::make_unique<std::stringstream>("0123456789abcdefghijklmnop"), 4};
83 auto text_or = ReadBytesFromStream(11, &input_stream);
84 ASSERT_THAT(text_or, IsOk());
85 EXPECT_THAT(text_or.value(), Eq("0123456789a"));
86
87 text_or = ReadBytesFromStream(5, &input_stream);
88 ASSERT_THAT(text_or, IsOk());
89 EXPECT_THAT(text_or.value(), Eq("bcdef"));
90 }
91
TEST(ReadBytesTest,Request0)92 TEST(ReadBytesTest, Request0) {
93 IstreamInputStream input_stream(
94 absl::make_unique<std::stringstream>("012345678"));
95 auto text_or = ReadBytesFromStream(4, &input_stream);
96 ASSERT_THAT(text_or, IsOk());
97 EXPECT_THAT(text_or.value(), Eq("0123"));
98 text_or = ReadBytesFromStream(0, &input_stream);
99 ASSERT_THAT(text_or, IsOk());
100 EXPECT_THAT(text_or.value(), Eq(""));
101 text_or = ReadBytesFromStream(5, &input_stream);
102 ASSERT_THAT(text_or, IsOk());
103 EXPECT_THAT(text_or.value(), Eq("45678"));
104 text_or = ReadBytesFromStream(0, &input_stream);
105 ASSERT_THAT(text_or, IsOk());
106 EXPECT_THAT(text_or.value(), Eq(""));
107 }
108
TEST(ReadBytesTest,RequestNegative)109 TEST(ReadBytesTest, RequestNegative) {
110 IstreamInputStream input_stream(
111 absl::make_unique<std::stringstream>("012345678"));
112 auto text_or = ReadBytesFromStream(-1, &input_stream);
113 ASSERT_THAT(text_or, IsOk());
114 EXPECT_THAT(text_or.value(), Eq(""));
115 }
116
TEST(ReadBytesTest,EmptyInput)117 TEST(ReadBytesTest, EmptyInput) {
118 IstreamInputStream input_stream(absl::make_unique<std::stringstream>(""));
119 auto text_or = ReadBytesFromStream(0, &input_stream);
120 ASSERT_THAT(text_or, IsOk());
121 EXPECT_THAT(text_or.value(), Eq(""));
122 text_or = ReadBytesFromStream(1, &input_stream);
123 EXPECT_THAT(text_or.status(), StatusIs(absl::StatusCode::kOutOfRange));
124 }
125
TEST(ReadSecretBytesTest,ReadExact)126 TEST(ReadSecretBytesTest, ReadExact) {
127 const std::string content = "Some content";
128 IstreamInputStream input_stream{
129 absl::make_unique<std::stringstream>(content)};
130 auto text_or = ReadSecretBytesFromStream(content.size(), &input_stream);
131 ASSERT_THAT(text_or, IsOk());
132 std::string text(util::SecretDataAsStringView(std::move(text_or).value()));
133 EXPECT_THAT(text, Eq(content));
134 }
135
TEST(ReadSecretBytesTest,ShortRead)136 TEST(ReadSecretBytesTest, ShortRead) {
137 IstreamInputStream input_stream{
138 absl::make_unique<std::stringstream>("Some content")};
139 auto text_or = ReadSecretBytesFromStream(100, &input_stream);
140 EXPECT_THAT(text_or.status(), StatusIs(absl::StatusCode::kOutOfRange));
141 }
142
TEST(ReadSecretBytesTest,ReadLess)143 TEST(ReadSecretBytesTest, ReadLess) {
144 IstreamInputStream input_stream{
145 absl::make_unique<std::stringstream>("0123456789abcdefghijklmnop")};
146 auto text_or = ReadSecretBytesFromStream(7, &input_stream);
147 ASSERT_THAT(text_or, IsOk());
148 std::string text(util::SecretDataAsStringView(std::move(text_or).value()));
149 EXPECT_THAT(text, Eq("0123456"));
150 }
151
TEST(ReadSecretBytesTest,ReadTwice)152 TEST(ReadSecretBytesTest, ReadTwice) {
153 IstreamInputStream input_stream{
154 absl::make_unique<std::stringstream>("0123456789abcdefghijklmnop")};
155 auto text_or = ReadSecretBytesFromStream(7, &input_stream);
156 std::string text(util::SecretDataAsStringView(std::move(text_or).value()));
157 EXPECT_THAT(text, Eq("0123456"));
158
159 text_or = ReadSecretBytesFromStream(5, &input_stream);
160 ASSERT_THAT(text_or, IsOk());
161 text = std::string(util::SecretDataAsStringView(std::move(text_or).value()));
162 EXPECT_THAT(text, Eq("789ab"));
163 }
164
TEST(ReadSecretBytesTest,ReadMoreThanBlockSize)165 TEST(ReadSecretBytesTest, ReadMoreThanBlockSize) {
166 // Use a block size of 4 such that ReadAtMost has to call the input multiple
167 // times.
168 IstreamInputStream input_stream{
169 absl::make_unique<std::stringstream>("0123456789abcdefghijklmnop"), 4};
170 auto text_or = ReadSecretBytesFromStream(11, &input_stream);
171 ASSERT_THAT(text_or, IsOk());
172 std::string text(util::SecretDataAsStringView(std::move(text_or).value()));
173 EXPECT_THAT(text, Eq("0123456789a"));
174
175 text_or = ReadSecretBytesFromStream(5, &input_stream);
176 ASSERT_THAT(text_or, IsOk());
177 text = std::string(util::SecretDataAsStringView(std::move(text_or).value()));
178 EXPECT_THAT(text, Eq("bcdef"));
179 }
180
TEST(ReadSecretBytesTest,Request0)181 TEST(ReadSecretBytesTest, Request0) {
182 IstreamInputStream input_stream(
183 absl::make_unique<std::stringstream>("012345678"));
184 auto text_or = ReadSecretBytesFromStream(4, &input_stream);
185 ASSERT_THAT(text_or, IsOk());
186 std::string text(util::SecretDataAsStringView(std::move(text_or).value()));
187 EXPECT_THAT(text, Eq("0123"));
188 text_or = ReadSecretBytesFromStream(0, &input_stream);
189 ASSERT_THAT(text_or, IsOk());
190 text = std::string(util::SecretDataAsStringView(std::move(text_or).value()));
191 EXPECT_THAT(text, Eq(""));
192 text_or = ReadSecretBytesFromStream(5, &input_stream);
193 ASSERT_THAT(text_or, IsOk());
194 text = std::string(util::SecretDataAsStringView(std::move(text_or).value()));
195 EXPECT_THAT(text, Eq("45678"));
196 text_or = ReadSecretBytesFromStream(0, &input_stream);
197 ASSERT_THAT(text_or, IsOk());
198 text = std::string(util::SecretDataAsStringView(std::move(text_or).value()));
199 EXPECT_THAT(text, Eq(""));
200 }
201
TEST(ReadSecretBytesTest,RequestNegative)202 TEST(ReadSecretBytesTest, RequestNegative) {
203 IstreamInputStream input_stream(
204 absl::make_unique<std::stringstream>("012345678"));
205 auto text_or = ReadSecretBytesFromStream(-1, &input_stream);
206 ASSERT_THAT(text_or, IsOk());
207 std::string text(util::SecretDataAsStringView(std::move(text_or).value()));
208 EXPECT_THAT(text, Eq(""));
209 }
210
TEST(ReadSecretBytesTest,EmptyInput)211 TEST(ReadSecretBytesTest, EmptyInput) {
212 IstreamInputStream input_stream(
213 absl::make_unique<std::stringstream>(""));
214 auto text_or = ReadSecretBytesFromStream(0, &input_stream);
215 ASSERT_THAT(text_or, IsOk());
216 std::string text(util::SecretDataAsStringView(std::move(text_or).value()));
217 EXPECT_THAT(text, Eq(""));
218 text_or = ReadSecretBytesFromStream(1, &input_stream);
219 EXPECT_THAT(text_or.status(), StatusIs(absl::StatusCode::kOutOfRange));
220 }
221
222 } // namespace
223 } // namespace tink
224 } // namespace crypto
225