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