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