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