1 // Copyright 2015 The Chromium Authors
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 //     https://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 #include "parser.h"
16 
17 #include <gtest/gtest.h>
18 #include "input.h"
19 #include "parse_values.h"
20 
21 BSSL_NAMESPACE_BEGIN
22 namespace der::test {
23 
TEST(ParserTest,ConsumesAllBytesOfTLV)24 TEST(ParserTest, ConsumesAllBytesOfTLV) {
25   const uint8_t der[] = {0x04 /* OCTET STRING */, 0x00};
26   Parser parser((Input(der)));
27   CBS_ASN1_TAG tag;
28   Input value;
29   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
30   ASSERT_EQ(CBS_ASN1_OCTETSTRING, tag);
31   ASSERT_FALSE(parser.HasMore());
32 }
33 
TEST(ParserTest,CanReadRawTLV)34 TEST(ParserTest, CanReadRawTLV) {
35   const uint8_t der[] = {0x02, 0x01, 0x01};
36   Parser parser((Input(der)));
37   Input tlv;
38   ASSERT_TRUE(parser.ReadRawTLV(&tlv));
39   ByteReader tlv_reader(tlv);
40   size_t tlv_len = tlv_reader.BytesLeft();
41   ASSERT_EQ(3u, tlv_len);
42   Input tlv_data;
43   ASSERT_TRUE(tlv_reader.ReadBytes(tlv_len, &tlv_data));
44   ASSERT_FALSE(parser.HasMore());
45 }
46 
TEST(ParserTest,IgnoresContentsOfInnerValues)47 TEST(ParserTest, IgnoresContentsOfInnerValues) {
48   // This is a SEQUENCE which has one member. The member is another SEQUENCE
49   // with an invalid encoding - its length is too long.
50   const uint8_t der[] = {0x30, 0x02, 0x30, 0x7e};
51   Parser parser((Input(der)));
52   CBS_ASN1_TAG tag;
53   Input value;
54   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
55 }
56 
TEST(ParserTest,FailsIfLengthOverlapsAnotherTLV)57 TEST(ParserTest, FailsIfLengthOverlapsAnotherTLV) {
58   // This DER encoding has 2 top-level TLV tuples. The first is a SEQUENCE;
59   // the second is an INTEGER. The SEQUENCE contains an INTEGER, but its length
60   // is longer than what it has contents for.
61   const uint8_t der[] = {0x30, 0x02, 0x02, 0x01, 0x02, 0x01, 0x01};
62   Parser parser((Input(der)));
63 
64   Parser inner_sequence;
65   ASSERT_TRUE(parser.ReadSequence(&inner_sequence));
66   uint64_t int_value;
67   ASSERT_TRUE(parser.ReadUint64(&int_value));
68   ASSERT_EQ(1u, int_value);
69   ASSERT_FALSE(parser.HasMore());
70 
71   // Try to read the INTEGER from the SEQUENCE, which should fail.
72   CBS_ASN1_TAG tag;
73   Input value;
74   ASSERT_FALSE(inner_sequence.ReadTagAndValue(&tag, &value));
75 }
76 
TEST(ParserTest,ReadOptionalTagPresent)77 TEST(ParserTest, ReadOptionalTagPresent) {
78   // DER encoding of 2 top-level TLV values:
79   // INTEGER { 1 }
80   // OCTET_STRING { `02` }
81   const uint8_t der[] = {0x02, 0x01, 0x01, 0x04, 0x01, 0x02};
82   Parser parser((Input(der)));
83 
84   Input value;
85   bool present;
86   ASSERT_TRUE(parser.ReadOptionalTag(CBS_ASN1_INTEGER, &value, &present));
87   ASSERT_TRUE(present);
88   const uint8_t expected_int_value[] = {0x01};
89   ASSERT_EQ(Input(expected_int_value), value);
90 
91   CBS_ASN1_TAG tag;
92   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
93   ASSERT_EQ(CBS_ASN1_OCTETSTRING, tag);
94   const uint8_t expected_octet_string_value[] = {0x02};
95   ASSERT_EQ(Input(expected_octet_string_value), value);
96 
97   ASSERT_FALSE(parser.HasMore());
98 }
99 
TEST(ParserTest,ReadOptionalTag2Present)100 TEST(ParserTest, ReadOptionalTag2Present) {
101   // DER encoding of 2 top-level TLV values:
102   // INTEGER { 1 }
103   // OCTET_STRING { `02` }
104   const uint8_t der[] = {0x02, 0x01, 0x01, 0x04, 0x01, 0x02};
105   Parser parser((Input(der)));
106 
107   std::optional<Input> optional_value;
108   ASSERT_TRUE(parser.ReadOptionalTag(CBS_ASN1_INTEGER, &optional_value));
109   ASSERT_TRUE(optional_value.has_value());
110   const uint8_t expected_int_value[] = {0x01};
111   ASSERT_EQ(Input(expected_int_value), *optional_value);
112 
113   CBS_ASN1_TAG tag;
114   Input value;
115   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
116   ASSERT_EQ(CBS_ASN1_OCTETSTRING, tag);
117   const uint8_t expected_octet_string_value[] = {0x02};
118   ASSERT_EQ(Input(expected_octet_string_value), value);
119 
120   ASSERT_FALSE(parser.HasMore());
121 }
122 
TEST(ParserTest,ReadOptionalTagNotPresent)123 TEST(ParserTest, ReadOptionalTagNotPresent) {
124   // DER encoding of 1 top-level TLV value:
125   // OCTET_STRING { `02` }
126   const uint8_t der[] = {0x04, 0x01, 0x02};
127   Parser parser((Input(der)));
128 
129   Input value;
130   bool present;
131   ASSERT_TRUE(parser.ReadOptionalTag(CBS_ASN1_INTEGER, &value, &present));
132   ASSERT_FALSE(present);
133 
134   CBS_ASN1_TAG tag;
135   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
136   ASSERT_EQ(CBS_ASN1_OCTETSTRING, tag);
137   const uint8_t expected_octet_string_value[] = {0x02};
138   ASSERT_EQ(Input(expected_octet_string_value), value);
139 
140   ASSERT_FALSE(parser.HasMore());
141 }
142 
TEST(ParserTest,ReadOptionalTag2NotPresent)143 TEST(ParserTest, ReadOptionalTag2NotPresent) {
144   // DER encoding of 1 top-level TLV value:
145   // OCTET_STRING { `02` }
146   const uint8_t der[] = {0x04, 0x01, 0x02};
147   Parser parser((Input(der)));
148 
149   std::optional<Input> optional_value;
150   ASSERT_TRUE(parser.ReadOptionalTag(CBS_ASN1_INTEGER, &optional_value));
151   ASSERT_FALSE(optional_value.has_value());
152 
153   CBS_ASN1_TAG tag;
154   Input value;
155   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
156   ASSERT_EQ(CBS_ASN1_OCTETSTRING, tag);
157   const uint8_t expected_octet_string_value[] = {0x02};
158   ASSERT_EQ(Input(expected_octet_string_value), value);
159 
160   ASSERT_FALSE(parser.HasMore());
161 }
162 
TEST(ParserTest,CanSkipOptionalTagAtEndOfInput)163 TEST(ParserTest, CanSkipOptionalTagAtEndOfInput) {
164   const uint8_t der[] = {0x02 /* INTEGER */, 0x01, 0x01};
165   Parser parser((Input(der)));
166 
167   CBS_ASN1_TAG tag;
168   Input value;
169   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
170   bool present;
171   ASSERT_TRUE(parser.ReadOptionalTag(CBS_ASN1_INTEGER, &value, &present));
172   ASSERT_FALSE(present);
173   ASSERT_FALSE(parser.HasMore());
174 }
175 
TEST(ParserTest,SkipOptionalTagDoesntConsumePresentNonMatchingTLVs)176 TEST(ParserTest, SkipOptionalTagDoesntConsumePresentNonMatchingTLVs) {
177   const uint8_t der[] = {0x02 /* INTEGER */, 0x01, 0x01};
178   Parser parser((Input(der)));
179 
180   bool present;
181   ASSERT_TRUE(parser.SkipOptionalTag(CBS_ASN1_OCTETSTRING, &present));
182   ASSERT_FALSE(present);
183   ASSERT_TRUE(parser.SkipOptionalTag(CBS_ASN1_INTEGER, &present));
184   ASSERT_TRUE(present);
185   ASSERT_FALSE(parser.HasMore());
186 }
187 
TEST(ParserTest,TagNumbersAboveThirtySupported)188 TEST(ParserTest, TagNumbersAboveThirtySupported) {
189   // Context-specific class, tag number 31, length 0.
190   const uint8_t der[] = {0x9f, 0x1f, 0x00};
191   Parser parser((Input(der)));
192 
193   CBS_ASN1_TAG tag;
194   Input value;
195   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
196   EXPECT_EQ(CBS_ASN1_CONTEXT_SPECIFIC | 31u, tag);
197   ASSERT_FALSE(parser.HasMore());
198 }
199 
TEST(ParserTest,ParseTags)200 TEST(ParserTest, ParseTags) {
201   {
202     // Universal primitive tag, tag number 4.
203     const uint8_t der[] = {0x04, 0x00};
204     Parser parser((Input(der)));
205 
206     CBS_ASN1_TAG tag;
207     Input value;
208     ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
209     EXPECT_EQ(CBS_ASN1_OCTETSTRING, tag);
210   }
211 
212   {
213     // Universal constructed tag, tag number 16.
214     const uint8_t der[] = {0x30, 0x00};
215     Parser parser((Input(der)));
216 
217     CBS_ASN1_TAG tag;
218     Input value;
219     ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
220     EXPECT_EQ(CBS_ASN1_SEQUENCE, tag);
221   }
222 
223   {
224     // Application primitive tag, tag number 1.
225     const uint8_t der[] = {0x41, 0x00};
226     Parser parser((Input(der)));
227 
228     CBS_ASN1_TAG tag;
229     Input value;
230     ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
231     EXPECT_EQ(CBS_ASN1_APPLICATION | 1, tag);
232   }
233 
234   {
235     // Context-specific constructed tag, tag number 30.
236     const uint8_t der[] = {0xbe, 0x00};
237     Parser parser((Input(der)));
238 
239     CBS_ASN1_TAG tag;
240     Input value;
241     ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
242     EXPECT_EQ(CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 30, tag);
243   }
244 
245   {
246     // Private primitive tag, tag number 15.
247     const uint8_t der[] = {0xcf, 0x00};
248     Parser parser((Input(der)));
249 
250     CBS_ASN1_TAG tag;
251     Input value;
252     ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
253     EXPECT_EQ(CBS_ASN1_PRIVATE | 15, tag);
254   }
255 }
256 
TEST(ParserTest,IncompleteEncodingTagOnly)257 TEST(ParserTest, IncompleteEncodingTagOnly) {
258   const uint8_t der[] = {0x01};
259   Parser parser((Input(der)));
260 
261   CBS_ASN1_TAG tag;
262   Input value;
263   ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
264   ASSERT_TRUE(parser.HasMore());
265 }
266 
TEST(ParserTest,IncompleteEncodingLengthTruncated)267 TEST(ParserTest, IncompleteEncodingLengthTruncated) {
268   // Tag: octet string; length: long form, should have 2 total octets, but
269   // the last one is missing. (There's also no value.)
270   const uint8_t der[] = {0x04, 0x81};
271   Parser parser((Input(der)));
272 
273   CBS_ASN1_TAG tag;
274   Input value;
275   ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
276   ASSERT_TRUE(parser.HasMore());
277 }
278 
TEST(ParserTest,IncompleteEncodingValueShorterThanLength)279 TEST(ParserTest, IncompleteEncodingValueShorterThanLength) {
280   // Tag: octet string; length: 2; value: first octet 'T', second octet missing.
281   const uint8_t der[] = {0x04, 0x02, 0x84};
282   Parser parser((Input(der)));
283 
284   CBS_ASN1_TAG tag;
285   Input value;
286   ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
287   ASSERT_TRUE(parser.HasMore());
288 }
289 
TEST(ParserTest,LengthMustBeEncodedWithMinimumNumberOfOctets)290 TEST(ParserTest, LengthMustBeEncodedWithMinimumNumberOfOctets) {
291   const uint8_t der[] = {0x01, 0x81, 0x01, 0x00};
292   Parser parser((Input(der)));
293 
294   CBS_ASN1_TAG tag;
295   Input value;
296   ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
297   ASSERT_TRUE(parser.HasMore());
298 }
299 
TEST(ParserTest,LengthMustNotHaveLeadingZeroes)300 TEST(ParserTest, LengthMustNotHaveLeadingZeroes) {
301   // Tag: octet string; length: 3 bytes of length encoding a value of 128
302   // (it should be encoded in only 2 bytes). Value: 128 bytes of 0.
303   const uint8_t der[] = {
304       0x04, 0x83, 0x80, 0x81, 0x80,  // group the 0s separately
305       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
316   Parser parser((Input(der)));
317 
318   CBS_ASN1_TAG tag;
319   Input value;
320   ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
321   ASSERT_TRUE(parser.HasMore());
322 }
323 
TEST(ParserTest,ReadConstructedFailsForNonConstructedTags)324 TEST(ParserTest, ReadConstructedFailsForNonConstructedTags) {
325   // Tag number is for SEQUENCE, but the constructed bit isn't set.
326   const uint8_t der[] = {0x10, 0x00};
327   Parser parser((Input(der)));
328 
329   CBS_ASN1_TAG expected_tag = 0x10;
330   Parser sequence_parser;
331   ASSERT_FALSE(parser.ReadConstructed(expected_tag, &sequence_parser));
332 
333   // Check that we didn't fail above because of a tag mismatch or an improperly
334   // encoded TLV.
335   Input value;
336   ASSERT_TRUE(parser.ReadTag(expected_tag, &value));
337   ASSERT_FALSE(parser.HasMore());
338 }
339 
TEST(ParserTest,CannotAdvanceAfterReadOptionalTag)340 TEST(ParserTest, CannotAdvanceAfterReadOptionalTag) {
341   const uint8_t der[] = {0x02, 0x01, 0x01};
342   Parser parser((Input(der)));
343 
344   Input value;
345   bool present;
346   ASSERT_TRUE(parser.ReadOptionalTag(0x04, &value, &present));
347   ASSERT_FALSE(present);
348   ASSERT_FALSE(parser.Advance());
349 }
350 
351 // Reads a valid BIT STRING with 1 unused bit.
TEST(ParserTest,ReadBitString)352 TEST(ParserTest, ReadBitString) {
353   const uint8_t der[] = {0x03, 0x03, 0x01, 0xAA, 0xBE};
354   Parser parser((Input(der)));
355 
356   std::optional<BitString> bit_string = parser.ReadBitString();
357   ASSERT_TRUE(bit_string.has_value());
358   EXPECT_FALSE(parser.HasMore());
359 
360   EXPECT_EQ(1u, bit_string->unused_bits());
361   ASSERT_EQ(2u, bit_string->bytes().size());
362   EXPECT_EQ(0xAA, bit_string->bytes()[0]);
363   EXPECT_EQ(0xBE, bit_string->bytes()[1]);
364 }
365 
366 // Tries reading a BIT STRING. This should fail because the tag is not for a
367 // BIT STRING.
TEST(ParserTest,ReadBitStringBadTag)368 TEST(ParserTest, ReadBitStringBadTag) {
369   const uint8_t der[] = {0x05, 0x03, 0x01, 0xAA, 0xBE};
370   Parser parser((Input(der)));
371 
372   std::optional<BitString> bit_string = parser.ReadBitString();
373   EXPECT_FALSE(bit_string.has_value());
374 }
375 
376 }  // namespace der::test
377 BSSL_NAMESPACE_END
378