xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/pki/parser_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 namespace bssl::der::test {
12 
TEST(ParserTest,ConsumesAllBytesOfTLV)13 TEST(ParserTest, ConsumesAllBytesOfTLV) {
14   const uint8_t der[] = {0x04 /* OCTET STRING */, 0x00};
15   Parser parser((Input(der)));
16   CBS_ASN1_TAG tag;
17   Input value;
18   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
19   ASSERT_EQ(CBS_ASN1_OCTETSTRING, tag);
20   ASSERT_FALSE(parser.HasMore());
21 }
22 
TEST(ParserTest,CanReadRawTLV)23 TEST(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 
TEST(ParserTest,IgnoresContentsOfInnerValues)36 TEST(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   CBS_ASN1_TAG tag;
42   Input value;
43   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
44 }
45 
TEST(ParserTest,FailsIfLengthOverlapsAnotherTLV)46 TEST(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   CBS_ASN1_TAG tag;
62   Input value;
63   ASSERT_FALSE(inner_sequence.ReadTagAndValue(&tag, &value));
64 }
65 
TEST(ParserTest,ReadOptionalTagPresent)66 TEST(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(CBS_ASN1_INTEGER, &value, &present));
76   ASSERT_TRUE(present);
77   const uint8_t expected_int_value[] = {0x01};
78   ASSERT_EQ(Input(expected_int_value), value);
79 
80   CBS_ASN1_TAG tag;
81   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
82   ASSERT_EQ(CBS_ASN1_OCTETSTRING, 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 
TEST(ParserTest,ReadOptionalTag2Present)89 TEST(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(CBS_ASN1_INTEGER, &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   CBS_ASN1_TAG tag;
103   Input value;
104   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
105   ASSERT_EQ(CBS_ASN1_OCTETSTRING, 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 
TEST(ParserTest,ReadOptionalTagNotPresent)112 TEST(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(CBS_ASN1_INTEGER, &value, &present));
121   ASSERT_FALSE(present);
122 
123   CBS_ASN1_TAG tag;
124   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
125   ASSERT_EQ(CBS_ASN1_OCTETSTRING, 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 
TEST(ParserTest,ReadOptionalTag2NotPresent)132 TEST(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(CBS_ASN1_INTEGER, &optional_value));
140   ASSERT_FALSE(optional_value.has_value());
141 
142   CBS_ASN1_TAG tag;
143   Input value;
144   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
145   ASSERT_EQ(CBS_ASN1_OCTETSTRING, 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 
TEST(ParserTest,CanSkipOptionalTagAtEndOfInput)152 TEST(ParserTest, CanSkipOptionalTagAtEndOfInput) {
153   const uint8_t der[] = {0x02 /* INTEGER */, 0x01, 0x01};
154   Parser parser((Input(der)));
155 
156   CBS_ASN1_TAG tag;
157   Input value;
158   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
159   bool present;
160   ASSERT_TRUE(parser.ReadOptionalTag(CBS_ASN1_INTEGER, &value, &present));
161   ASSERT_FALSE(present);
162   ASSERT_FALSE(parser.HasMore());
163 }
164 
TEST(ParserTest,SkipOptionalTagDoesntConsumePresentNonMatchingTLVs)165 TEST(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(CBS_ASN1_OCTETSTRING, &present));
171   ASSERT_FALSE(present);
172   ASSERT_TRUE(parser.SkipOptionalTag(CBS_ASN1_INTEGER, &present));
173   ASSERT_TRUE(present);
174   ASSERT_FALSE(parser.HasMore());
175 }
176 
TEST(ParserTest,TagNumbersAboveThirtySupported)177 TEST(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   CBS_ASN1_TAG tag;
183   Input value;
184   ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
185   EXPECT_EQ(CBS_ASN1_CONTEXT_SPECIFIC | 31u, tag);
186   ASSERT_FALSE(parser.HasMore());
187 }
188 
TEST(ParserTest,ParseTags)189 TEST(ParserTest, ParseTags) {
190   {
191     // Universal primitive tag, tag number 4.
192     const uint8_t der[] = {0x04, 0x00};
193     Parser parser((Input(der)));
194 
195     CBS_ASN1_TAG tag;
196     Input value;
197     ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
198     EXPECT_EQ(CBS_ASN1_OCTETSTRING, 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     CBS_ASN1_TAG tag;
207     Input value;
208     ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
209     EXPECT_EQ(CBS_ASN1_SEQUENCE, 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     CBS_ASN1_TAG tag;
218     Input value;
219     ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
220     EXPECT_EQ(CBS_ASN1_APPLICATION | 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     CBS_ASN1_TAG tag;
229     Input value;
230     ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
231     EXPECT_EQ(CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 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     CBS_ASN1_TAG tag;
240     Input value;
241     ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
242     EXPECT_EQ(CBS_ASN1_PRIVATE | 15, tag);
243   }
244 }
245 
TEST(ParserTest,IncompleteEncodingTagOnly)246 TEST(ParserTest, IncompleteEncodingTagOnly) {
247   const uint8_t der[] = {0x01};
248   Parser parser((Input(der)));
249 
250   CBS_ASN1_TAG tag;
251   Input value;
252   ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
253   ASSERT_TRUE(parser.HasMore());
254 }
255 
TEST(ParserTest,IncompleteEncodingLengthTruncated)256 TEST(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   CBS_ASN1_TAG tag;
263   Input value;
264   ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
265   ASSERT_TRUE(parser.HasMore());
266 }
267 
TEST(ParserTest,IncompleteEncodingValueShorterThanLength)268 TEST(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   CBS_ASN1_TAG tag;
274   Input value;
275   ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
276   ASSERT_TRUE(parser.HasMore());
277 }
278 
TEST(ParserTest,LengthMustBeEncodedWithMinimumNumberOfOctets)279 TEST(ParserTest, LengthMustBeEncodedWithMinimumNumberOfOctets) {
280   const uint8_t der[] = {0x01, 0x81, 0x01, 0x00};
281   Parser parser((Input(der)));
282 
283   CBS_ASN1_TAG tag;
284   Input value;
285   ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
286   ASSERT_TRUE(parser.HasMore());
287 }
288 
TEST(ParserTest,LengthMustNotHaveLeadingZeroes)289 TEST(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   CBS_ASN1_TAG tag;
308   Input value;
309   ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
310   ASSERT_TRUE(parser.HasMore());
311 }
312 
TEST(ParserTest,ReadConstructedFailsForNonConstructedTags)313 TEST(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   CBS_ASN1_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 
TEST(ParserTest,CannotAdvanceAfterReadOptionalTag)329 TEST(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.
TEST(ParserTest,ReadBitString)341 TEST(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());
350   ASSERT_EQ(2u, bit_string->bytes().size());
351   EXPECT_EQ(0xAA, bit_string->bytes()[0]);
352   EXPECT_EQ(0xBE, bit_string->bytes()[1]);
353 }
354 
355 // Tries reading a BIT STRING. This should fail because the tag is not for a
356 // BIT STRING.
TEST(ParserTest,ReadBitStringBadTag)357 TEST(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
366