1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/logging.h"
6 #include "base/numerics/safe_math.h"
7 #include "net/der/input.h"
8 #include "net/der/parse_values.h"
9 #include "net/der/parser.h"
10 #include "testing/gtest/include/gtest/gtest.h"
16 TEST(ParserTest
, ConsumesAllBytesOfTLV
) {
17 const uint8_t der
[] = {0x04, 0x00};
18 Parser
parser(Input(der
, sizeof(der
)));
21 ASSERT_TRUE(parser
.ReadTagAndValue(&tag
, &value
));
23 ASSERT_FALSE(parser
.HasMore());
26 TEST(ParserTest
, CanReadRawTLV
) {
27 const uint8_t der
[] = {0x02, 0x01, 0x01};
28 Parser
parser(Input(der
, sizeof(der
)));
30 ASSERT_TRUE(parser
.ReadRawTLV(&tlv
));
31 ByteReader
tlv_reader(tlv
);
32 size_t tlv_len
= tlv_reader
.BytesLeft();
33 ASSERT_EQ(3u, tlv_len
);
35 ASSERT_TRUE(tlv_reader
.ReadBytes(tlv_len
, &tlv_data
));
36 ASSERT_FALSE(parser
.HasMore());
39 TEST(ParserTest
, IgnoresContentsOfInnerValues
) {
40 // This is a SEQUENCE which has one member. The member is another SEQUENCE
41 // with an invalid encoding - its length is too long.
42 const uint8_t der
[] = {0x30, 0x02, 0x30, 0x7e};
43 Parser
parser(Input(der
, sizeof(der
)));
46 ASSERT_TRUE(parser
.ReadTagAndValue(&tag
, &value
));
49 TEST(ParserTest
, FailsIfLengthOverlapsAnotherTLV
) {
50 // This DER encoding has 2 top-level TLV tuples. The first is a SEQUENCE;
51 // the second is an INTEGER. The SEQUENCE contains an INTEGER, but its length
52 // is longer than what it has contents for.
53 const uint8_t der
[] = {0x30, 0x02, 0x02, 0x01, 0x02, 0x01, 0x01};
54 Parser
parser(Input(der
, sizeof(der
)));
56 Parser inner_sequence
;
57 ASSERT_TRUE(parser
.ReadSequence(&inner_sequence
));
59 ASSERT_TRUE(parser
.ReadUint64(&int_value
));
60 ASSERT_EQ(1u, int_value
);
61 ASSERT_FALSE(parser
.HasMore());
63 // Try to read the INTEGER from the SEQUENCE, which should fail.
66 ASSERT_FALSE(inner_sequence
.ReadTagAndValue(&tag
, &value
));
69 TEST(ParserTest
, CanSkipOptionalTagAtEndOfInput
) {
70 const uint8_t der
[] = {0x02, 0x01, 0x01};
71 Parser
parser(Input(der
, sizeof(der
)));
75 ASSERT_TRUE(parser
.ReadTagAndValue(&tag
, &value
));
77 ASSERT_TRUE(parser
.ReadOptionalTag(0x02, &value
, &present
));
78 ASSERT_FALSE(present
);
79 ASSERT_FALSE(parser
.HasMore());
82 TEST(ParserTest
, SkipOptionalTagDoesntConsumePresentNonMatchingTLVs
) {
83 const uint8_t der
[] = {0x02, 0x01, 0x01};
84 Parser
parser(Input(der
, sizeof(der
)));
87 ASSERT_TRUE(parser
.SkipOptionalTag(0x04, &present
));
88 ASSERT_FALSE(present
);
89 ASSERT_TRUE(parser
.SkipOptionalTag(0x02, &present
));
91 ASSERT_FALSE(parser
.HasMore());
94 TEST(ParserTest
, TagNumbersAboveThirtyUnsupported
) {
95 // Context-specific class, tag number 31, length 0.
96 const uint8_t der
[] = {0x9f, 0x1f, 0x00};
97 Parser
parser(Input(der
, sizeof(der
)));
101 ASSERT_FALSE(parser
.ReadTagAndValue(&tag
, &value
));
102 ASSERT_TRUE(parser
.HasMore());
105 TEST(ParserTest
, IncompleteEncodingTagOnly
) {
106 const uint8_t der
[] = {0x01};
107 Parser
parser(Input(der
, sizeof(der
)));
111 ASSERT_FALSE(parser
.ReadTagAndValue(&tag
, &value
));
112 ASSERT_TRUE(parser
.HasMore());
115 TEST(ParserTest
, IncompleteEncodingLengthTruncated
) {
116 // Tag: octet string; length: long form, should have 2 total octets, but
117 // the last one is missing. (There's also no value.)
118 const uint8_t der
[] = {0x04, 0x81};
119 Parser
parser(Input(der
, sizeof(der
)));
123 ASSERT_FALSE(parser
.ReadTagAndValue(&tag
, &value
));
124 ASSERT_TRUE(parser
.HasMore());
127 TEST(ParserTest
, IncompleteEncodingValueShorterThanLength
) {
128 // Tag: octet string; length: 2; value: first octet 'T', second octet missing.
129 const uint8_t der
[] = {0x04, 0x02, 0x84};
130 Parser
parser(Input(der
, sizeof(der
)));
134 ASSERT_FALSE(parser
.ReadTagAndValue(&tag
, &value
));
135 ASSERT_TRUE(parser
.HasMore());
138 TEST(ParserTest
, LengthMustBeEncodedWithMinimumNumberOfOctets
) {
139 const uint8_t der
[] = {0x01, 0x81, 0x01, 0x00};
140 Parser
parser(Input(der
, sizeof(der
)));
144 ASSERT_FALSE(parser
.ReadTagAndValue(&tag
, &value
));
145 ASSERT_TRUE(parser
.HasMore());
148 TEST(ParserTest
, LengthMustNotHaveLeadingZeroes
) {
149 // Tag: octet string; length: 3 bytes of length encoding a value of 128
150 // (it should be encoded in only 2 bytes). Value: 128 bytes of 0.
151 const uint8_t der
[] = {
152 0x04, 0x83, 0x80, 0x81, 0x80, // group the 0s separately
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
164 Parser
parser(Input(der
, sizeof(der
)));
168 ASSERT_FALSE(parser
.ReadTagAndValue(&tag
, &value
));
169 ASSERT_TRUE(parser
.HasMore());
172 TEST(ParserTest
, ReadConstructedFailsForNonConstructedTags
) {
173 // Tag number is for SEQUENCE, but the constructed bit isn't set.
174 const uint8_t der
[] = {0x10, 0x00};
175 Parser
parser(Input(der
, sizeof(der
)));
177 Tag expected_tag
= 0x10;
178 Parser sequence_parser
;
179 ASSERT_FALSE(parser
.ReadConstructed(expected_tag
, &sequence_parser
));
181 // Check that we didn't fail above because of a tag mismatch or an improperly
184 ASSERT_TRUE(parser
.ReadTag(expected_tag
, &value
));
185 ASSERT_FALSE(parser
.HasMore());
188 TEST(ParserTest
, CannotAdvanceAfterReadOptionalTag
) {
189 const uint8_t der
[] = {0x02, 0x01, 0x01};
190 Parser
parser(Input(der
, sizeof(der
)));
194 ASSERT_TRUE(parser
.ReadOptionalTag(0x04, &value
, &present
));
195 ASSERT_FALSE(present
);
196 ASSERT_FALSE(parser
.Advance());