blob: 0bb2c6f7bfb77d894c3045a5314fbb7c0f73a315 [file] [log] [blame]
Bob Beckbc97b7a2023-04-18 08:35:15 -06001// 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
Bob Beckbc97b7a2023-04-18 08:35:15 -06007#include <gtest/gtest.h>
Bob Beck5c7a2a02023-11-20 17:28:21 -07008#include "test_helpers.h"
Bob Beckbc97b7a2023-04-18 08:35:15 -06009
David Benjamin0fbc17a2024-08-21 15:13:10 -040010BSSL_NAMESPACE_BEGIN
Bob Beckbc97b7a2023-04-18 08:35:15 -060011
12namespace {
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.
Bob Beck5c7a2a02023-11-20 17:28:21 -070019::testing::AssertionResult LoadTestData(const std::string &prefix,
20 const std::string &value_type,
21 const std::string &suffix,
22 std::string *result) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060023 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
35TEST(ParseNameTest, IA5SafeStringValue) {
36 const uint8_t der[] = {
37 0x46, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72,
38 };
David Benjamin2a5db682024-02-06 21:56:57 -050039 X509NameAttribute value(der::Input(), CBS_ASN1_IA5STRING, der::Input(der));
Bob Beckbc97b7a2023-04-18 08:35:15 -060040 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
48TEST(ParseNameTest, IA5UnsafeStringValue) {
49 const uint8_t der[] = {
50 0x46, 0x6f, 0xFF, 0x20, 0x62, 0x61, 0x72,
51 };
David Benjamin2a5db682024-02-06 21:56:57 -050052 X509NameAttribute value(der::Input(), CBS_ASN1_IA5STRING, der::Input(der));
Bob Beckbc97b7a2023-04-18 08:35:15 -060053 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
60TEST(ParseNameTest, PrintableSafeStringValue) {
61 const uint8_t der[] = {
62 0x46, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72,
63 };
David Benjamin2a5db682024-02-06 21:56:57 -050064 X509NameAttribute value(der::Input(), CBS_ASN1_PRINTABLESTRING,
65 der::Input(der));
Bob Beckbc97b7a2023-04-18 08:35:15 -060066 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
74TEST(ParseNameTest, PrintableUnsafeStringValue) {
75 const uint8_t der[] = {
76 0x46, 0x6f, 0x5f, 0x20, 0x62, 0x61, 0x72,
77 };
David Benjamin2a5db682024-02-06 21:56:57 -050078 X509NameAttribute value(der::Input(), CBS_ASN1_PRINTABLESTRING,
79 der::Input(der));
Bob Beckbc97b7a2023-04-18 08:35:15 -060080 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
87TEST(ParseNameTest, PrintableStringUnsafeOptions) {
88 const uint8_t der[] = {
89 0x46, 0x6f, 0x5f, 0x20, 0x62, 0x61, 0x72,
90 };
David Benjamin2a5db682024-02-06 21:56:57 -050091 X509NameAttribute value(der::Input(), CBS_ASN1_PRINTABLESTRING,
92 der::Input(der));
Bob Beckbc97b7a2023-04-18 08:35:15 -060093 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
101TEST(ParseNameTest, TeletexSafeStringValue) {
102 const uint8_t der[] = {
103 0x46, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72,
104 };
David Benjamin2a5db682024-02-06 21:56:57 -0500105 X509NameAttribute value(der::Input(), CBS_ASN1_T61STRING, der::Input(der));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600106 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
114TEST(ParseNameTest, TeletexLatin1StringValue) {
115 const uint8_t der[] = {
116 0x46, 0x6f, 0xd6, 0x20, 0x62, 0x61, 0x72,
117 };
David Benjamin2a5db682024-02-06 21:56:57 -0500118 X509NameAttribute value(der::Input(), CBS_ASN1_T61STRING, der::Input(der));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600119 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
127TEST(ParseNameTest, ConvertBmpString) {
128 const uint8_t der[] = {
129 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x61, 0x00, 0x72,
130 };
David Benjamin2a5db682024-02-06 21:56:57 -0500131 X509NameAttribute value(der::Input(), CBS_ASN1_BMPSTRING, der::Input(der));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600132 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.
141TEST(ParseNameTest, ConvertInvalidBmpString) {
142 const uint8_t der[] = {0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x72};
David Benjamin2a5db682024-02-06 21:56:57 -0500143 X509NameAttribute value(der::Input(), CBS_ASN1_BMPSTRING, der::Input(der));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600144 std::string result;
145 ASSERT_FALSE(value.ValueAsStringUnsafe(&result));
146 ASSERT_FALSE(value.ValueAsString(&result));
147}
148
149TEST(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};
David Benjamin2a5db682024-02-06 21:56:57 -0500153 X509NameAttribute value(der::Input(), CBS_ASN1_UNIVERSALSTRING,
154 der::Input(der));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600155 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.
164TEST(ParseNameTest, ConvertInvalidUniversalString) {
165 const uint8_t der[] = {0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72};
David Benjamin2a5db682024-02-06 21:56:57 -0500166 X509NameAttribute value(der::Input(), CBS_ASN1_UNIVERSALSTRING,
167 der::Input(der));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600168 std::string result;
169 ASSERT_FALSE(value.ValueAsStringUnsafe(&result));
170 ASSERT_FALSE(value.ValueAsString(&result));
171}
172
173TEST(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
181TEST(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);
David Benjamin71c58962024-01-29 22:20:18 -0500195 ASSERT_EQ("US", BytesAsStringView(atv[0][0].value));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600196 ASSERT_EQ(1u, atv[1].size());
197 ASSERT_EQ(der::Input(kTypeOrganizationNameOid), atv[1][0].type);
David Benjamin71c58962024-01-29 22:20:18 -0500198 ASSERT_EQ("Google Inc.", BytesAsStringView(atv[1][0].value));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600199 ASSERT_EQ(1u, atv[2].size());
200 ASSERT_EQ(der::Input(kTypeCommonNameOid), atv[2][0].type);
David Benjamin71c58962024-01-29 22:20:18 -0500201 ASSERT_EQ("Google Test CA", BytesAsStringView(atv[2][0].value));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600202}
203
204TEST(ParseNameTest, InvalidNameExtraData) {
205 std::string invalid;
206 ASSERT_TRUE(
207 LoadTestData("invalid", "AttributeTypeAndValue", "extradata", &invalid));
208 RDNSequence atv;
Bob Beck2e119172023-08-14 11:06:38 -0600209 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600210}
211
212TEST(ParseNameTest, InvalidNameEmpty) {
213 std::string invalid;
214 ASSERT_TRUE(
215 LoadTestData("invalid", "AttributeTypeAndValue", "empty", &invalid));
216 RDNSequence atv;
Bob Beck2e119172023-08-14 11:06:38 -0600217 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600218}
219
220TEST(ParseNameTest, InvalidNameBadType) {
221 std::string invalid;
222 ASSERT_TRUE(LoadTestData("invalid", "AttributeTypeAndValue",
223 "badAttributeType", &invalid));
224 RDNSequence atv;
Bob Beck2e119172023-08-14 11:06:38 -0600225 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600226}
227
228TEST(ParseNameTest, InvalidNameNotSequence) {
229 std::string invalid;
230 ASSERT_TRUE(LoadTestData("invalid", "AttributeTypeAndValue", "setNotSequence",
231 &invalid));
232 RDNSequence atv;
Bob Beck2e119172023-08-14 11:06:38 -0600233 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600234}
235
236TEST(ParseNameTest, InvalidNameNotSet) {
237 std::string invalid;
238 ASSERT_TRUE(LoadTestData("invalid", "RDN", "sequenceInsteadOfSet", &invalid));
239 RDNSequence atv;
Bob Beck2e119172023-08-14 11:06:38 -0600240 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600241}
242
243TEST(ParseNameTest, InvalidNameEmptyRdn) {
244 std::string invalid;
245 ASSERT_TRUE(LoadTestData("invalid", "RDN", "empty", &invalid));
246 RDNSequence atv;
Bob Beck2e119172023-08-14 11:06:38 -0600247 ASSERT_FALSE(ParseName(SequenceValueFromString(invalid), &atv));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600248}
249
250TEST(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
266TEST(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
282TEST(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
298TEST(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
313TEST(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
328TEST(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
340TEST(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
354TEST(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
David Benjamin0fbc17a2024-08-21 15:13:10 -0400366BSSL_NAMESPACE_END