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