1 // Copyright 2016 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 "parse_name.h"
6
7 #include "test_helpers.h"
8 #include <gtest/gtest.h>
9
10 namespace bssl {
11
12 namespace {
13 // Loads test data from file. The filename is constructed from the parameters:
14 // |prefix| describes the type of data being tested, e.g. "ascii",
15 // "unicode_bmp", "unicode_supplementary", and "invalid".
16 // |value_type| indicates what ASN.1 type is used to encode the data.
17 // |suffix| indicates any additional modifications, such as caseswapping,
18 // whitespace adding, etc.
LoadTestData(const std::string & prefix,const std::string & value_type,const std::string & suffix,std::string * result)19 ::testing::AssertionResult LoadTestData(const std::string& prefix,
20 const std::string& value_type,
21 const std::string& suffix,
22 std::string* result) {
23 std::string path = "testdata/verify_name_match_unittest/names/" + prefix +
24 "-" + value_type + "-" + suffix + ".pem";
25
26 const PemBlockMapping mappings[] = {
27 {"NAME", result},
28 };
29
30 return ReadTestDataFromPemFile(path, mappings);
31 }
32
33 } // anonymous namespace
34
TEST(ParseNameTest,IA5SafeStringValue)35 TEST(ParseNameTest, IA5SafeStringValue) {
36 const uint8_t der[] = {
37 0x46, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72,
38 };
39 X509NameAttribute value(der::Input(), der::kIA5String, der::Input(der));
40 std::string result_unsafe;
41 ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe));
42 ASSERT_EQ("Foo bar", result_unsafe);
43 std::string result;
44 ASSERT_TRUE(value.ValueAsString(&result));
45 ASSERT_EQ("Foo bar", result);
46 }
47
TEST(ParseNameTest,IA5UnsafeStringValue)48 TEST(ParseNameTest, IA5UnsafeStringValue) {
49 const uint8_t der[] = {
50 0x46, 0x6f, 0xFF, 0x20, 0x62, 0x61, 0x72,
51 };
52 X509NameAttribute value(der::Input(), der::kIA5String, der::Input(der));
53 std::string result_unsafe;
54 ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe));
55 ASSERT_EQ("Fo\377 bar", result_unsafe);
56 std::string result;
57 ASSERT_FALSE(value.ValueAsString(&result));
58 }
59
TEST(ParseNameTest,PrintableSafeStringValue)60 TEST(ParseNameTest, PrintableSafeStringValue) {
61 const uint8_t der[] = {
62 0x46, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72,
63 };
64 X509NameAttribute value(der::Input(), der::kPrintableString, der::Input(der));
65 std::string result_unsafe;
66 ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe));
67 ASSERT_EQ("Foo bar", result_unsafe);
68 std::string result;
69 ASSERT_TRUE(value.ValueAsString(&result));
70 ASSERT_EQ("Foo bar", result);
71 }
72
TEST(ParseNameTest,PrintableUnsafeStringValue)73 TEST(ParseNameTest, PrintableUnsafeStringValue) {
74 const uint8_t der[] = {
75 0x46, 0x6f, 0x5f, 0x20, 0x62, 0x61, 0x72,
76 };
77 X509NameAttribute value(der::Input(), der::kPrintableString, der::Input(der));
78 std::string result_unsafe;
79 ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe));
80 ASSERT_EQ("Fo_ bar", result_unsafe);
81 std::string result;
82 ASSERT_FALSE(value.ValueAsString(&result));
83 }
84
TEST(ParseNameTest,PrintableStringUnsafeOptions)85 TEST(ParseNameTest, PrintableStringUnsafeOptions) {
86 const uint8_t der[] = {
87 0x46, 0x6f, 0x5f, 0x20, 0x62, 0x61, 0x72,
88 };
89 X509NameAttribute value(der::Input(), der::kPrintableString, der::Input(der));
90 std::string result;
91 ASSERT_FALSE(value.ValueAsStringWithUnsafeOptions(
92 X509NameAttribute::PrintableStringHandling::kDefault, &result));
93 ASSERT_TRUE(value.ValueAsStringWithUnsafeOptions(
94 X509NameAttribute::PrintableStringHandling::kAsUTF8Hack, &result));
95 ASSERT_EQ("Fo_ bar", result);
96 }
97
TEST(ParseNameTest,TeletexSafeStringValue)98 TEST(ParseNameTest, TeletexSafeStringValue) {
99 const uint8_t der[] = {
100 0x46, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72,
101 };
102 X509NameAttribute value(der::Input(), der::kTeletexString, der::Input(der));
103 std::string result_unsafe;
104 ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe));
105 ASSERT_EQ("Foo bar", result_unsafe);
106 std::string result;
107 ASSERT_TRUE(value.ValueAsString(&result));
108 ASSERT_EQ("Foo bar", result);
109 }
110
TEST(ParseNameTest,TeletexLatin1StringValue)111 TEST(ParseNameTest, TeletexLatin1StringValue) {
112 const uint8_t der[] = {
113 0x46, 0x6f, 0xd6, 0x20, 0x62, 0x61, 0x72,
114 };
115 X509NameAttribute value(der::Input(), der::kTeletexString, der::Input(der));
116 std::string result_unsafe;
117 ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe));
118 ASSERT_EQ("Fo\xd6 bar", result_unsafe);
119 std::string result;
120 ASSERT_TRUE(value.ValueAsString(&result));
121 ASSERT_EQ("FoÖ bar", result);
122 }
123
TEST(ParseNameTest,ConvertBmpString)124 TEST(ParseNameTest, ConvertBmpString) {
125 const uint8_t der[] = {
126 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x61, 0x00, 0x72,
127 };
128 X509NameAttribute value(der::Input(), der::kBmpString, der::Input(der));
129 std::string result_unsafe;
130 ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe));
131 ASSERT_EQ("foobar", result_unsafe);
132 std::string result;
133 ASSERT_TRUE(value.ValueAsString(&result));
134 ASSERT_EQ("foobar", result);
135 }
136
137 // BmpString must encode characters in pairs of 2 bytes.
TEST(ParseNameTest,ConvertInvalidBmpString)138 TEST(ParseNameTest, ConvertInvalidBmpString) {
139 const uint8_t der[] = {0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x72};
140 X509NameAttribute value(der::Input(), der::kBmpString, der::Input(der));
141 std::string result;
142 ASSERT_FALSE(value.ValueAsStringUnsafe(&result));
143 ASSERT_FALSE(value.ValueAsString(&result));
144 }
145
TEST(ParseNameTest,ConvertUniversalString)146 TEST(ParseNameTest, ConvertUniversalString) {
147 const uint8_t der[] = {0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x6f,
148 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x62,
149 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x72};
150 X509NameAttribute value(der::Input(), der::kUniversalString, der::Input(der));
151 std::string result_unsafe;
152 ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe));
153 ASSERT_EQ("foobar", result_unsafe);
154 std::string result;
155 ASSERT_TRUE(value.ValueAsString(&result));
156 ASSERT_EQ("foobar", result);
157 }
158
159 // UniversalString must encode characters in pairs of 4 bytes.
TEST(ParseNameTest,ConvertInvalidUniversalString)160 TEST(ParseNameTest, ConvertInvalidUniversalString) {
161 const uint8_t der[] = {0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72};
162 X509NameAttribute value(der::Input(), der::kUniversalString, der::Input(der));
163 std::string result;
164 ASSERT_FALSE(value.ValueAsStringUnsafe(&result));
165 ASSERT_FALSE(value.ValueAsString(&result));
166 }
167
TEST(ParseNameTest,EmptyName)168 TEST(ParseNameTest, EmptyName) {
169 const uint8_t der[] = {0x30, 0x00};
170 der::Input rdn(der);
171 RDNSequence atv;
172 ASSERT_TRUE(ParseName(rdn, &atv));
173 ASSERT_EQ(0u, atv.size());
174 }
175
TEST(ParseNameTest,ValidName)176 TEST(ParseNameTest, ValidName) {
177 const uint8_t der[] = {0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
178 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30,
179 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x47,
180 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63,
181 0x2e, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
182 0x03, 0x13, 0x0e, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
183 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41};
184 der::Input rdn(der);
185 RDNSequence atv;
186 ASSERT_TRUE(ParseName(rdn, &atv));
187 ASSERT_EQ(3u, atv.size());
188 ASSERT_EQ(1u, atv[0].size());
189 ASSERT_EQ(der::Input(kTypeCountryNameOid), atv[0][0].type);
190 ASSERT_EQ("US", atv[0][0].value.AsString());
191 ASSERT_EQ(1u, atv[1].size());
192 ASSERT_EQ(der::Input(kTypeOrganizationNameOid), atv[1][0].type);
193 ASSERT_EQ("Google Inc.", atv[1][0].value.AsString());
194 ASSERT_EQ(1u, atv[2].size());
195 ASSERT_EQ(der::Input(kTypeCommonNameOid), atv[2][0].type);
196 ASSERT_EQ("Google Test CA", atv[2][0].value.AsString());
197 }
198
TEST(ParseNameTest,InvalidNameExtraData)199 TEST(ParseNameTest, InvalidNameExtraData) {
200 std::string invalid;
201 ASSERT_TRUE(
202 LoadTestData("invalid", "AttributeTypeAndValue", "extradata", &invalid));
203 RDNSequence atv;
204 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
205 }
206
TEST(ParseNameTest,InvalidNameEmpty)207 TEST(ParseNameTest, InvalidNameEmpty) {
208 std::string invalid;
209 ASSERT_TRUE(
210 LoadTestData("invalid", "AttributeTypeAndValue", "empty", &invalid));
211 RDNSequence atv;
212 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
213 }
214
TEST(ParseNameTest,InvalidNameBadType)215 TEST(ParseNameTest, InvalidNameBadType) {
216 std::string invalid;
217 ASSERT_TRUE(LoadTestData("invalid", "AttributeTypeAndValue",
218 "badAttributeType", &invalid));
219 RDNSequence atv;
220 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
221 }
222
TEST(ParseNameTest,InvalidNameNotSequence)223 TEST(ParseNameTest, InvalidNameNotSequence) {
224 std::string invalid;
225 ASSERT_TRUE(LoadTestData("invalid", "AttributeTypeAndValue", "setNotSequence",
226 &invalid));
227 RDNSequence atv;
228 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
229 }
230
TEST(ParseNameTest,InvalidNameNotSet)231 TEST(ParseNameTest, InvalidNameNotSet) {
232 std::string invalid;
233 ASSERT_TRUE(LoadTestData("invalid", "RDN", "sequenceInsteadOfSet", &invalid));
234 RDNSequence atv;
235 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
236 }
237
TEST(ParseNameTest,InvalidNameEmptyRdn)238 TEST(ParseNameTest, InvalidNameEmptyRdn) {
239 std::string invalid;
240 ASSERT_TRUE(LoadTestData("invalid", "RDN", "empty", &invalid));
241 RDNSequence atv;
242 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
243 }
244
TEST(ParseNameTest,RFC2253FormatBasic)245 TEST(ParseNameTest, RFC2253FormatBasic) {
246 const uint8_t der[] = {0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
247 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x16, 0x30,
248 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x49,
249 0x73, 0x6f, 0x64, 0x65, 0x20, 0x4c, 0x69, 0x6d, 0x69,
250 0x74, 0x65, 0x64, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03,
251 0x55, 0x04, 0x03, 0x13, 0x0b, 0x53, 0x74, 0x65, 0x76,
252 0x65, 0x20, 0x4b, 0x69, 0x6c, 0x6c, 0x65};
253 der::Input rdn_input(der);
254 RDNSequence rdn;
255 ASSERT_TRUE(ParseName(rdn_input, &rdn));
256 std::string output;
257 ASSERT_TRUE(ConvertToRFC2253(rdn, &output));
258 ASSERT_EQ("CN=Steve Kille,O=Isode Limited,C=GB", output);
259 }
260
TEST(ParseNameTest,RFC2253FormatMultiRDN)261 TEST(ParseNameTest, RFC2253FormatMultiRDN) {
262 const uint8_t der[] = {
263 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
264 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a,
265 0x13, 0x0b, 0x57, 0x69, 0x64, 0x67, 0x65, 0x74, 0x20, 0x49, 0x6e, 0x63,
266 0x2e, 0x31, 0x1f, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x05,
267 0x53, 0x61, 0x6c, 0x65, 0x73, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03,
268 0x13, 0x08, 0x4a, 0x2e, 0x20, 0x53, 0x6d, 0x69, 0x74, 0x68};
269 der::Input rdn_input(der);
270 RDNSequence rdn;
271 ASSERT_TRUE(ParseName(rdn_input, &rdn));
272 std::string output;
273 ASSERT_TRUE(ConvertToRFC2253(rdn, &output));
274 ASSERT_EQ("OU=Sales+CN=J. Smith,O=Widget Inc.,C=US", output);
275 }
276
TEST(ParseNameTest,RFC2253FormatQuoted)277 TEST(ParseNameTest, RFC2253FormatQuoted) {
278 const uint8_t der[] = {
279 0x30, 0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
280 0x13, 0x02, 0x47, 0x42, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
281 0x04, 0x0a, 0x13, 0x15, 0x53, 0x75, 0x65, 0x2c, 0x20, 0x47, 0x72,
282 0x61, 0x62, 0x62, 0x69, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x52,
283 0x75, 0x6e, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04,
284 0x03, 0x13, 0x08, 0x4c, 0x2e, 0x20, 0x45, 0x61, 0x67, 0x6c, 0x65};
285 der::Input rdn_input(der);
286 RDNSequence rdn;
287 ASSERT_TRUE(ParseName(rdn_input, &rdn));
288 std::string output;
289 ASSERT_TRUE(ConvertToRFC2253(rdn, &output));
290 ASSERT_EQ("CN=L. Eagle,O=Sue\\, Grabbit and Runn,C=GB", output);
291 }
292
TEST(ParseNameTest,RFC2253FormatNonPrintable)293 TEST(ParseNameTest, RFC2253FormatNonPrintable) {
294 const uint8_t der[] = {0x30, 0x33, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
295 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x0d, 0x30,
296 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x04, 0x54,
297 0x65, 0x73, 0x74, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03,
298 0x55, 0x04, 0x03, 0x13, 0x0c, 0x42, 0x65, 0x66, 0x6f,
299 0x72, 0x65, 0x0d, 0x41, 0x66, 0x74, 0x65, 0x72};
300 der::Input rdn_input(der);
301 RDNSequence rdn;
302 ASSERT_TRUE(ParseName(rdn_input, &rdn));
303 std::string output;
304 ASSERT_TRUE(ConvertToRFC2253(rdn, &output));
305 ASSERT_EQ("CN=Before\\0DAfter,O=Test,C=GB", output);
306 }
307
TEST(ParseNameTest,RFC2253FormatUnknownOid)308 TEST(ParseNameTest, RFC2253FormatUnknownOid) {
309 const uint8_t der[] = {0x30, 0x30, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
310 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x0d, 0x30,
311 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x04, 0x54,
312 0x65, 0x73, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x08,
313 0x2b, 0x06, 0x01, 0x04, 0x01, 0x8b, 0x3a, 0x00, 0x13,
314 0x04, 0x04, 0x02, 0x48, 0x69};
315 der::Input rdn_input(der);
316 RDNSequence rdn;
317 ASSERT_TRUE(ParseName(rdn_input, &rdn));
318 std::string output;
319 ASSERT_TRUE(ConvertToRFC2253(rdn, &output));
320 ASSERT_EQ("1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB", output);
321 }
322
TEST(ParseNameTest,RFC2253FormatLargeOid)323 TEST(ParseNameTest, RFC2253FormatLargeOid) {
324 const uint8_t der[] = {0x30, 0x16, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a,
325 0x81, 0x0d, 0x06, 0x01, 0x99, 0x21, 0x01, 0x8b,
326 0x3a, 0x00, 0x13, 0x04, 0x74, 0x65, 0x73, 0x74};
327 der::Input rdn_input(der);
328 RDNSequence rdn;
329 ASSERT_TRUE(ParseName(rdn_input, &rdn));
330 std::string output;
331 ASSERT_TRUE(ConvertToRFC2253(rdn, &output));
332 ASSERT_EQ("2.61.6.1.3233.1.1466.0=#74657374", output);
333 }
334
TEST(ParseNameTest,RFC2253FormatInvalidOid)335 TEST(ParseNameTest, RFC2253FormatInvalidOid) {
336 // Same DER as RFC2253FormatLargeOid but with the last byte of the OID
337 // replaced with 0x80, which ends the OID with a truncated multi-byte
338 // component.
339 const uint8_t der[] = {0x30, 0x16, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a,
340 0x81, 0x0d, 0x06, 0x01, 0x99, 0x21, 0x01, 0x8b,
341 0x3a, 0x80, 0x13, 0x04, 0x74, 0x65, 0x73, 0x74};
342 der::Input rdn_input(der);
343 RDNSequence rdn;
344 ASSERT_TRUE(ParseName(rdn_input, &rdn));
345 std::string output;
346 EXPECT_FALSE(ConvertToRFC2253(rdn, &output));
347 }
348
TEST(ParseNameTest,RFC2253FormatUTF8)349 TEST(ParseNameTest, RFC2253FormatUTF8) {
350 const uint8_t der[] = {0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06,
351 0x03, 0x55, 0x04, 0x04, 0x13, 0x07, 0x4c,
352 0x75, 0xc4, 0x8d, 0x69, 0xc4, 0x87};
353 der::Input rdn_input(der);
354 RDNSequence rdn;
355 ASSERT_TRUE(ParseName(rdn_input, &rdn));
356 std::string output;
357 ASSERT_TRUE(ConvertToRFC2253(rdn, &output));
358 ASSERT_EQ("SN=Lu\\C4\\8Di\\C4\\87", output);
359 }
360
361 } // namespace net
362