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