1 // Copyright 2020 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/subtle/prf/streaming_prf_wrapper.h"
18
19 #include <memory>
20 #include <sstream>
21 #include <string>
22 #include <utility>
23
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "absl/status/status.h"
27 #include "absl/strings/str_cat.h"
28 #include "tink/util/input_stream_util.h"
29 #include "tink/util/istream_input_stream.h"
30 #include "tink/util/test_matchers.h"
31 #include "tink/util/test_util.h"
32 #include "proto/tink.pb.h"
33
34 namespace crypto {
35 namespace tink {
36 namespace {
37
38 using ::crypto::tink::test::IsOk;
39 using ::crypto::tink::test::StatusIs;
40 using ::google::crypto::tink::KeysetInfo;
41 using ::google::crypto::tink::KeyStatusType;
42 using ::google::crypto::tink::OutputPrefixType;
43 using ::testing::Eq;
44 using ::testing::HasSubstr;
45
46 class DummyStreamingPrf : public StreamingPrf {
47 public:
DummyStreamingPrf(absl::string_view name)48 explicit DummyStreamingPrf(absl::string_view name) : name_(name) {}
ComputePrf(absl::string_view input) const49 std::unique_ptr<InputStream> ComputePrf(
50 absl::string_view input) const override {
51 return absl::make_unique<crypto::tink::util::IstreamInputStream>(
52 absl::make_unique<std::stringstream>(
53 absl::StrCat(name_.length(), ":", name_, input)));
54 }
55
56 private:
57 std::string name_;
58 };
59
TEST(AeadSetWrapperTest,WrapNullptr)60 TEST(AeadSetWrapperTest, WrapNullptr) {
61 StreamingPrfWrapper wrapper;
62 EXPECT_THAT(
63 wrapper.Wrap(nullptr).status(),
64 StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("non-NULL")));
65 }
66
TEST(KeysetDeriverWrapperTest,WrapEmpty)67 TEST(KeysetDeriverWrapperTest, WrapEmpty) {
68 EXPECT_THAT(StreamingPrfWrapper()
69 .Wrap(absl::make_unique<PrimitiveSet<StreamingPrf>>())
70 .status(),
71 StatusIs(absl::StatusCode::kInvalidArgument,
72 HasSubstr("exactly one key")));
73 }
74
TEST(KeysetDeriverWrapperTest,WrapSingle)75 TEST(KeysetDeriverWrapperTest, WrapSingle) {
76 auto prf_set = absl::make_unique<PrimitiveSet<StreamingPrf>>();
77 KeysetInfo::KeyInfo key_info;
78 key_info.set_key_id(1234);
79 key_info.set_status(KeyStatusType::ENABLED);
80 key_info.set_output_prefix_type(OutputPrefixType::RAW);
81
82 auto entry_or = prf_set->AddPrimitive(
83 absl::make_unique<DummyStreamingPrf>("single_key"), key_info);
84 ASSERT_THAT(entry_or, IsOk());
85 EXPECT_THAT(prf_set->set_primary(entry_or.value()), IsOk());
86
87 auto wrapped_prf = StreamingPrfWrapper().Wrap(std::move(prf_set));
88
89 ASSERT_THAT(wrapped_prf, IsOk());
90
91 auto prf_output = ReadBytesFromStream(
92 23, wrapped_prf.value()->ComputePrf("input_text").get());
93 ASSERT_THAT(prf_output, IsOk());
94 EXPECT_THAT(prf_output.value(), Eq("10:single_keyinput_text"));
95 }
96
TEST(KeysetDeriverWrapperTest,WrapNonRaw)97 TEST(KeysetDeriverWrapperTest, WrapNonRaw) {
98 auto prf_set = absl::make_unique<PrimitiveSet<StreamingPrf>>();
99 KeysetInfo::KeyInfo key_info;
100 key_info.set_key_id(1234);
101 key_info.set_status(KeyStatusType::ENABLED);
102 key_info.set_output_prefix_type(OutputPrefixType::TINK);
103
104 auto entry_or = prf_set->AddPrimitive(
105 absl::make_unique<DummyStreamingPrf>("single_key"), key_info);
106 ASSERT_THAT(entry_or, IsOk());
107 EXPECT_THAT(prf_set->set_primary(entry_or.value()), IsOk());
108
109 EXPECT_THAT(StreamingPrfWrapper().Wrap(std::move(prf_set)).status(),
110 StatusIs(absl::StatusCode::kInvalidArgument,
111 HasSubstr("output_prefix_type")));
112 }
113
114
TEST(KeysetDeriverWrapperTest,WrapMultiple)115 TEST(KeysetDeriverWrapperTest, WrapMultiple) {
116 auto prf_set = absl::make_unique<PrimitiveSet<StreamingPrf>>();
117 KeysetInfo::KeyInfo key_info;
118 key_info.set_key_id(1234);
119 key_info.set_status(KeyStatusType::ENABLED);
120 key_info.set_output_prefix_type(OutputPrefixType::RAW);
121
122 auto entry_or = prf_set->AddPrimitive(
123 absl::make_unique<DummyStreamingPrf>("single_key"), key_info);
124 ASSERT_THAT(entry_or, IsOk());
125 EXPECT_THAT(prf_set->set_primary(entry_or.value()), IsOk());
126 key_info.set_key_id(2345);
127 EXPECT_THAT(
128 prf_set
129 ->AddPrimitive(absl::make_unique<DummyStreamingPrf>("second_key"),
130 key_info)
131 .status(),
132 IsOk());
133
134 EXPECT_THAT(StreamingPrfWrapper().Wrap(std::move(prf_set)).status(),
135 StatusIs(absl::StatusCode::kInvalidArgument,
136 HasSubstr("given set has 2 keys")));
137 }
138
139
140 } // namespace
141 } // namespace tink
142 } // namespace crypto
143