1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "device/fido/fido_parsing_utils.h"
6 
7 #include "device/fido/fido_test_data.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 
11 namespace device {
12 namespace fido_parsing_utils {
13 
14 namespace {
15 constexpr uint8_t kOne[] = {0x01};
16 constexpr uint8_t kOneTwo[] = {0x01, 0x02};
17 constexpr uint8_t kTwo[] = {0x02};
18 constexpr uint8_t kTwoThree[] = {0x02, 0x03};
19 constexpr uint8_t kThree[] = {0x03};
20 constexpr uint8_t kOneTwoThree[] = {0x01, 0x02, 0x03};
21 }  // namespace
22 
TEST(U2fParsingUtils,RangeLess)23 TEST(U2fParsingUtils, RangeLess) {
24   const std::array<int, 4> kOneTwoThreeFour = {1, 2, 3, 4};
25 
26   EXPECT_FALSE(RangeLess()(kOne, kOne));
27   EXPECT_TRUE(RangeLess()(kOne, kOneTwo));
28   EXPECT_TRUE(RangeLess()(kOne, kTwo));
29   EXPECT_TRUE(RangeLess()(kOne, kTwoThree));
30   EXPECT_TRUE(RangeLess()(kOne, kThree));
31   EXPECT_TRUE(RangeLess()(kOne, kOneTwoThree));
32   EXPECT_TRUE(RangeLess()(kOne, kOneTwoThreeFour));
33 
34   EXPECT_FALSE(RangeLess()(kOneTwo, kOne));
35   EXPECT_FALSE(RangeLess()(kOneTwo, kOneTwo));
36   EXPECT_TRUE(RangeLess()(kOneTwo, kTwo));
37   EXPECT_TRUE(RangeLess()(kOneTwo, kTwoThree));
38   EXPECT_TRUE(RangeLess()(kOneTwo, kThree));
39   EXPECT_TRUE(RangeLess()(kOneTwo, kOneTwoThree));
40   EXPECT_TRUE(RangeLess()(kOneTwo, kOneTwoThreeFour));
41 
42   EXPECT_FALSE(RangeLess()(kTwo, kOne));
43   EXPECT_FALSE(RangeLess()(kTwo, kOneTwo));
44   EXPECT_FALSE(RangeLess()(kTwo, kTwo));
45   EXPECT_TRUE(RangeLess()(kTwo, kTwoThree));
46   EXPECT_TRUE(RangeLess()(kTwo, kThree));
47   EXPECT_FALSE(RangeLess()(kTwo, kOneTwoThree));
48   EXPECT_FALSE(RangeLess()(kTwo, kOneTwoThreeFour));
49 
50   EXPECT_FALSE(RangeLess()(kTwoThree, kOne));
51   EXPECT_FALSE(RangeLess()(kTwoThree, kOneTwo));
52   EXPECT_FALSE(RangeLess()(kTwoThree, kTwo));
53   EXPECT_FALSE(RangeLess()(kTwoThree, kTwoThree));
54   EXPECT_TRUE(RangeLess()(kTwoThree, kThree));
55   EXPECT_FALSE(RangeLess()(kTwoThree, kOneTwoThree));
56   EXPECT_FALSE(RangeLess()(kTwoThree, kOneTwoThreeFour));
57 
58   EXPECT_FALSE(RangeLess()(kThree, kOne));
59   EXPECT_FALSE(RangeLess()(kThree, kOneTwo));
60   EXPECT_FALSE(RangeLess()(kThree, kTwo));
61   EXPECT_FALSE(RangeLess()(kThree, kTwoThree));
62   EXPECT_FALSE(RangeLess()(kThree, kThree));
63   EXPECT_FALSE(RangeLess()(kThree, kOneTwoThree));
64   EXPECT_FALSE(RangeLess()(kThree, kOneTwoThreeFour));
65 
66   EXPECT_FALSE(RangeLess()(kOneTwoThree, kOne));
67   EXPECT_FALSE(RangeLess()(kOneTwoThree, kOneTwo));
68   EXPECT_TRUE(RangeLess()(kOneTwoThree, kTwo));
69   EXPECT_TRUE(RangeLess()(kOneTwoThree, kTwoThree));
70   EXPECT_TRUE(RangeLess()(kOneTwoThree, kThree));
71   EXPECT_FALSE(RangeLess()(kOneTwoThree, kOneTwoThree));
72   EXPECT_TRUE(RangeLess()(kOneTwoThree, kOneTwoThreeFour));
73 
74   EXPECT_FALSE(RangeLess()(kOneTwoThreeFour, kOne));
75   EXPECT_FALSE(RangeLess()(kOneTwoThreeFour, kOneTwo));
76   EXPECT_TRUE(RangeLess()(kOneTwoThreeFour, kTwo));
77   EXPECT_TRUE(RangeLess()(kOneTwoThreeFour, kTwoThree));
78   EXPECT_TRUE(RangeLess()(kOneTwoThreeFour, kThree));
79   EXPECT_FALSE(RangeLess()(kOneTwoThreeFour, kOneTwoThree));
80   EXPECT_FALSE(RangeLess()(kOneTwoThreeFour, kOneTwoThreeFour));
81 }
82 
TEST(U2fParsingUtils,Materialize)83 TEST(U2fParsingUtils, Materialize) {
84   const std::vector<uint8_t> empty;
85   EXPECT_THAT(Materialize(empty), ::testing::IsEmpty());
86   EXPECT_THAT(Materialize(base::span<const uint8_t>()), ::testing::IsEmpty());
87 
88   EXPECT_THAT(Materialize(base::span<const uint8_t>(kOne)),
89               ::testing::ElementsAreArray(kOne));
90   EXPECT_THAT(Materialize(base::span<const uint8_t>(kOneTwoThree)),
91               ::testing::ElementsAreArray(kOneTwoThree));
92 
93   static_assert(std::is_same<std::vector<uint8_t>,
94                              decltype(Materialize(
95                                  base::span<const uint8_t>(kOne)))>::value,
96                 "Materialize with a dynamic span should yield a std::vector.");
97 }
98 
TEST(U2fParsingUtils,StaticMaterialize)99 TEST(U2fParsingUtils, StaticMaterialize) {
100   std::array<uint8_t, 0> empty;
101   EXPECT_THAT(Materialize(empty), ::testing::IsEmpty());
102   EXPECT_THAT(Materialize(base::span<const uint8_t, 0>()),
103               ::testing::IsEmpty());
104 
105   EXPECT_THAT(Materialize(base::make_span(kOne)),
106               ::testing::ElementsAreArray(kOne));
107   EXPECT_THAT(Materialize(base::make_span(kOneTwoThree)),
108               ::testing::ElementsAreArray(kOneTwoThree));
109 
110   static_assert(
111       std::is_same<std::array<uint8_t, 1>,
112                    decltype(Materialize(base::make_span(kOne)))>::value,
113       "Materialize with a static span should yield a std::array.");
114 }
115 
TEST(U2fParsingUtils,MaterializeOrNull)116 TEST(U2fParsingUtils, MaterializeOrNull) {
117   auto result = MaterializeOrNull(kOneTwoThree);
118   ASSERT_TRUE(result.has_value());
119   EXPECT_THAT(*result, ::testing::ElementsAreArray(kOneTwoThree));
120 
121   EXPECT_EQ(MaterializeOrNull(base::nullopt), base::nullopt);
122 }
123 
TEST(U2fParsingUtils,Append)124 TEST(U2fParsingUtils, Append) {
125   std::vector<uint8_t> target;
126 
127   Append(&target, base::span<const uint8_t>());
128   EXPECT_THAT(target, ::testing::IsEmpty());
129 
130   // Should be idempotent, try twice for good measure.
131   Append(&target, base::span<const uint8_t>());
132   EXPECT_THAT(target, ::testing::IsEmpty());
133 
134   const std::vector<uint8_t> one(std::begin(kOne), std::end(kOne));
135   Append(&target, one);
136   EXPECT_THAT(target, ::testing::ElementsAreArray(kOne));
137 
138   Append(&target, kTwoThree);
139   EXPECT_THAT(target, ::testing::ElementsAreArray(kOneTwoThree));
140 }
141 
TEST(U2fParsingUtils,AppendSelfCrashes)142 TEST(U2fParsingUtils, AppendSelfCrashes) {
143   std::vector<uint8_t> target(std::begin(kOneTwoThree), std::end(kOneTwoThree));
144   auto span = base::make_span(target);
145 
146   // Tests the case where |in_values| overlap with the beginning of |*target|.
147   EXPECT_DEATH_IF_SUPPORTED(Append(&target, span.first(1)), "");
148 
149   // Tests the case where |in_values| overlap with the end of |*target|.
150   EXPECT_DEATH_IF_SUPPORTED(Append(&target, span.last(1)), "");
151 }
152 
153 // ExtractSpan and ExtractSuffixSpan are implicitly tested as they used by
154 // the Extract and ExtractSuffix implementations.
155 
TEST(U2fParsingUtils,ExtractEmpty)156 TEST(U2fParsingUtils, ExtractEmpty) {
157   const std::vector<uint8_t> empty;
158   EXPECT_THAT(Extract(empty, 0, 0), ::testing::IsEmpty());
159 
160   EXPECT_THAT(Extract(kOne, 0, 0), ::testing::IsEmpty());
161   EXPECT_THAT(Extract(kOne, 1, 0), ::testing::IsEmpty());
162 
163   EXPECT_THAT(Extract(kOneTwoThree, 0, 0), ::testing::IsEmpty());
164   EXPECT_THAT(Extract(kOneTwoThree, 1, 0), ::testing::IsEmpty());
165   EXPECT_THAT(Extract(kOneTwoThree, 2, 0), ::testing::IsEmpty());
166   EXPECT_THAT(Extract(kOneTwoThree, 3, 0), ::testing::IsEmpty());
167 }
168 
TEST(U2fParsingUtils,ExtractInBounds)169 TEST(U2fParsingUtils, ExtractInBounds) {
170   EXPECT_THAT(Extract(kOne, 0, 1), ::testing::ElementsAreArray(kOne));
171   EXPECT_THAT(Extract(kOneTwoThree, 0, 1), ::testing::ElementsAreArray(kOne));
172   EXPECT_THAT(Extract(kOneTwoThree, 2, 1), ::testing::ElementsAreArray(kThree));
173   EXPECT_THAT(Extract(kOneTwoThree, 1, 2),
174               ::testing::ElementsAreArray(kTwoThree));
175   EXPECT_THAT(Extract(kOneTwoThree, 0, 3),
176               ::testing::ElementsAreArray(kOneTwoThree));
177 }
178 
TEST(U2fParsingUtils,ExtractOutOfBounds)179 TEST(U2fParsingUtils, ExtractOutOfBounds) {
180   const std::vector<uint8_t> empty;
181   EXPECT_THAT(Extract(empty, 0, 1), ::testing::IsEmpty());
182   EXPECT_THAT(Extract(empty, 1, 0), ::testing::IsEmpty());
183 
184   EXPECT_THAT(Extract(kOne, 0, 2), ::testing::IsEmpty());
185   EXPECT_THAT(Extract(kOne, 1, 1), ::testing::IsEmpty());
186   EXPECT_THAT(Extract(kOne, 2, 0), ::testing::IsEmpty());
187 
188   EXPECT_THAT(Extract(kOneTwoThree, 0, 4), ::testing::IsEmpty());
189   EXPECT_THAT(Extract(kOneTwoThree, 1, 3), ::testing::IsEmpty());
190   EXPECT_THAT(Extract(kOneTwoThree, 2, 2), ::testing::IsEmpty());
191   EXPECT_THAT(Extract(kOneTwoThree, 3, 1), ::testing::IsEmpty());
192   EXPECT_THAT(Extract(kOneTwoThree, 4, 0), ::testing::IsEmpty());
193 }
194 
TEST(U2fParsingUtils,ExtractSuffixEmpty)195 TEST(U2fParsingUtils, ExtractSuffixEmpty) {
196   const std::vector<uint8_t> empty;
197   EXPECT_THAT(ExtractSuffix(empty, 0), ::testing::IsEmpty());
198   EXPECT_THAT(ExtractSuffix(kOne, 1), ::testing::IsEmpty());
199   EXPECT_THAT(ExtractSuffix(kOneTwoThree, 3), ::testing::IsEmpty());
200 }
201 
TEST(U2fParsingUtils,ExtractSuffixInBounds)202 TEST(U2fParsingUtils, ExtractSuffixInBounds) {
203   EXPECT_THAT(ExtractSuffix(kOne, 0), ::testing::ElementsAreArray(kOne));
204   EXPECT_THAT(ExtractSuffix(kOneTwoThree, 1),
205               ::testing::ElementsAreArray(kTwoThree));
206   EXPECT_THAT(ExtractSuffix(kOneTwoThree, 2),
207               ::testing::ElementsAreArray(kThree));
208 }
209 
TEST(U2fParsingUtils,ExtractSuffixOutOfBounds)210 TEST(U2fParsingUtils, ExtractSuffixOutOfBounds) {
211   const std::vector<uint8_t> empty;
212   EXPECT_THAT(ExtractSuffix(empty, 1), ::testing::IsEmpty());
213   EXPECT_THAT(ExtractSuffix(kOne, 2), ::testing::IsEmpty());
214   EXPECT_THAT(ExtractSuffix(kOneTwoThree, 4), ::testing::IsEmpty());
215 }
216 
TEST(U2fParsingUtils,ExtractArray)217 TEST(U2fParsingUtils, ExtractArray) {
218   const std::vector<uint8_t> empty;
219   std::array<uint8_t, 0> array_empty;
220   EXPECT_TRUE(ExtractArray(empty, 0, &array_empty));
221 
222   std::array<uint8_t, 2> array_two_three;
223   EXPECT_TRUE(ExtractArray(kTwoThree, 0, &array_two_three));
224   EXPECT_THAT(array_two_three, ::testing::ElementsAreArray(kTwoThree));
225 
226   EXPECT_FALSE(ExtractArray(kOneTwoThree, 2, &array_two_three));
227 
228   std::array<uint8_t, 1> array_three;
229   EXPECT_TRUE(ExtractArray(kOneTwoThree, 2, &array_three));
230   EXPECT_THAT(array_three, ::testing::ElementsAreArray(kThree));
231 }
232 
TEST(U2fParsingUtils,SplitSpan)233 TEST(U2fParsingUtils, SplitSpan) {
234   std::vector<uint8_t> empty;
235   EXPECT_THAT(SplitSpan(empty, 1), ::testing::IsEmpty());
236   EXPECT_THAT(SplitSpan(empty, 2), ::testing::IsEmpty());
237   EXPECT_THAT(SplitSpan(empty, 3), ::testing::IsEmpty());
238 
239   EXPECT_THAT(SplitSpan(kOne, 1),
240               ::testing::ElementsAre(::testing::ElementsAreArray(kOne)));
241   EXPECT_THAT(SplitSpan(kOne, 2),
242               ::testing::ElementsAre(::testing::ElementsAreArray(kOne)));
243   EXPECT_THAT(SplitSpan(kOne, 3),
244               ::testing::ElementsAre(::testing::ElementsAreArray(kOne)));
245 
246   EXPECT_THAT(SplitSpan(kOneTwo, 1),
247               ::testing::ElementsAre(::testing::ElementsAreArray(kOne),
248                                      ::testing::ElementsAreArray(kTwo)));
249   EXPECT_THAT(SplitSpan(kOneTwo, 2),
250               ::testing::ElementsAre(::testing::ElementsAreArray(kOneTwo)));
251   EXPECT_THAT(SplitSpan(kOneTwo, 3),
252               ::testing::ElementsAre(::testing::ElementsAreArray(kOneTwo)));
253 
254   EXPECT_THAT(SplitSpan(kOneTwoThree, 1),
255               ::testing::ElementsAre(::testing::ElementsAreArray(kOne),
256                                      ::testing::ElementsAreArray(kTwo),
257                                      ::testing::ElementsAreArray(kThree)));
258   EXPECT_THAT(SplitSpan(kOneTwoThree, 2),
259               ::testing::ElementsAre(::testing::ElementsAreArray(kOneTwo),
260                                      ::testing::ElementsAreArray(kThree)));
261   EXPECT_THAT(
262       SplitSpan(kOneTwoThree, 3),
263       ::testing::ElementsAre(::testing::ElementsAreArray(kOneTwoThree)));
264   EXPECT_THAT(
265       SplitSpan(kOneTwoThree, 4),
266       ::testing::ElementsAre(::testing::ElementsAreArray(kOneTwoThree)));
267   EXPECT_THAT(
268       SplitSpan(kOneTwoThree, 5),
269       ::testing::ElementsAre(::testing::ElementsAreArray(kOneTwoThree)));
270   EXPECT_THAT(
271       SplitSpan(kOneTwoThree, 6),
272       ::testing::ElementsAre(::testing::ElementsAreArray(kOneTwoThree)));
273 }
274 
TEST(U2fParsingUtils,CreateSHA256Hash)275 TEST(U2fParsingUtils, CreateSHA256Hash) {
276   EXPECT_THAT(CreateSHA256Hash("acme.com"),
277               ::testing::ElementsAreArray(test_data::kApplicationParameter));
278 }
279 
TEST(U2fParsingUtils,ConvertSpanToStringPiece)280 TEST(U2fParsingUtils, ConvertSpanToStringPiece) {
281   constexpr uint8_t kTestAsciiAbcd[] = {'a', 'b', 'c', 'd'};
282   EXPECT_EQ("abcd", ConvertToStringPiece(kTestAsciiAbcd));
283 }
284 
285 }  // namespace fido_parsing_utils
286 }  // namespace device
287